[REBOL] Re: Storing/loading object functions

2003-12-07 Thread lmecir

Hi,

Volker wrote:

 If class:
...
 a more efficient way is to use a method-object, like
 faces do.
 then you have
 
 a-handler: context [
 type: a-handler
 add: func [this increment] [this/value: this/value +
 increment]
 ; ^ note we pass 'this explicitely
 ]
 a-class: context [handler: a-handler a: none]
 a-object: make a-class [value: 5]
 a-object/handler/add a-object 3
 
 the call-syntax is not very handy, 
 but complete /view-styles are based on this system.
 Usually there is a dispatch-function, so that one can
 write
 ao-add: func[this incr][this/handler/add this 3]
 ao-add a-object 4
 
 see 'do-face in /view, 
 or 'show, which dispatches to face/feel/redraw and does
 some more work.

An universal dispatcher can be written as
follows:

msg: func [
{simple message dispatcher}
[throw]
message [block!]
] [
use [this method call] copy/deep [
set [this message] do/next message
method: first message
message: next message
if not path? method [method: to path! method]
insert method 'this/handler
call: make block! 2 + length? message
insert/only call method
insert tail call this
insert tail call message
do call
]
]

Instead of writing:

 a-object/handler/add a-object 3

we can use the above dispatcher and write:

msg [a-object add 3]


-- 
Eurotel Data Nonstop - Neomezen pstup na internet ji od 799
K msn!
http://www.eurotel.cz/site/cz/servicesAndTariffs/specialOffer.html?list=34995



-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: Millennium + 1 ...

2001-01-03 Thread lmecir

The Millenium and the Rebol Counting Error.

There was a dispute when the Second Millenium of our Julian/Gregorian calendar shall be
celebrated. The Millenium in this case shall mean the day, that is two thousand years 
after the starting day of the
calendar. The calendar documentation is stating, that the starting day
has been assigned the date 1/1/1 A.D. According to that, the Second Millenium day 
shall have the date 1/1/2001 A.D.

The architect of the Julian calendar used the date 1/1/1 A.D. as the starting date of 
the calendar.
What did the calendar architect do, when he wanted to refer back in time?
He used another calendar called the B.C. calendar, that counted the years backwards. 
The first year of the B.C. calendar was  
the year immediately preceding the first year of the A.D. calendar. We,
knowing zero and the negative numbers, can use A.D. calendar even for
the B.C. calendar dates. A conversion table:

YEARCONVERTED TO A.D.
**

4 A.D.   4
3 A.D.   3
2 A.D.   2
1 A.D.   1
1 B.C.   0
2 B.C.  -1
3 B.C.  -2
4 B.C.  -3

From the fact, that in Rebol 

(1/1/0001 - 1) ; == 31/12/

we can observe, that Rebol doesn't use the B.C. calendar, but it rather
uses the A.D. calendar even for the days before the start of our
calendar. This is simpler and more practical, than the ancient "calendar
switching".

Now about the Rebol Counting Error. Example:

series1: skip [-2 -1 0 1 2] 3; == [1 2]

Now we can ask what does the first place of our series contain. The
answer is, that the first place of our SERIES1 contains the number 1:

pick series1 1

What does the second place of our SERIES1 contain? It contains the
number 2:

pick series1 2

What does the place 1 B.S. i.e. the first place before the start of the SERIES1 
contain? It contains the number 0.
This place should be the place number 0 S. (i.e. the place number zero in the 
SERIES1), as everybody able to count
backwards from 1 can find out. The problem is, that the Rebol designer
is currently trying to convince us, that it is the place -1 S., as can
be seen from:

help pick

pick series1 0 ; == none
pick series1 -1 ; == 0

What do other Rebols think?



  2-Jan-0001 - 1
== 1-Jan-0001

 1-Jan-0001 - 1
== 31-Dec-

So,
 those who claim 2001 as the start of the new millinnium are wrong,
as
 there was a year 0.  At least according to REBOL... (:

-- 
Carl Read
 [EMAIL PROTECTED]

-- 
To unsubscribe from this list, please send
 an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject,
 without the quotes.


-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.




[REBOL] Re: [ANN] time-in-digits.r 1.3.0

2000-12-29 Thread lmecir

Hi Ryan,

the statement "within the same exact thousandth of a second" is not correct. The 
/precise refinement still can get only the system time, so the "granularity" of the 
time you can get depends on the operating system you use. Some values:

OS  Granularity

Windows 95/98   55 ms
Windows NT  10 ms

The value for the granularity can be easily computed with my TIME-TICK function, that 
can be found in http://www.sweb.cz/LMecir/timblk.r

Regards
Ladislav

 Hooray!

I have updated my 'time-in-digits function so that it can be
 used with 
the /precise refinement for 'now.

I use 'time-in-digits
 exhaustively, because it can be used to create 
sequential session IDs
 over time and to create sequential file names 
over time.

Because it
 can now handle the /precise refinement, it is very unlikely 
you will
 create the same session ID for multiple connections to a CGI 
interface
 (which was a possibility previously since more than one 
person might
 submit to CGI within the same exact second. Now 
there would only be a
 problem if more than one person might submit 
to CGI within the same
 exact thousandth of a second.)

-Ryan


REBOL [
   Title:   "Date and
 time in digits"
   Date:28-Dec-2000
   Name:'time-in-digits
  
 Version: 1.3.0
   File:%time-in-digits.r
   Author:  "Ryan C.
 Christiansen"
   Email:   [EMAIL PROTECTED]
   Owner:   "Ryan C.
 Christiansen"
   Rights:  "Copyright (C) Ryan C. Christiansen 2000"
  
 Tabs:4
   Language: 'English
   Purpose: {
  Convert the date
 and time into a string of digits.
   }
   Comment: {
  Use this
 function to create a string of digits denoting
  the date and time.
 This is useful, especially for creating
  sequential session IDs.
 If used with 'now to create a file
  name, the newest file will
 always appear at the end of
  a directory.
   }
   History: [
 
 1.0.0 [12-June-2000 "posted to rebol.com" "Ryan"]
  1.3.0
 [28-Dec-2000 "updated for /precise refinement" "Ryan"]
   ]
  
 Category: [util 2]
]

time-in-digits: func [
"Convert the date and
 time from 'now' into a string of digits."
sun-dial [date!] "The
 current date and time from 'now'"
][
year: to-string sun-dial/year
month: to-string sun-dial/month
if (length? month)  2 [insert
 month "0"]
day: to-string sun-dial/day
if (length? day)  2
 [insert day "0"]

current-time: sun-dial/time
hour: to-string
 current-time/hour
if (length? hour)  2 [insert hour "0"]
   
 minutes: to-string current-time/minute
if (length? minutes)  2
 [insert minutes "0"]
seconds: to-string current-time/second
   
 seconds-rounded: make integer! current-time/second
either
 current-time/second = seconds-rounded [
whole-seconds: seconds
 partial-seconds: "000"
   ][
either seconds-rounded = 0 [
 
   whole-seconds: "00"
time-string: make string! (reform
 current-time)
split-time: parse/all time-string "."
   
 partial-seconds: second split-time
][
either
 current-time/second = 0 [
whole-seconds: "00"

 partial-seconds: "000"
][
split-seconds: parse/all
 seconds "."
whole-seconds: first split-seconds

partial-seconds: second split-seconds
]
]
   ]
while
 [(length? whole-seconds)  2][insert whole-seconds "0"]
while
 [(length? partial-seconds)  3][append partial-seconds "0"]

   
 rejoin [year month day hour minutes whole-seconds partial-seconds]
]


  This appears to work until the thousandths-of-a-second value reaches
  either 1,000 or zero (not sure how REBOL is handling this, which is 
 where
 the problem lies, I believe.)
 
 Probably goes from 999 and
 roll around to 0, or none.
 
  ** Script Error: Out of range or past
 end
  ** Where: time-in-digits
  ** Near: partial-seconds: second
 split-seconds
  while [(length? whole-seconds)  2]
 
 Probably
 'whole-seconds is 'none ?
 
 I hope that helps!
 
 Andrew Martin

 ICQ: 26227169 http://members.nbci.com/AndrewMartin/
 --
 
 
 -- 
  To unsubscribe from this list, please send an email to

 [EMAIL PROTECTED] with "unsubscribe" in the 
 subject, without
 the quotes.
 


-- 
To unsubscribe from this list, please send an
 email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject,
 without the quotes.


-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.




[REBOL] Rebol von Neumann properties (RIP ifs-for-whomever cont.) Re:(3)

2000-10-17 Thread lmecir

Hi,

 If I understand your use of the term "evolving language" correctly,
 back in the 70's we used the term "extensible language" for the same
 thing (or something quite similar).  That term implied that the
 programmer could:

 *  add new syntactical structures (notation),
 *  add new control structures,
 *  create new datatypes and associated operations, and that
having done so,
 *  the extended language would appear as a whole language, without
obvious "seams" between the core language and the extensions, and
 *  there should not be a significant performance penalty for using
the extensions.

Extensible Language seems perfect.

  I don't think, that an Evolving Language must be able to do
  something like:
 
  a: [append a [+ 1] 1]
  do a
 
  (a von Neumann property - Pure Self Modifying Code), but I do
  think, that an Evolving language must be able to do:
 
  a: create-a-translation-of something
  do a
 
  , which may be described as a von Neumann property of the language
  too, but this is a code I would like to describe as a provision to
  understand Something with new syntactic/semantic rules (a new
  dialect, if you like, but it might not be a new dialect, but a new
  stage of the original language evolution).
 

 I believe I understand the distinction you're drawing here, but I
 must confess that I don't yet grasp HOW to enforce it without either
 performance penalties or loss of introspection.  For example, if I
 imagine something like

 active-thing: load-to-read-only-code data-representation
 do active-thing

 ALONG WITH the ability to introspect

 interesting-property: obtain-state active-thing selector

 then wouldn't I be able to do this

 altered-property: mutate interesting-property
 active-thing: load-to-read-only-code replace/all
   interesting-property altered-property
 do active-thing

 and be right back with self-modification, albeit at a severely
 lowered performance?

 Have I missed something?


The performance subject is very questionable, IMHO. I would call your sample
a WYSIWYG code. Let's try to compare it with Pure SMC like:

a: [append a [+ 1] 1]
do a

Don't you see any difference? If I would like to do it in a WYSIWYG fashion,
I would have to write:

a: [append a [+ 1] 1]
do copy a

Let's compare the results:

the first case:
 a: [append a [+ 1] 1]
== [append a [+ 1] 1]
 do a
== 1
 do a
== 2
 do a
== 3
 do a
== 4
 do a
== 5
 do a
== 6
 do a
== 8

the second one:

 a: [append a [+ 1] 1]
== [append a [+ 1] 1]
 do copy a
== 1

 do copy a
== 2
 do copy a
== 3
 do copy a
== 4
 do copy a
== 5
 do copy a
== 6
 do copy a
== 7
 do copy a
== 8
 do copy a
== 9
 do copy a
== 10


Regards
Ladislav




[REBOL] Rebol Bug-List Re:

2000-10-13 Thread lmecir

Hi,

I don't understand, why your mail didn't get through (I received your
previous mail normally).

 Hi, Ladislav.

 I'm replying through the Rebol list, because my ISP says:
 Quote
 This Message was undeliverable due to the following reason:

 Your message was not delivered because the return address was refused.

 The return address was '[EMAIL PROTECTED]'
 /Quote

 It seems your email service doesn't like me. :-(

 You wrote (directly to me):
  How about the bug list organization - all bugs in one file, or a file
for
 every bug?

 One bug = one file. One file to list them, one file to describe them, and
 one file to link them all! :-)

 Apart from sounding like a line from Tolkien, it's a reasonable plan I
 believe.

 Suggestions
 Directories like this:
 /Core
 /View
 /Apache
 /Command

 Each of the above having:
 /New - This is for new bugs.
 /Fixing - Bugs being fixed (hopefully).
 /Fixed - For fixed bugs.

 [Your suggestions here.]

How about /Patched?


 Andrew Martin
 ICQ: 26227169
 http://members.nbci.com/AndrewMartin/
 --






[REBOL] Rebol von Neumann properties (RIP ifs-for-whomever cont.) Re:

2000-10-13 Thread lmecir

Hi Joel,

I am sorry I wrote my previous post in a way you felt a need to apologize.
The fact is, that I was sorry about it right after I sent it. I knew I
wasn't totally right about the non-terminating issue. The only problem of
your code WRT termination is, that it doesn't terminate for some trivial
inputs, such as None supplied as the first argument.

[...snip...]

 REBOL definitely offers expressive power far beyond the reach of
 most of the current crop of programming languages, and I find it
 interesting to see just how far that can go.

[...snip...]
 REBOL (as a von Neumann language in the company of Lisp, PROLOG,
 etc.) gives us the ability to indulge in what I'll call "logical
 fractals" whose behavior is *SEVERELY* unobvious if we aren't
 aware of what we're getting into.  Now, please hold that thought
 for a moment, while I draw in one other connection...

 In an essay (the ninth chapter of his book _Patterns_of_Software_,
 Rich Gabriel suggests four characteristics which a programming
 language must have to survive:

* Languages are accepted and evolve by a social process,
  not a technical or technological one.

* Successful languages must have modest or minimal
  computer resource requirements.

* Successful languages must have a simple performance
  model.

* Successful languages must not require users [to] have
  "mathematical sophistication."

 REBOL succeeds admirably on #2, and we're all working on #1 via
 this mailing list.

 #3 is more problematic.  I've never seen an "official" model of
 REBOL semantics, but throughout my involvement with it I've
 been trying to come up with pieces of one (e.g., my earlier
 essays on SERIES! values).  I still believe that there are many
 parts of REBOL that could be explained precisely and simply,
 but others that are not so clear.  (Either in my poor head or
 in fact -- witness the differences in behavior when mutations
 are applied to BLOCK! versus LIST! values.)

 #4 is the most "dangerous" to REBOL, in that *EVERY* vNL of
 which I'm aware -- REBOL included -- requires at some point a
 fair bit of sophistication to understand, or at least to
 recognize when one is getting into deep waters.


 TYING IT ALL TOGETHER (at last!)

 I suspect that what we (computing folk in general) need before
 vNL languages in general -- and REBOL in particular -- will be
 widely accepted is the beginnings of a real grasp on "logical
 fractals" that let us use their power effectively and (mostly)
 safely.  Of course, one approach is to say "Don't do that at
 all!"  If I take that approach, I begin to wonder why I don't
 just stick to COBOL!

 OTOH, if I can begin to get a grip on when and how to use such
 "monsters" as:

 *  mezzanine-level control constructs,
 *  higher-order functions,
 *  self-modifying, stateful values,
 *  ...etc...

 I may be able to take advantage of REBOL's power -- using it
 more effectively -- and be able to explain/communicate its
 benefits more persuasively -- promoting its success more
 effectively.


I do like the notion of an Evolving Language. That means a language, whose
dictionary is easy to enlarge together with its syntactic/semantic rules.
All those properties are present in natural languages, like English, etc. To
enlarge a language there must be a possibility to speak about the language
in the language. As Carl likes to underline, an Evolving  Language must be
its own metalanguage.

I don't think, that an Evolving Language must be able to do something like:

a: [append a [+ 1] 1]
do a

(a von Neumann property - Pure Self Modifying Code), but I do think, that an
Evolving language must be able to do:

a: create-a-translation-of something
do a

, which may be described as a von Neumann property of the language too, but
this is a code I would like to describe as a provision to understand
Something with new syntactic/semantic rules (a new dialect, if you like, but
it might not be a new dialect, but a new stage of the original language
evolution).

Regards
Ladislav






[REBOL] Ifs Re:(2)

2000-10-12 Thread lmecir

Hi Joel,

I am not glad, that I must disappoint you, but see the following example:

a: 1
b: to paren! [to paren! [to paren! [to paren! [a: 0 - a
ifs-for-dummies b [negative: ["Negative"] zero: ["Zero"] positive:
["Positive"]]
== "Zero"

I think, you should read Exception #5 for Word Evaluation of my Rebol/Core
User's
Guide Comments once again and hope, that this will be interesting even for
others...

Regards
Ladislav

P.S. My strong opinion is, that the best you can get is:

signed-if: func [
{If positive do positive-block, zero do zero-block, negative do
negative-block}
[throw]
condition [number! char! money! time!]
positive-block [block!]
zero-block [block!]
negative-block [block!]
] [
either positive? condition [do positive-block] [
either negative? condition [do negative-block] [do zero-block]
]
]

I am afraid, that Signed-if-for-dummies may become a victim of the GC bug
and similar issues, when used recursively...

- Original Message -
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Wednesday, October 11, 2000 11:20 PM
Subject: [REBOL] Ifs Re:


 Hi, all...

 In honor of the newest REBOL book (and for those of us who can't count to
 three in proper order, such as myself! ;-) and inspired by the keywords
 feature of Common Lisp, I offer yet another   ifs   , which doesn't care
 in which order the actions are specified:

a: 1
   == 1
ifs-for-dummies a [positive: ["plus"] zero: ["zip"] negative:
["minus"]]
   == "plus"
ifs-for-dummies a [zero: ["zip"] positive: ["plus"] negative:
["minus"]]
   == "plus"
ifs-for-dummies a [negative: ["minus"] zero: ["zip"] positive:
["plus"]]
   == "plus"

 whether they are all specified:

ifs-for-dummies a [positive: ["biggerthanzero"]]
   == "biggerthanzero"
ifs-for-dummies a [negative: ["smallerthanzero"]]
ifs-for-dummies a [zero: ["equaltozero"]]
ifs-for-dummies a [zero: ["equaltozero"] positive: ["bigger,
again!"]]
   == "bigger, again!"

 or whether the selector has unstable side-effects:

a: 1
   == 1
b: to-paren [a: 0 - a]
   == (a: 0 - a)

ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive:
["plus"]]
   == "minus"
ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive:
["plus"]]
   == "plus"
ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive:
["plus"]]
   == "minus"
ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive:
["plus"]]
   == "plus"

 This new candidate (which will run if evaluated, but not if elected), has
a
 running mate:

   fortranif: make object! [
   positive: []
   negative: []
   zero: []
   selector: 0
   compute:  func [[throw] selexpr] [
   selector: selexpr
   either positive? selector [
   do positive
   ][
   either negative? selector [
   do negative
   ][
   do zero
   ]
   ]
   ]
   ]

 and a campaign promise:

   ifs-for-dummies: func [[throw] selexp conseq [block!] /local actor] [
 actor: make fortranif conseq
 actor/compute selexp
   ]

 (In case you're wondering, the news coverage of the US election campaigns
 hasn't affected me at all!  "My fellow REBOLians...")

 -jn-

 "Coding at the speed of a dummy!"

 --
 ; Joel Neely  [EMAIL PROTECTED]  901-263-4460  38017/HKA/9677
 REBOL []  print to-string debase decompress #{
 789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC
 B6F4F574CFC888342AC949CE74B50500E1710C0C2400}






[REBOL] Ifs Re:(4)

2000-10-12 Thread lmecir

Hi,

a stupid example:

f: func [x [any-type!]] [1]
b: to paren! [to paren! [:f]]
ifs-for-dummies-who-play-with-fire b [positive: [print "positive"] negative:
[print "negative"] zero: [print "zero"]]

The result:

zero
== 1

Regards
Ladislav

 [EMAIL PROTECTED] wrote:
 
  Hi Joel,
 
  I am not glad, that I must disappoint you, [...]
 

 Not at all!  It's just that I, being a Bear of Small Brain, find it
 difficult to give up.  I'm very appreciative of the feedback!

 I've forgotten the source, but recall the saying, "In science, a
 successful experiment teaches nothing, as only the expected result
 is obtained.  One learns only when an experiment fails, providing a
 challenge for new thought."

 Thanks for the excellent teaching!

  but see the following example:
 
  a: 1
  b: to paren! [to paren! [to paren! [to paren! [a: 0 - a
  ifs-for-dummies b [negative: ["Negative"] zero: ["Zero"] positive:
  ["Positive"]]
  == "Zero"
 
  I think, you should read Exception #5 for Word Evaluation of my
  Rebol/Core User's Guide Comments once again [...]
 

 Have done.

 
  and hope, that this will be interesting even for others...
 

 I also.

 Trying yet again, (I'm running the risk of keeping two distinct issues
 entangled here -- the get-to-the-bottom-of-a-strange-selector puzzle,
 and the object-for-named-parameters gimmick)...

 unravel: func [[throw] exp /local val] [
 val: exp
 while [not any[ number? val  char? val  money? val  time? val]]
 [
 val: do val ]
 val ]

 signed-choice: make object! [
 positive: []
 negative: []
 zero: []
 selector: 0
 compute:  func [[throw] selexpr] [
 selector: unravel selexpr
 either positive? selector [
 do positive
 ][
 either negative? selector [
 do negative
 ][
 do zero
 ]   ]   ]   ]

 ifs-for-dummies-who-play-with-fire: func [
 [throw] selexp conseq [block!] /local actor
 ][
 actor: make signed-choice conseq
 actor/compute selexp ]

 After which I can conduct more experiments...

  c: [{[{[{"-1"}]}]}]
 == [{[{[{"-1"}]}]}]
  ifs-for-dummies-who-play-with-fire c [
positive: ["+"] negative: ["-"] zero: ["0"]]
 == "-"
  c: [{[{[{"1"}]}]}]
 == [{[{[{"1"}]}]}]
  ifs-for-dummies-who-play-with-fire c [
positive: ["+"] negative: ["-"] zero: ["0"]]
 == "+"
  c: [{[{[{"2 - 2"}]}]}]
 == [{[{[{"2 - 2"}]}]}]
  ifs-for-dummies-who-play-with-fire c [
positive: ["+"] negative: ["-"] zero: ["0"]]
 == "0"
 

 
  I am afraid, that Signed-if-for-dummies may become a victim of the GC
bug
  and similar issues, when used recursively...
 

 I haven't had time to play with that issue, but will do so when I can.

 Thanks again!

 -jn-







[REBOL] Ifs Re:(6)

2000-10-12 Thread lmecir

Well, the problem is, that you are trying to disobey the KISS rule. That
rule means, that your signed-if-for-dummies should do one thing and do it
well. I think, that it should execute the properly chosen block. It shoudn't
try to evaluate its first argument at any price, because supplying it is a
work for the caller IMO. I am pretty sure, that the code is much more
"brittle" and cryptic, than the proper solution, which should work for
useful first argument values and not for any garbage. E.g. your solution has
the worst possible property of any algorithm: there are some inputs, for
which the algorithm doesn't stop.

Regards
Ladislav

 Hi, Ladislav,

 That was severely subtle!  (And AFAIAC sounded the death knell on the
notion
 that REBOL is a simple language for non-programmers! ;-)

 [EMAIL PROTECTED] wrote:
 
  Hi,
 
  a stupid example:
 

 replace read previous-message-in-thread "stupid" "challenging"

 
  f: func [x [any-type!]] [1]
  b: to paren! [to paren! [:f]]
  ifs-for-dummies-who-play-with-fire b [positive: [print "positive"]
negative:
  [print "negative"] zero: [print "zero"]]
 
  The result:
 
  zero
  == 1
 

 Even knowing the dynamic, code=data=code=data... nature of REBOL, I hadn't
 thought of the possibility of supplying a value that totally changes the
 evaluation pattern of another bit of code.  Of course, this creates a
whole
 new level of threat models for trying to write defenses against
potentially
 hostile external code.

 At any rate, the following mod seems to close the wormhole:

 signed-choice: make object! [
 positive: []
 negative: []
 zero: []
 selector: 0
 compute:  func [[throw] selexpr] [
 selector: (unravel selexpr)
 either positive? selector [
 do positive
 ][
 either negative? selector [
 do negative
 ][
 do zero
 ]   ]   ]   ]

 ...allowing...

 ifs-for-dummies-who-play-with-fire b [
positive: ["+"] negative: ["-"] zero: ["0"]
 ]

 == "+"

 ifs-for-dummies-who-play-with-fire b [
positive: ["+"] negative: ["-"] zero: ["0"]
 ]

 == "+"

 Thanks!

 -jn-






[REBOL] Open source project Re:(9)

2000-10-11 Thread lmecir

Hi Rebols,

...
 With regard to the specifics of buglists, knowledge-bases, and specs: I'm
for it.  But help me out because I don't have the time or peoplepower to do
everything for everybody.  Like I said: I've been focusing on YOU for four
years now. I've had no life, just you.  Now, you've got to help me focus on
REBOL the company.  That is truly the most rewarding path to the future, for
all of us.

 A REBOL as always,

 -Carl Sassenrath
  Founder  CTO
  REBOL Technologies


If I understood correctly, we should build a bug-list ourselves. I would
like to help with that. Where should it reside?




[REBOL] generalities of addresses and values... Re:(4)

2000-10-11 Thread lmecir

Hi,

Joel wrote:

 At this point, one would need to do similar tests for all REBOL
 datatypes to completely answer your question.  The description
 of   copy   (with respect to the   /deep   refinement) leaves
 the impression that anything under the   series!   pseudotype
 would be a "reference", however.
 
For some info you can see:

http://www.rebol.org/advanced/mutable.r

and

http://www.geocities.com/lmecir.geo/evaluation.html

Regards
Ladislav







[REBOL] Rebol/Core User's Guide

2000-10-11 Thread lmecir

Hi List! Sorry for the length, but some may be interested, I hope...

Variables:

[Quote]
A variable refers to a specific value only within a defined context, such as
a block, a function, or an entire program.
[End Quote]

That seems to be in contradiction with:

 probe block
[a a a]
== [a a a]

 do probe first block
a
== 1

 do probe second block
a
** Script Error: a has no value.
** Where: do probe second block

 do probe third block
a
== 2

Words:

[Quote]
For example, -1 and +1 are numbers, not words.
[End Quote]

The following exceptions to the rule might be interesting:

 type? probe to word! "-1"
-1
== word!

 type? probe to word! "+1"
+1
== word!

 type? probe to word! "{"
{
== word!

 type? probe to word! "[test]"
[test]
== word!

 type? probe to word! "@#$%^,"
@#$%,
== word!

 type? probe to word! {
{}


== word!

 type? probe to word! ":a"
:a
== word!

 type? probe to word! "a:"
a:
== word!

 type? probe to word! "a/v"
a/v
== word!

 type? probe to word! "'a"
'a
== word!

[Quote]
Word Format

word

REBOL's Treatment

Evaluates the word. This is the most natural and common way to write words.
If the word holds a function, it will be evaluated. Otherwise, the value of
the word will be returned.
[End Quote]

I see the following exceptions to this rule:

1) If the word holds a set-word, the corresponding word is set.
2) If the word holds a lit-word, the corresponding word is returned.
3) If the word holds a path, the path is evaluated and the result of the
evaluation is returned.
4) If the word holds a lit-path, the corresponding path is returned.
5) If the word holds a paren, the paren is evaluated and the result of the
evaluation is returned.
6) If the word holds a set-path, the corresponding path is set.
7) If the word is unset, an error occurs.

Series:

page 5-2

[Quote]
A series is a set of values organized in a specific order.
[End Quote]

The problem with this definition is, that it is a little bit incorrect. The
reason is as follows:

Let's have two mathematical sets: {0} (a set containing zero) and {0,1} (a
set containing zero and one). It is obvious, that these are different sets.

As opposed to this, it is not a problem to have one Rebol series, that
contains only zero and change it to contain both zero and one:

series: [0]
append series 1
series

That is why the correct definition of the series should take into account,
that a series is an ordered container used when we want to store/retrieve
Rebol values.

[Quote]
The first position of the block is called its head.
[End Quote]

This is incorrect, as can be seen here:

block: next [1 2 3 4]
 first block
== 2

But:
 first head block
== 1

I would use a little bit different definition:

Every series has got a position (an integer number), that can be obtained as
follows:

index? series

Series with position 1 is called head.

[Quote]
The last position is called tail.
[End Quote]

I would prefer a more consistent wording, e.g.:

A series can have a subseries having a higher position. The smallest
possible subseries of a series is a series with the highest possible
position containing no elements, which is called its tail. The position of
the tail is the length of the head series plus one.

page 5-6

[Quote]
Now the 'colors variable is resting at the tail of the block.
...
print tail? colors
false
[End Quote]

An error, IMO. It should be True.

page 5-36

[Quote]
Although 'str is a local variable, its string value is global.
[End Quote]

[My Favourite Wording]
Although 'str is a local variable, initialized every time Print-it is
evaluated, its string value is contained (or referenced?) in the body of
Print-it and therefore persistent as long as Print-it exists, or at least as
long, as its body references the string in question.
[End My Favourite Wording]

The main reason for suggesting the changed formulation is, that a sentence:

"... string value is global..."

Doesn't have any meaning a common user (e.g. me) could understand. (How can
I tell a
"global string" from "a local one"?)

page 5-64
[Quote]
Multiple variables can refer to the same series.
[End Quote]

The above wording underlines variables, but there are other means how to
obtain a series (a function result, e.g. Next Series, an element of another
series,...)

[My Favourite Wording]
Multiple Rebol series can be the subseries of the same head series.
[End My Favourite Wording]

Scope of Variables
page 8-30 REBOL/Core User Guide Version 2.3
[Quote]
For example, here is a signed if function that evaluates one of three blocks
based on
the sign of a conditional value:
ifs: func [
"If positive do block 1, zero do block 2, minus do 3"
condition block1 block2 block3
][
if positive? condition [return do block1]
if negative? condition [return do block3]
return do block2
]
print ifs 12:00 - now/time ["morning"]["noon"]["night"]
night
[End Quote]

The above definition doesn't work correctly, because it doesn't have the
Throw attribute.

[Corrected version]
ifs: 

[REBOL] Rebol strings (generalities of...)

2000-10-11 Thread lmecir

A model of Rebol string implementation (written in Java):

class RebolStringStorage {
char [] storage;
int storageLength;
int stringLength;
}

class RebolString {
int position;
RebolStringStorage storage;
}

Regards
Ladislav









[REBOL] Rebol strings (generalities of...)

2000-10-11 Thread lmecir

Hi,

when testing the properties of Rebol strings I came to:

 a: skip [1 2 3 4 5 6] 3
== [4 5 6]
 index? a
== 4
 b: head a
== [1 2 3 4 5 6]
 remove back tail b
== []
 b
== [1 2 3 4 5]
 remove back tail b
== []
 b
== [1 2 3 4]
 remove back tail b
== []
 b
== [1 2 3]
 remove back tail b
== []
 b
== [1 2]
 index? a
** Script Error: Out of range or past end.
** Where: index? a

which seems to be in accordance with the model proposed...

Ladislav




[REBOL] Rebol/Core User's Guide Re:(2)

2000-10-11 Thread lmecir

Hi Joel,

I knew about that issue, but considered the Throw attribute as absolutely
necessary in this case (the chapter follows the one describing Throw/Catch
attributes AFAIR). You are right. To be correct, it should have been like
this:

ifs: func [
{If positive do block 1, zero do block 2, minus do 3}
[throw]
condition [number!]
block1 [block!]
block2 [block!]
block3 [block!]
] [
either positive? condition [do block1] [
either negative? condition [do block3] [do block2]
]
]

Regards
Ladislav

- Original Message -
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Wednesday, October 11, 2000 5:34 PM
Subject: [REBOL] Rebol/Core User's Guide Re:


 Hi, Ladislav,

 I haven't finished thinking through all of your comments, but one issue
 jumped out at me so forcefully that I thought I'd go ahead and comment
 on it...

 [EMAIL PROTECTED] wrote:
 
 [...snip...]
  Scope of Variables
  page 8-30 REBOL/Core User Guide Version 2.3
  [Quote]
  For example, here is a signed if function that evaluates one of three
blocks
  based on
  the sign of a conditional value:
  ifs: func [
  "If positive do block 1, zero do block 2, minus do 3"
  condition block1 block2 block3
  ][
  if positive? condition [return do block1]
  if negative? condition [return do block3]
  return do block2
  ]
  print ifs 12:00 - now/time ["morning"]["noon"]["night"]
  night
  [End Quote]
 
  The above definition doesn't work correctly, because it doesn't have the
  Throw attribute.
 
  [Corrected version]
  ifs: func [
  "If positive do block 1, zero do block 2, minus do 3"
  [throw]
  condition block1 block2 block3
  ][
  either positive? condition [do block1] [
  either negative? condition [do block3] [do block2]
  ]
  ]
  print ifs 12:00 - now/time ["morning"]["noon"]["night"]
  morning
  [End Corrected Version]
 

 It's also incorrect because it assumes that successive uses of the
argument
 calledconditionwill produce identical values!  Consider this:

  a: 1
 == 1
  b: to-paren [a: 0 - a]
 == (a: 0 - a)
  ifs b ["positive"] ["negative"] ["zero"]
 == "zero"

 (simply demonstrating, once again, the severe subtlety of REBOL!)

 -jn-

 --
 ; Joel Neely  [EMAIL PROTECTED]  901-263-4460  38017/HKA/9677
 REBOL []  print to-string debase decompress #{
 789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC
 B6F4F574CFC888342AC949CE74B50500E1710C0C2400}






[REBOL] Rebol/Core User's Guide Re:(4)

2000-10-11 Thread lmecir

Hi Joel,

you wrote:

 Hello again, Ladislav,

 [EMAIL PROTECTED] wrote:
 
  Hi Joel,
 
  I knew about that issue, but considered the Throw attribute as
absolutely
  necessary in this case...
 

 Certainly!  I've been reading a fascinating essay by Richard Gabriel on
the
 power (and dangers!) of abstraction, and will likely mutter about that in
 a later post.

  You are right. To be correct, it should have been like
  this:
 
  ifs: func [
  {If positive do block 1, zero do block 2, minus do 3}
  [throw]
  condition [number!]
  block1 [block!]
  block2 [block!]
  block3 [block!]
  ] [
  either positive? condition [do block1] [
  either negative? condition [do block3] [do block2]
  ]
  ]
 

 Well, I was as surprised as you will be by the following behavior:

  ifs: func [
 [{If positive do block 1, zero do block 2, minus do 3}
 [[throw]
 [condition [number!]
 [block1 [block!]
 [block2 [block!]
 [block3 [block!]
 [] [
 [either positive? condition [do block1] [
 [either negative? condition [do block3] [do block2]
 []
 []
  ifs b ["positive"] ["negative"] ["zero"]
 == "positive"
  ifs b ["positive"] ["negative"] ["zero"]
 == "zero"
  ifs b ["positive"] ["negative"] ["zero"]
 == "positive"
  ifs b ["positive"] ["negative"] ["zero"]
 == "zero

 I had expected that the argument type check would barf on my little
 pathological case, but it didn't!


You should read exception #5 for word evaluation of my Rebol/Core User's
Guide Comments to understand the behaviour. The fact is, that Ifs really
gets a
number and there is no need to worry about any change during the Ifs
evaluation in the case you supplied and, moreover, if Ifs is defined as
above, no such bug is lurking behind the scenes.


 However, I accept fault for typing and hitting "Send" too quickly without
 explaining my interest in the issue of expressions with side effects.

 (So no-one has to backtrack in the thread, let me repeat the definitions
and
 usage of

  a: 1
 == 1
  b: to-paren [a: 0 - a]
 == (a: 0 - a)
  b
 == -1
  b
 == 1
  b
 == -1
  b
 == 1

 for use below)

 I was actually wondering about allowing a more general type of argument,
 but writing   ifs   in such a way as to "freeze" the value with one
 evaluation, then re-use that frozen, evaluated-once-only value as often
 as necessary.  I tried a little experiment with this variation:

 ifs: func [[throw] ce b1 b2 b3 /local cf] [
 either positive? cf: ce [
 do b1
 ][
 either negative? cf [
 do b2
 ][
 do b3
 ]
 ]
 ]

  ifs b ["positive"] ["negative"] ["zero"]
 == "positive"
  ifs b ["positive"] ["negative"] ["zero"]
 == "negative"
  ifs b ["positive"] ["negative"] ["zero"]
 == "positive"
  ifs b ["positive"] ["negative"] ["zero"]
 == "negative"
  ifs b ["positive"] ["negative"] ["zero"]
 == "positive"

 Aha!  This captures the side-effects avoidance nicely.  (I think I have
 permuted the argument list here, but that's irrelevant to the main point
 I'm pursuing, so I didn't bother to fix that inconsistency.)

 Notice that the above definition uses cryptic argument names.  It also
 is simply selecting which of the three blocks todoas the chosen
 activity.  Therefore, I expected it to be equivalent to the nicer

 ifs: func [[throw] cexp pblk zblk nblk /local cval] [
 do either positive? cval: cexp [pblk] [
 either negative? cval [nblk] [zblk]
 ]
 ]

 so you can imagine my surprise to obtain these results!

  ifs b ["positive"] ["negative"] ["zero"]
 == "zero"
  ifs b ["positive"] ["negative"] ["zero"]
 == "positive"
  ifs b ["positive"] ["negative"] ["zero"]
 == "zero"
  ifs b ["positive"] ["negative"] ["zero"]
 == "positive"
  ifs b ["positive"] ["negative"] ["zero"]
 == "zero"

 Well, it appears that   do   does NOT distribute over evaluation of its
 argument!

 Comments welcomed!

 -jn-

 --
 ; Joel Neely  [EMAIL PROTECTED]  901-263-4460  38017/HKA/9677
 REBOL []  print to-string debase decompress #{
 789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC
 B6F4F574CFC888342AC949CE74B50500E1710C0C2400}







[REBOL] Ifs

2000-10-11 Thread lmecir

Hi Rebols,

in the case anybody would like to have an as correct and general as possible
version of Ifs, here you are:

ifs: func [
{If positive do positive-block, zero do zero-block, negative do
negative-block}
[throw]
condition [number! char! money! time!]
positive-block [block!]
zero-block [block!]
negative-block [block!]
] [
either positive? condition [do positive-block] [
either negative? condition [do negative-block] [do zero-block]
]
]

Look out! It is necessary to write the arguments in correct order!

Regards
Ladislav




[REBOL] Re: [REBOL Helpdesk] assigned #4659

2000-10-11 Thread lmecir

Hi Bo,

Compare:

Example #1:
a: [1 2]
remove back tail a
b: skip a 2
index? b

== 2

Example #2:
a: [1 2]
b: skip a 2
remove back tail a
index? b

** Script Error: Out of range or past end.
** Where: index? b

From that I am concluding, That Rebol behaviour is inconsistent, because
both cases should yield the same result. My suggestion is as follows:

old-index?: :index?
index?: function [
{Returns the index number of the current position in the series.}
series [series! port!]
] [result] [
if error? result: try [old-index? :series] [result: old-index? series:
tail :series]
result
]

Now the result of Example#2:

== 2

Andrew could enhance Rebol patches, I think.

Regards
Ladislav


 Ladislav,

 Do you see this as being a bug?  If so, why?  Also, what behavior
 would you rather have occur?

 Awaiting your answer!

 REBOL Support
 --








[REBOL] Bug? 'func not really 'func Re:(3)

2000-10-10 Thread lmecir

Hi,

[...snip...]

 I am confused as to why 'copy seems to be evaluating the words in the
block
 it's given. And also why it doesn't show up until after the function is
put
 together.

 BTW, here's a patch for 'function, to add 'throw-on-error around it, like
 'does and 'func have:

 if not equal? second third :function [catch] [
 function: func
 head insert/only at load mold third :function 2 [catch]
 compose/deep [
 throw-on-error [
 (copy/deep second :function)
 ]
 ]
  ]

 Andrew Martin
 Falling prey to hypos...
 ICQ: 26227169
 http://members.nbci.com/AndrewMartin/
 --


1)
Not Copy, but Func evaluates its spec block to get the datatypes supplied,
instead of words. That is why you normally won't see the difference, but
look:

spec: [a [block!]]
type? probe first second spec
block!
== word!

f: func spec []
type? probe first second third :f
block!
== datatype!

Load Mold converts the datatype back to word.

2)
Your patch is not advisable in general. The reason:

x: 1
y: 0
z: 4
u: 2
f1: does [x / y]
f2: does [z / u]

trial: func [blk [block!]] [
probe do blk
]
trial [f1 f2]

Normally yields

** Math Error: Attempt to divide by zero.
** Where: x / y

, while

transformed-trial: func [[catch] blk [block!]] [
probe throw-on-error blk
]
transformed-trial [f1 f2]

yields:

** Math Error: Attempt to divide by zero.
** Where: transformed-trial [f1 f2]

, which may be useless for debugging. That is why error throwing is
advisable sometimes, but sometimes it isn't. Have a look at For source as an
example of balanced throwing, although the series bug I discovered still
remains unrepaired.

Regards
Ladislav




[REBOL] polymorphic object/block VWord func - useful in decoding CGI's, etc. Re:

2000-10-10 Thread lmecir

Hi Douglas,

a useful function, IMHO. I would suggest a more "goal oriented" approach
with the i-alt parameter:

i-alt [unset! block!] ; the alternate code to execute

; example code to be executed as alternate case
return either value? 'i-alt [do i-alt] [none]

Regards
Ladislav

 For your consideration:

 We are using a function called "vword" as
 (value of word in block or object)
 a safe, easy way to get unknown values out of blocks or objects.

 For instance:
We store email/report templates in blocks, but can now safely skip
any report details by leaving the items out of the template/blocks or
providing a default value to use as a substitute.

   Another great use for "vword" is when decoding CGI gets or posts.
   You never really know what is in or out of CGI object,
   so vword is a safe way to interogate the object and get all the values.


 Try it out and let me know what you think.

 REBOL []

;---
 -
 vword: func [
   { Test to see if a certain word is found in a block or object.
 If so, the value of the word is returned. (Hence, the name vword.)
 If not, then the alternate value will be used.
 If the word is not found and no alternate value is supplied, none is
 returned.}
   item [block! object!] "The item containing the word you wish to search
 for."
   i-word [word!]"The word / attribute you wish to search for."
   i-alt  [any-type!]"The alternate value to use if the word is not
 found."
   /local ret
 ][
   either block? item [
  if none? ret: select item :i-word  [
 if (value? 'i-alt) [ret: i-alt]
  ]
   ][
 either none? ret: in item :i-word [
if (value? 'i-alt) [ret: i-alt]
 ][
ret: get in item :i-word
 ]
   ]
   return ret
 ]

;---
 -



  do %/e/scripts/rs/vword.r
 Script: "Untitled" (none)
  vword [a "APPLE" b "BANANA" c "CARROT"] 'd "DICED PEACHES"
 == "DICED PEACHES"
  vword [a "APPLE" b "BANANA" c "CARROT"] 'a "DICED PEACHES"
 == "APPLE"
  vword [a "APPLE" b "BANANA" c "CARROT"] 'b "DICED PEACHES"
 == "BANANA"
  vword [a "APPLE" b "BANANA" c "CARROT"] 'c "DICED PEACHES"
 == "CARROT"
  vword [a "APPLE" b "BANANA" c "CARROT"] 'e "DICED PEACHES"
 == "DICED PEACHES"
  vword [a "APPLE" b "BANANA" c "CARROT"] 'e
 == none




  print mold xo

 make object! [
 a: "ABC"
 b: "BOY"
 ]
  vword xo 'a "alpha"
 == "ABC"
  vword xo 'c "alpha"
 == "alpha"
  vword xo 'c
 == none
  vword xo 'c "alpha"
 == "alpha"
  vword xo 'b "alpha"
 == "BOY"
 



 Douglas Vos - EDS/GM-BSU Webmaster
 e-Mail: mailto:[EMAIL PROTECTED]








[REBOL] Joel's technical essay/challenge

2000-10-07 Thread lmecir

Hi,

I recently suggested my Rt (Referentially transparent) function, but
overlooked, that Joel wanted to have the first element of the path to be an
object (or a general Rebol value), not a Rebol word. Here is my next trial:

rt: func [
{
a referentially transparent way
to invoke a path on a given object/function/something
Usage:
rt [[object 'function 'refinement1 ...] arg1...]
}
[catch]
blk [block!]
] [
do function [] [result1 result2 something] [
throw-on-error [
result1: do/next first blk
something: first result1
result2: append copy ['something] reduce second result1
do head change/only copy blk to path! result2
]
]
]
; Warning - although it seems to work, it is untested against the GC bug!
; (and my personal guess is, that it wouldn't survive)

; Joel's examples:
bunchanums: [3 1 35 8 4 5 52 42 19 13 32 43 81 2 6 34 46]

tally: make object! [
tot: 0
zero: does [tot: 0]
up: func [/by n [number!]] [tot: tot + either by [n] [1]]
down: func [/by n [number!]] [tot: tot - either by [n] [1]]
now?: does [tot]
]

; example #1:
use [evens odds] [
evens: make tally []
odds: make tally []
foreach num bunchanums [
rt [[either even? num [evens] [odds] 'up 'by] num]
]
print ["evens:" evens/now? " odds:" odds/now?]
]

{
Result:
evens: 226  odds: 200
}

; example #2:
use [diffs] [
diffs: make tally []
foreach num bunchanums [
rt [[diffs either even? num ['up] ['down] 'by] num]
]
print ["net sum:" diffs/now?]
]

{
Result:
net sum: 26
}

Regards
Ladislav




[REBOL] Do/next error handling

2000-10-07 Thread lmecir


Example #1 (correct):
block: [1 / 0]
do block

Result:
** Math Error: Attempt to divide by zero.
** Where: 1 / 0

Example #2 (incorrect):
block: [1 / 0]
do/next block

Result:
** Math Error: Attempt to divide by zero.
** Where: do/next block

Regards
Ladislav




[REBOL] Who is that grouch? -or- Fun with functions! Re:(10)

2000-10-06 Thread lmecir

Hi,

I am prepared to incorporate enhancements you suggest to
http://www.rebol.org/advanced/highfun.r

Cheers
Ladislav

BTW, an RT (Referentially Transparent) version of:

object/function/refinement1/.../refinementN arg1 ...argN

call can be written (using Refined from above URL) as follows:

do refined get in object 'function reduce [
'refinement1 ...'refinementN
] arg1 ...argN

(ugly), or, more efficiently (using RT function defined below):

rt: function [block [block!]] [blk] [
do head change/only copy block to path! reduce first block
]

as:

rt [['object 'function 'refinement1 ... 'refinementN] arg1 ... argN]

(MUCH more sexy).

 Happy, Grouchy, and Dopey  ;-)

 I don't think this has been mentioned in this thread yet.
 Ladislav created a number of the high level functions. Not sure how they
 stack up in light of the recent benchmarks. But they are worth a look.

 A set of higher order functions:
 Accum, Apply, Curry, Composition, Enum, Filter, Map, Mapper, Nargs,
Refined
 http://www.rebol.org/advanced/highfun.r

 Cheers,

 Allen K
 Lazy..

 --Snow White Carl, and REBOL dwarves, playing to peer review in a suburb
 near you!--








[REBOL] Who is that grouch? -or- Fun with functions! Re:(12)

2000-10-06 Thread lmecir

Hi Joel,

   A set of higher order functions:
   Accum, Apply, Curry, Composition, Enum, Filter, Map, Mapper, Nargs,
  Refined
   http://www.rebol.org/advanced/highfun.r
  
 

 Well, actually, I do have one question (esp. to Ladislav and/or
 Allen) regarding style.  I've noticed both of you using capital
 letters (e.g., in the list of HOFs above), but haven't figured
 out the convention by which one decides what is capitalized.
 Just curious...

 -jn-


that is my "convention", that nobody else uses AFAIK, Allen just (as that
lazy... suggests) copied a part of the file IMHO. I do it when speaking
about Rebol values to distinguish them and the normal text. Example:

a: either b= 1[5] [6]

When refering to the code above I am trying to (as consistently as possible)
use A as a name for the Rebol integer value stored in the Rebol word 'A
(whether it is 5 or 6) as opposed to 'A, which denotes the Rebol word as
such.

That is why I speak about Refined (Rebol function) and 'Refined (Rebol
word).

My "convention" differs dramatically from Elan's, (maybe others use that
too), because what I call A he usually denotes 'a and what I call 'A he
usually denotes a (or A). I think, that from the above description is clear,
that either mine, or his "convention" looks as being "inside out" or "upside
down". When I wrote a HTML version of my
http://www.geocities.com/lmecir.geo/contexts.html, I used a different
"convention": I simply used a different font (Courier) for the same purpose
instead of initial capital letters, which may be even more readable (I
hope).

Cheers
Ladislav




[REBOL] Transpose Re:(3)

2000-10-06 Thread lmecir

Hi,

Andrew wrote:

 Why capitals? Here's the Transpose function again:

 Transpose: function [
 [catch]
 "Transposes Matrices"
 Matrix [block!]
 ][
 Results Width Height Column
 ][
 Results: make block! Width: length? Matrix/1
 Height: length? Matrix
 repeat Index Width [
 Column: make block! Width
 foreach Row Matrix [
 insert/only tail Column Row/:Index
 ]
 insert/only tail Results Column
 ]
 Results
 ]

 Note that every word that is defined here is in Title case. Also note that
 every common word that's in Rebol like 'insert, '/only, 'length? etcetera
 are in lower case. What's _important_ is signalled by the Title case
words.

[...snip...]

  I assume your  [catch]  was a faster way of addressing this same issue,
by
 simply passing the error resulting from an empty argument list back to the
 caller.

 It's a whole lot simpler and catches the error earlier and it runs faster.

 Andrew Martin
 Look what happens when I go to sleep! :-)
 ICQ: 26227169
 http://members.nbci.com/AndrewMartin/
 --


I would say, that your source is (as long as :make, :block!, :length?,
:repeat, :foreach, :insert, :tail are normal, unchanged natives) exactly
equivalent to the same function not having [catch] refinement, because there
is no Throw for it in the source.

Cheers,
Ladislav




[REBOL] Transpose Re:(5)

2000-10-06 Thread lmecir

Hi,

I don't think, that I can bring any theoretical reasons for preferring one
style over the other. I tried both. I must admit, that I liked the style
Andrew is evangelizing more and tried to use it exclusively. The difference
(for me) has shown itself when I wrote a script having six-page listing.
Then I found out, that the orientation in the script using enclosing bracket
indentation worsened drastically (for me) against its RT approved version.
That is why I am currently using the RT approved version and knowing, that
there is a good reason for it.

Cheers
Ladislav


- Original Message -
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Saturday, October 07, 2000 12:00 AM
Subject: [REBOL] Transpose Re:(4)


 This is clearly one of those "you say tomato, I say ketchup" issues.
 Anyone who doesn't like ketchup on his steak (or steak under his ketchup)
 is welcome to skip this post entirely!

 -jn-

 [EMAIL PROTECTED] wrote:
 
  Rebol Crew wrote:
   The contents of a block are indented, but the block's enclosing
brackets
  [] are not. That's because the brackets belong to the prior level of
syntax
  as they define the block, but are not contents of the block. Also it's
  easier to spot breaks between adjacent blocks when the brackets stand
out.
 
  I disagree with Carl's reasoning here, but I can cope with it. I prefer
the
  better human readable style like this example:
 
  repeat Index Width [
  Column: make block! Width
  foreach Row Matrix [
  insert/only tail Column Row/:Index
  ]
  insert/only tail Results Column
  ]
 

 I've always understood INdentation as showing what was IN something else.
 Viewed strictly as a block (i.e. ignoring the fact that I think I know
what
 some of those words mean...) the example above has this shape to my mind's
 eye (abbreviating a few places -- strictly for space -- and making
explicit
 an enclosing block...):

   [*]
 /--^-\

 repeat Index Width [*]
 /---^\
 Column: make block! Width foreach Row Matrix [*] append Results Column
 /-^-\
 append Results Column

 (Those hyphens, carets, asterisks, slashes, and backwardslashes are
 standing in for the nice pretty lines in my head...)

 The top level block contains 4 things -- three words and another block.
 That last block contains 11 things -- the eighth of which is another
 block.  etc...  Notice that the contents are UNDER the brackets  -- [*] --
 that mark the boundaries of the block.

 Of course, this horizontal layout is not going to work typographically,
 especially in email, as my lists get longer.  So we can rotate it to run
 vertically.  Unfortunately I don't have rotated brackets on my keyboard,
 so I'll just have to use the same old more-or-less-vertical ones:

/  repeat  /  Column:
 [  |  Index   |  make
 *-   Width   |  block!
 ]  |  [   |  Width
|  *--   foreach
\  ]   |  Row
   |  Matrix
   |  [/  append
   |  *---   Results
   |  ]\  Column
   |  append
   |  Results
   \  Column

 Notice that the contents of a block are still under the brackets that
 mark the block's boundaries (although logical "under" is now geometrically
 "to the right").  Of course all these overlapping columns of words and
 lines are a little cluttered (even though more compact) so let's try to
 declutter by putting contents between the boundaries of their blocks
 (but still INdenting to make it clear that they are INside the blocks):

 [
 repeat
 Index
 Width
 [
 Column:
 make
 block!
 Width
 foreach
 Row
 Matrix
 [
 append
 tail
 Column
 Row/:Index
 ]
 append
 tail
 Results
 Column
 ]
 ]

 Now let's remember that we know what these "words" mean.  If we do,
 we'll tend to think of bigger units, perhaps called "phrases", that
 group words into fewer, bigger chunks.  If I do that, I'll have to
 keep the first word of a new phrase back at the same level that
 it had before I started "chunking", so I don't lose track of my
 levels.

 If one of these phrases includes a block, I may try to write it out
 all at once.  but if it doesn't fit, I'll try to pull the open brace
 into the line with the rest of the phrase, but leave the content
 indented with the closing brace "outdented" back to its own level
 to make it clear that I've come back up/out a level in the structure.

 [
 repeat Index Width [
 Column: 

[REBOL] Document bug - [catch] There's a catch! Re:

2000-10-06 Thread lmecir

Hi,

I am sure, I didn't explain the things as they should have been explained.
Here is the example, how the code could look:

Transpose: function [
[catch]
"Transposes Matrices"
Matrix [block!]
] [
Results Width Height Column
] [
throw-on-error [
Results: make block! Width: length? Matrix/1
Height: length? Matrix
repeat Index Width [
Column: make block! Width
foreach Row Matrix [
insert/only tail Column Row/:Index
]
insert/only tail Results Column
]
Results
]
]

Now an example use:

 transpose [[1 2 3] [a b c] 3]
** Script Error: Cannot use path on integer! value.
** Where: transpose [[1 2 3] [a b c] 3]

Cheers,
Ladislav

- Original Message -
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]; [EMAIL PROTECTED]
Sent: Saturday, October 07, 2000 2:00 AM
Subject: [REBOL] Document bug - [catch] There's a catch!


 Joel wrote:
I assume your  [catch]  was a faster way of addressing this same
 issue, by simply passing the error resulting from an empty argument list
 back to the caller.

 Andrew (mistakenly!!) wrote:
   It's a whole lot simpler and catches the error earlier and it runs
 faster.

 Ladislav wrote:
  I would say, that your source is (as long as :make, :block!, :length?,
 :repeat, :foreach, :insert, :tail are normal, unchanged natives) exactly
 equivalent to the same function not having [catch] refinement, because
there
 is no Throw for it in the source.

  transpose [[1 2 3] [a b c] 3]
 ** Script Error: Cannot use path on integer! value.
 ** Where: insert/only tail Column Row/:Index

 Ladislav, you're right! I've read the manual on this part, Page 268, 8-26
 Function Attributes, and it reads:
 quote
 If the [catch] attribute is specified, errors that are thrown within the
 function are caught automatically within the function but
 (continued on next page)
 at the point where the function was used. This is useful if you are
 providing a function library (mezzanine functions) and don't want the
error
 to be displayed within your function, where where it was called:
 /Quote

 But it doesn't mention that this _only_ happens if 'throw is used in the
 body of the function or one of functions the function might call.

 I've sent this to feedback and docs @ rebol.com so they can fix it up.

 Andrew Martin
 Foolishly believing the documentation! :-)
 ICQ: 26227169
 http://members.nbci.com/AndrewMartin/
 --







[REBOL] Did you know? - 'Bind is stackable! Re:

2000-10-05 Thread lmecir

Hi,

Andrew wrote:

 Did you know? - 'Bind is stackable!

 I didn't - until I tried it. Have a look at the line:
 if all bind bind Filter 'File 'Header

 Unit: function ['Name [word!] Base-Directory [file!] Sub-Directory [file!]
 Filter [block!]] [Script Header] [
 error? try [
 if system/script/parent/header/File = %user.r [
 set Name make object! [
 Directory: file!
 Files: block!
 ]
 change-dir Base-Directory
 Name: get Name
 Name/Directory: Sub-Directory
 Name/Files: read Name/Directory
 change-dir Name/Directory
 foreach File Name/Files [
 Script: load/header File
 Header: first Script
 if all bind bind Filter 'File 'Header [
 do Script
 ]
 ]
 Name/Directory: join Base-Directory Sub-Directory
 ]
 ]
 ]

 Unit Patches %/C/Rebol/Patch/ %Patches/ [
 Header/File = File
 Header/Patch = Header/Name
 ]

 Unit Enhancements %/C/Rebol/Enhancement/ %Enhancements/ [
 Header/File = File
 Header/Enhancement = Header/Name
 ]

 BTW, 'Unit is my keystone building block for Patches, Enhancements for
Rebol
 and Components and Plug-ins for Rebol applications, like RebMail.

 Note that the order of 'File and 'Header didn't matter. Which leads me to
 wonder if an enhanced version of 'bind that allows a block would be of
 interest to people or Rebol crew.

 Andrew Martin
 ICQ: 26227169
 http://members.nbci.com/AndrewMartin/
 http://members.xoom.com/AndrewMartin/
 --


The order of 'File and 'Header didn't matter only because 'File context,
'Header context and the block bound aren't such, that there is a word e.g.
'Common such that 'Common is in the block and 'Common can be bound to both
'File context and 'Header context. In that case the results would differ.

Regards
Ladislav




[REBOL] a GC bug of the second kind Re:(6)

2000-09-27 Thread lmecir

Hi,

example code:

word: use [a] [a: 11 'a]
get word
recycle
get word

CRASH!

Ladislav

- Original Message - 
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Thursday, September 28, 2000 12:31 AM
Subject: [REBOL] a GC bug of the second kind Re:(5)


 ptretter wrote:
  Just what is the GC bug?
 
 A bug that Rebol crew haven't fixed yet. :-) Unfortunately I've forgotten
 the example code that made Rebol crash. :-( Anyone?
 
 Andrew Martin
 ICQ: 26227169
 http://members.nbci.com/AndrewMartin/
 http://members.xoom.com/AndrewMartin/
 --
 
 
 
 




[REBOL] Interleaving of strings question Re:

2000-09-25 Thread lmecir

Hi,

although your question has a little in common with Rebol, my answers are as
follows:

1. It would be more precise to interleave each bit - ie. each binary digit -
as the smallest unit of information

2. in that case the bit - sort yields:
 [0,0 2,2 1,5 5,1]

3. as you pointed out, the result of the sort doesn't depend on the
representation, but on the comparison function, any suitable representation
can do

4. your suggestion doesn't work, because you need close things in the terms
of distance to remain close in the terms of sort. Your suggestion works only
in the neighborhood of the 0,0 point

Best regards
Ladislav

- Original Message -
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Monday, September 25, 2000 1:04 PM
Subject: [REBOL] Interleaving of strings question


 I was thinking about the earlier postings about
 sorting coordinates by interleaving digits of the 2
 axis values.  The interleaving, it would seem, is to
 make the longitude as significant as the latitude, in
 terms of distance from other points.  Ignoring the
 need to have the lat/long pairs stored that way for
 later processing, and ignoring stated expected values
 for the coordinates I thought:

 1.  Wouldn't it be more precise to interleave each
 digit?

 2.  In terms of a regular x,y system, even that would
 be incorrect sometimes. E.G.: [ 0,0 1,5 2,2 5,1 ] (a
 sorted set of simplified coordinates) isn't correct.
 2,2 is closer to 0,0; 1,5 and 5,1 are the same
 distance from 0,0.

 3.  Could pairs or tuples be used?  Answer: pairs
 didn't sort that way and I have no reason to assume
 sort would think of tuples as coordinates.

 4.  Wouldn't it be the least convoluted to have a
 /compare function for sort that understood that all
 components of the coordinate were equally significant?
  That way there's no manipulating the coordinates, and
 it should be the most precise.

 Would a Pythagorean type thing work, because it looks
 like simply summing the absolute differences between
 each coordinate component isn't right:

 1,1 to 1,5 = 4  ((1-1)+(5-1))
 1,1 to 2,4 = 4  ((2-1)+(4-1))

 yet 2,4 is closer to 1,1 than is 1,5.  Until the real
 distance is needed, I don't think you'd have to take
 the square root of the sum (and how do you do that for
 3-dimensions, does it become cubed and cube root -
 aha)

 (ABS(x1-x2) to the nth) + (ABS(y1-y2) to the nth) ...
 + (ABS(n1-n2) to the nth)


 Comments?  Is this right?

 __
 Do You Yahoo!?
 Send instant messages  get email alerts with Yahoo! Messenger.
 http://im.yahoo.com/







[REBOL] a GC bug of the second kind

2000-09-24 Thread lmecir

Jeff already signaled, that List! and Hash! datatypes are being fixed. I
succeeded to track down the behaviour to the following:

h: make hash! 0
insert h copy "0123456789"
h
recycle
insert h copy "0123456789"
CRASH!

just in case you didn't know...

Regards
Ladislav




[REBOL] Compiler for Rebol ? Re:(8)

2000-09-24 Thread lmecir

Well, let me throw in some thoughts.

I think, that the debate started to look more abstract than I prefer. My
comments are:

1) Rebol is IMHO designed with the runtime code accessibility in mind
(inspired by Lisp), so I do not think, there's an easy way to convert that
feature to its opposite.

2) I prefer the speed when compilation is considered, the source code
protection is only a minor effect surely achievable by more direct means
(discussed by Joel some time ago).
2a) When I look at the development in processor speeds (GHz looking as
standard for year 2001 processors) and the neverstopping need to increase
processor speeds, it is surely less preferable to write programs 100 or more
times slower than C in some cases, so the speed is something any language
including Rebol could use.
2b) Rebol with its mutable values used to store code radically differs even
from Lisp, that uses immutable series for that AFAIK. That fact has
immediate consequences - Self Modifying Code looks as standard - even some
basic Rebol constructs are modifying, eg:

2ba) Use - modifies its (code) block argument (this causes even "unexpected"
behaviour when recursive functions are called) and causes its code block
argument very hard to compile when speed is the goal

2bb) Make object! - modifies its (code) block argument - see above

2bc) Bind - modifying, as opposed to Bind/copy, which behaves better

2bd) any mutables contained in the code aren't protected against change - no
compilation advantage

2be) the code block can easily modify itself - a feature making compilation
almost impractical

Not trying to criticize, just to discuss the possibilities. What do you
think?
Ladislav

- Original Message -
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Sunday, September 24, 2000 7:24 PM
Subject: [REBOL] Compiler for Rebol ? Re:(7)


 [EMAIL PROTECTED] wrote:
 
  Right, thats my opinion too, but by using compile to hide the
  source we would loose the ability to acces code at runtime of
  compiled code. Coming from CommonLisp I think this would be
  very bad - we would give away a really important feature!
 

 I don't want to belabor this point unnecessrily (I probably
 have!), but I do NOT agree with casting this issue as a value
 judgement over an option which other languages provide the
 developer.

 If you (or your company) takes the policy position that you
 will never buy/license any software that comes without source,
 that's your right!  (And if that means that you therefore can't
 use some products because they don't come with that option...
 well, you had the choice, so you get the consequences.)

 EQUALLY IMPORTANT IS THE DEVELOPERS RIGHT TO CHOOSE...

 If some developer creates a product for which he/she chooses not
 to distribute the source, that's his/her right!  (And if that
 means that she/he loses some sales to people who require source
 as a precondition... well, she/he had the choice, so she/he gets
 the consequences.)

 EITHER WAY, that's what free markets are about.

 But to pre-empt EITHER the consumers' or developers' rights to
 choose how they will do business by creating a development
 environment (or a political environment or an economic one...)
 that gives all the rights of choice to one party (or by
 institutionalizing that party's choice so that it isn't even
 a choice any longer) is to prevent the market from working
 such things out on a case by case basis -- which I believe to
 be the fairest mechanism in the long run.

 
   Carl's support for MS operating systems doesn't keep me from
   using any of several varieties of Unix/Linux (except Debian, but
   that's another issue!), MacOS, etc.
 
  I never said something against this fact.
 

 You didn't, and I didn't mean to imply that you had.

 I was using the "choice of O/S" issue (which I think we all
 agree is a Good Thing) to try to illustrate why I think the
 "choice of distribution form" is also a Good Thing.

 
  _I_ would prefer using compilation (native, bytecode or whatever)
  for making the code more efficient and smaller.
 

 And I wholeheartedly support any steps which allow you that choice!

 
  But I do _not_ want to loose runtime accessibility to the code.
 

 And that, also, is your choice.  You have a perfect right to make
 that a condition of doing business with you.  However, I don't
 support making that a constraint on how everybody can conduct their
 affairs, when they are NOT doing business with you.  That's THEIR
 choice!

 -jn-








[REBOL] Small admin/report benchmark Re:(3)

2000-09-23 Thread lmecir

Hi Joel,

You wrote:
 Ladislav's comes next (this is the second script he
 posted; the first one blew up on my box repeatedly).

Confused, I expected the SECOND script (the script using Hash! datatype) to
blow up - it looked to me like RT didn't succeed to implement of Hash!
datatype reliably, or like there was another sign of the GC bug...

Regards
Ladislav






[REBOL] Small admin/report benchmark Re:(5)

2000-09-23 Thread lmecir

Hi Andrew,

no, that is not a bug for me (a feature). The real bug is, that you can use
my Hash! ADS implementation for Joel's original password file (22 lines
AFAIK), but it crashes Rebol (not error, simply crash, like GC bug) for his
huge password file (360,448 lines ).

If you are willing to test it, I would be very glad.

Regards
Ladislav

 Joel wrote:
   Ladislav's comes next (this is the second script he posted; the first
 one blew up on my box repeatedly).

 Ladislav wrote:
  Confused, I expected the SECOND script (the script using Hash! datatype)
 to blow up - it looked to me like RT didn't succeed to implement of Hash!
 datatype reliably, or like there was another sign of the GC bug...

 Are you thinking of the "sort-of bug" in objects where hash! datatypes,
like
 sub-objects, aren't copied?

 Andrew Martin
 ICQ: 26227169
 http://members.ncbi.com/AndrewMartin/
 http://members.xoom.com/AndrewMartin/
 --






[REBOL] How do I get the sort/compare func not to sort? Re:(2)

2000-09-20 Thread lmecir

Hi,

there is a help, but you must use a stable sorting algorithm, eg. my
Merge-sort could do what you want (can send you my %msort.r privately).

Regards
Ladislav

 Based on the following:

  blk1
 == [8 6 4 2 0 3 7 5 1 9]
  sort/compare blk1 func [a b] [a  b]
 == [0 1 2 3 4 5 6 7 8 9]
  sort/compare blk1 func [a b] [a  b]
 == [9 8 7 6 5 4 3 2 1 0]
  sort/compare blk1 func [a b] [(a // 2)  (b // 2)]
 == [6 2 8 0 4 3 7 5 1 9]
  sort/compare blk1 func [a b] [(a // 2)  (b // 2)]
 == [2 0 6 4 8 7 3 9 1 5]
  sort/compare blk1 func [a b] [(a // 2)  (b // 2)]
 == [0 4 2 8 6 3 7 5 1 9]
  sort/compare blk1 func [a b] [(a // 2)  (b // 2)]
 == [4 8 0 6 2 7 3 9 1 5]
  sort/compare blk1 func [a b] [true]
 == [1 5 2 9 7 6 8 4 0 3]
  sort/compare blk1 func [a b] [true]
 == [0 3 7 4 6 9 5 1 2 8]
  sort/compare blk1 func [a b] [true]
 == [2 8 6 1 9 4 3 0 7 5]

 I infer two things:

 1)  the comparison function should return  true  or  false according
 to whether its two arguments are presented in the desired order
 or not, and

 2)  sort/compare  uses an unstable sorting algorithm.  That bit of
 jargon that means that the result is guaranteed to satisfy the
 comparison function between adjacent elements, but is there is
 NO guarantee that original ordering is preserved (even among
 elements that were properly ordered to begin with).

 We can test the second inference by creating a comparison that uses
 only part of the values, and see if the ignored portions remain in
 the same relative positions:

  blk: ["fe" "ca" "br" "ff" "cb" "bq"]
 == ["fe" "ca" "br" "ff" "cb" "bq"]
  sort/compare blk func [a b] [(first a)  (first b)]
 == ["bq" "br" "ca" "cb" "ff" "fe"]
  sort/compare blk func [a b] [(first a)  (first b)]
 == ["br" "bq" "ca" "cb" "fe" "ff"]
  sort/compare blk func [a b] [(first a)  (first b)]
 == ["bq" "br" "ca" "cb" "ff" "fe"]
  sort/compare blk func [a b] [true]
 == ["cb" "ff" "br" "bq" "ca" "fe"]
  sort/compare blk func [a b] [(first a)  (first b)]
 == ["bq" "br" "cb" "ca" "fe" "ff"]

 Notice that the function requires that strings be in order by their
 first letter only.  In each of the first three uses, that property
 is clearly possessed by the result, but ordering (even original
 ordering) between strings with the same first letter gets fiddled
 arbitrarily.

 Using a compare function which always returns  true  basically
 lets the sort routine do whatever it wants.  After that has
 happened, returning to the first-letter-only sort produces yet
 another ordering (in which two out of three pseudo-equal strings
 change ordering from the input).


 I'm out of ideas, except to say "don't sort to start with", but you
 didn't hear it from me!   ;-)

 -jn-

 [EMAIL PROTECTED] wrote:
 
  Hello,
 
  Given,
  s: "abvde"
  sort/compare s func [a b][return 0]
 
  What can I exchange for the 0 return value such that the input is left
  unchanged?
  (and no, the answer is not "don't sort to start with" :-)
  I've tried -1, 0, 1.   They all change the string!
 
  Anton.







[REBOL] Small admin/report benchmark Re:

2000-09-19 Thread lmecir

Hi Joel,

I didn't succeed to run your benchmark (not enough memory error occurred),
so I modified it a bit:

Rebol []

file: home/passwords.txt

shells: copy make block! 5
countshell: func [sh [string!] /local shr] [
either none? shr: find shells sh [
append shells reduce [sh 1]
][
change shr: next shr 1 + shr/1
]
]

t1: now/time

p: open/read/lines/direct file

while [not error? try [line: first p]] [
countshell any [pick parse/all line ":" 7  "(none)"]
]

foreach [sh n] sort/skip shells 2 [
n: to-string n
while [3  length? n] [insert n " "]
print [n sh]
]

prin "Time1: " print now/time - t1
close p

The results were:

 include/mult %smallad.r
Script: "Untitled" (none)
196608 (none)
98304 /bin/bash
16384 /bin/false
16384 /bin/sync
16384 /sbin/halt
16384 /sbin/shutdown
Time1: 0:00:11

Here is my second attempt, which works with the original file:

REBOL []

include %ads.r

file: home/smallad.txt

shells: make-ads
countshell: func [sh [string!] /local shr] [
associate shells sh 1 + associated/or shells sh [0]
]

p: open/read/lines/direct file
while [not error? try [line: first p]] [
countshell any [pick parse/all line ":" 7  "(none)"]
]

shells2: sort to block! first shells

foreach sh shells2 [
n: associated shells sh
n: to-string n
while [3  length? n] [insert n " "]
print [n sh]
]

close p

The results are:

 12 (none)
  6 /bin/bash
  1 /bin/false
  1 /bin/sync
  1 /sbin/halt
  1 /sbin/shutdown

For the small input file. Problem is, that for the huge file
(%passwords.txt) an error (a GC fault?) occurs. Would anybody have time to
test it?

Regards
Ladislav

Here is %ads.r:

Hi Rebols,

here is my attempt to satisfy those who don't like objects for ADS
implementation,
those, who would like to have the fast searching capability,
those, who would like to store in Any-type Rebol values and
those who want to use only strings for keys.

Rebol [
Title: "ADS"
Name: 'Ads
File: %Ads.r
Author: "Ladislav Mecir"
Email: [EMAIL PROTECTED]
Date: 19/September/2000
]

make-ads: does [reduce [make hash! 0 make block! 0]]

associate: function [
ads [block!]
key [string!]
value [any-type!]
] [index] [
either index: find first ads key [
index: index? index
change at second ads index head insert/only copy [] get/any 'value
] [
insert tail first ads key
insert tail second ads get/any 'value
]
ads
]

deassociate: function [
ads [block!]
key [string!]
] [index] [
if index: find first ads key [
index: index? index
remove at first ads index
remove at second ads index
]
ads
]

associated: function [
ads [block!]
key [string!]
/or
or-block [block!]
] [index] [
either index: find first ads key [
return pick second ads index? index
] [
if or [do or-block]
]
]

- Original Message -
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED]
Sent: Monday, September 18, 2000 6:16 AM
Subject: [REBOL] Small admin/report benchmark


 Here's a small benchmark based on a fairly typical kind
 of sysadmin, file processing, or data reduction task.
 The timing results are given after the description of
 the problem and the code I used for timing.

 I'm including a sample data file and output so that
 anyone who wants to improve on my code can test his/her
 solution with the same data.


 Problem:

 Read through the colon-delimited file below (a copy of
 an /etc/passwd file, mangled for security purposes),
 and print a report tallying the distinct values in the
 7th field (in this case, the field that identifies the
 default shell for each userID).  Sort the results by
 the value of the field being tallied, and print the
 results in neat columns.

 == begin sample data file ==
 ayxa:a:824:277:Zmgxoy "Uucl" Tmaam:/ibmg/rsrn:/bin/bash
 ciyp:x:8:72:jksi:/zfp/qnffy/drgn:
 grnfk:p:115:383:SNMKW hwxyzry:/evfk/tsmgt:/bin/bash
 guqkvtwn:o:2:2:blvbnjsg:/lbld:/sbin/shutdown
 kpsbwt:z:85:98:frwbqf:/zeu/bml/egtyin-mexi:
 kst:y:1:3:gsi:/opj:
 kvik:f:3:9:clnd:/bfje:/bin/sync
 lw:b:518:941:Nxpn "VAXVAzjzw" Muhxp:/esaq/jy:/bin/bash
 mmlmgxep:g:69:4:lnuytrat:/vvot:
 nnd:g:46:89:WQT Pcpu:/shrs/vzq:
 ospax:t:707:92:Lpojk bro Gokzfe:/qaqf/gaedx:/bin/bash
 pbubex:v:7:9:eworcq:/khuc:
 qpdd:l:39:19:qckl:/omg/clghd/szdr:
 rkuu:p:2:1:rusj:/ltnm:/sbin/halt
 sft:q:045:235:H Buya Gtdtre:/stj/W75/ot:/bin/false
 srimrg:c:19:41:Ybltzu:/:
 vgonz:n:86:051:oqufv:/hgo/awkxv:
 vqn:n:7:0:ant:/npy/hpm:
 wbci:s:2:5:pyiy:/xngl:/bin/bash
 wlzr:o:7:00:rqwe:/mxy/rkchz/lsfu:
 xao:c:21:50::/fgqu/orw:/bin/bash
 yf:d:1:6:ay:/xzb/njwes/kvd:
 === end sample data file ===

 = begin sample output list =
  12 (none)
   6 /bin/bash
   1 /bin/false
   1 /bin/sync
   1 /sbin/halt
   1 /sbin/shutdown
 == end sample output list ==


 Perl solution:

 A fairly typical Perl script to perform this task is
 

[REBOL] Essay on Associative Data Stores Re:

2000-09-18 Thread lmecir

Hi Joel,

two notes:

1) I think that some posts on ADS missed one very important point - the
speed. The problem is, that Find (sequential search) may be a bottleneck for
some apps.

2) Select may be less general than Select/only sometimes.

Regards
Ladislav




[REBOL] Associative Data Store Re:

2000-09-18 Thread lmecir

Hi Andrew,

there is a lot of cases, where your functions won't work as expected, eg.:

blk: copy []
associate blk [2] 3
associate? blk [2]

The other problem is, that your functions won't accept Any-type! values for
Key/Value

Regards
Ladislav

 Here's an implementation for an Associative Data Store (ADS) that uses
only
 two functions, doesn't require an object per ADS and can use any Rebol
value
 as a key. Comment invited. Thanks to Gabriele for showing how to shorten
the
 'Associate? function.

 [
 Rebol [
 Title: "Associate"
 Name: 'Associate
 File: %Associate.r
 Author: "Andrew Martin"
 Email: [EMAIL PROTECTED]
 Date: 18/September/2000
 ]

 Associate: function [Block [block!] Key Value] [Index] [
 Index: find Block Key
 either none? Value [
 if found? Index [
 remove/part Index 2
 ]
 ][
 either found? Index [
 change/only next Index reduce [Value]
 ][
 append Block reduce [Key reduce [Value]]
 ]
 ]
 Block
 ]

 Associate?: function [Block [block!] Key] [Value] [
 all [
 Value: select Block Key
 first Value
 ]
 ]
 ]

 Andrew Martin
 ICQ: 26227169
 http://members.ncbi.com/AndrewMartin/
 http://members.xoom.com/AndrewMartin/
 --






[REBOL] How do I dynamically extend an object! instance Re:(3)

2000-09-12 Thread lmecir

Hi bobr,

what are the results of the code below and which version of Rebol you use?

-Ladislav

 At 09:09 PM 9/10/00 +0200, [EMAIL PROTECTED] wrote:
 Hi bobr,
  - can it be done without creating a new instance?
 
 No.
 
 
 ok here is my latest method for extending an object in-situ.
 the example hasnt been turned into a function
 and I hope I am not violating any storage but here goes...
 [
 
 a: make object! [
   addr: "417 howser st"
   name: "joyce haversham"
   ]
 
 wds: first a
 vals: second a
 
 append wds 'email
 append vals "joyce@someplace"
 
 probe a
 
 ]
 
 now this -looks- fine,
 you can save/probe/mold the object and read it back in
 with no problems. best of all no new object
 is instantiated so all references to a are updated as well.
 
 for some reason you cannot access the new items
 by a path.  as soon as you type  a/email
 there is an error.
 
 
 remove seems to be just as simple but
 I think I will stay away from it
 till I know exactly is going on with a/email 
 and why the path doesnt work before I drop
 something out of the middle.
 
 
 ;# mailto: [EMAIL PROTECTED]
 
 




[REBOL] rebol weak points (i think) Re:(3)

2000-09-10 Thread lmecir

Hi Rishi,

I think, that you are missing only complications here. What you are saying
is, that Math below is an instance of Object! datatype. You are right. You
are saying, that you would prefer it to be a class. But classes in a lot of
languages (except for C++, Java, ..., AFAIK) are instances of object
datatype too. There is only a little other language classes could do for you
and Rebol objects can't, IMHO. (You can even create a Rebol class hierarchy
using Rebol objects, as I demonstrated.)

Regards
Ladislav

 no. The Math/Pie you have created is an instance variable not a static
 variable. It is associated with an instance of the class, not the class
 itself. A static variable means that there is a single copy of this
variable
 associated with class itself. You do not need to instantiate a class to
use
 static variable. For example:

 make-circle: make func [
 radius
 /local blah-blah-blah
 /static num_circles  ;let's say this is how you create static var.
 ] [
 num_circles: num_circles + 1 ;this may not be correct but you get the
 idea...
 return make object! [
 ;object code goes here
 ]
 ]

 small-circle: make-math(2)
 large-circle: make-math(100)
 print make-circle/num-circles  ;this should hypothetically print out 2
 print num-circles ;should print error

 Unfortunately, it would not make sense to add a static option the way I
have
 done it since not all functions return objects.

 Anyway, the fact that rebol does not have static variables and static
 functions is no big deal. It was probably a concious decision not to
include
 it.

 The main advantage of having static variables would be to prevent name
 collisions and to group variables/functions that act on a class (not an
 object) together for use in a more natural way.

 The main disadvantage of having static variables is that perhaps it is an
 unnecessary complication. But I don't think so. Maybe because I come from
 java/javascript background. I'm still wondering though if there is a way
to
 have static variables that I don't know.

 Regardless, the main problem that I wonder about is if rebol is suited for
 modular programming where people reuse other people's functions/code.
Since
 everything is either global or local, it seems as though it would be
 unnatural to use rebol in this way. Java has packages and stuff...perhaps
I
 am not thinking straight and have too much java in my blood (which I have
 been doing to much of lately and finally got sick of all the abstractions
 that got in the way of doing simple stuff!!)

 Rishi


 - Original Message -
 From: [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Saturday, September 09, 2000 6:03 PM
 Subject: [REBOL] rebol weak points (i think) Re:


  Rishi wrote:
   Math.pi=20
 
   Math: make object! [
  [Pie: 20
  []
   Math/Pie
  == 20
   Pie
  ** Script Error: Pie has no value.
  ** Where: Pie
  
 
  Andrew Martin
  ICQ: 26227169
  http://members.xoom.com/AndrewMartin/
  --
 
 






[REBOL] How do I dynamically extend an object! instance Re:

2000-09-10 Thread lmecir

Hi bobr,

you wrote:

 I have an existing dataase
 of saved objects which I wish to add fields to (IE add words:).
 I probably only want to add the words if I absolutely must
 in order to keep size down. I also may already
 have added a particular word to an object instance and dont wish to
 overwrite the value already associated with that word.


 Here is what I have so far.
 questions follow below.



 object-addword: func [

  { add a word only if it is not already there,
returns a new instance of the object

examples
  myobj: object-addword myobj emailaddr
  dbrecord: object-addword/initial dbrecord areacode 978
  }

  o   [object!] "the object to have a word added"
  'w1 [any-word!]   "the word to add"
  /initial
 vdef [any-type!]   "provide initial value for the word"
  /local
 mb "mini block"
  ] [
 if not find (first o) w1 [
 ; try to emulate:   set/any in o w1 none
 mb: do rejoin [ {[} :w1 {: none ]} ]
 o: make o mb
 if initial [ set/any in o w1 vdef ]
 ]
 return o
  ]


 ; for discussion:

 - can this be written more succinctly yet not hardcode
   anything about the object?

I would suggest the following:

object-addword: func [
{
add a word only if it is not already there,
returns a new instance of object

examples
myobj: object-addword myobj emailaddr
dbrecord: object-addword/initial dbrecord areacode 978
}
o   [object!]   "the object to have a word added"
; I prefer not to use unevaluated/fetched arguments
w1 [word!]   "the word to add"
/initial
vdef [any-type!]   "provide initial value for the word"
] [
if not find (first o) w1 [
o: make o reduce [to set-word! w1 none]
; because you declared vdef to be any-type!, this is the only way to
set it
error? set/any in o w1 get/any 'vdef
]
return o
]

Example:

 probe object-addword/initial make object! [] 'a ()

make object! [
a: unset
]

The problem is, that even this is not general enough, as is explained below

 - can it be done without creating a new instance?

No.

 - can a corresponding function for removing a word
   from an object be written without evaluating
   all the other words/elements?

The general answer is no, IMHO, only special cases can be solved. There are
two problems:

1. 'Self can be any-type! in Rebol.
2. There are problems with "complicated" datatypes, eg. functions


 I have tried several arrangements for the arguments
 and names for the function. I have settled on

   object-addword   rcvrobj   operand

 - are the precedents for putting the word operand first?
 - since, from context, you can tell which argument
   is the object and which is simply a word
   which may need to be added to the object,
   why not make the function figure out
   which argument is which type and do the right thing
   regardless of how it is called?
   can this be coded without resorting to second-level functions?


It is feasible, if you don't use unevaluated arguments:

object-addword: func [
[catch]
o [object! word!]
w [object! word!]
] [
if word? o [
set [o w] reduce [w o]
]
if not object? o [
throw make error! reduce ['script 'expect-arg 'object-addword 'o
object!]
]
if not word? w [
throw make error! reduce ['script 'expect-arg 'object-addword 'w
word!]
]
; ...
]

 - is a better name for the function possible?
   I have considered 'object+ and 'object+word as potential names.
   Is there a precedent that I have missed?

 ;# mailto: [EMAIL PROTECTED]






[REBOL] Trying to compose a block out of global and local bindings Re:(2)

2000-09-08 Thread lmecir

Hi Elan,

you wrote:
 letter2: func [b] [
   foreach name ["Sue" "Sally"] [
  print bind b 'name
   ]
 ]

 Here BIND directs REBOL to associate all words contained in 'b with the
 "closest" context that contains the symbol name.

L:
I would recommend to change the wording:

{Bind associates all words contained in B (not in 'B, because in 'B is
"contained" a block IMHO) with the context previously associated with the
word 'Name (again, not Name, as you wrote) which is its second argument.}

I am not sure I understand the term "closest" above, I would recommend to
not use
it here.

Elan:
 Because
 1. the context in which the BIND expression is being used is the block
 passed to foreach, and

L:
Again, a change suggested. I don't believe, that the block passed to Foreach
is a context, sorry. This wording looks better:

{The second argument of Bind is the word 'Name previously associated with
the context Foreach created.}

Elan:
 2.
 a) because the first argument passed to foreach (foreach name ...) is an
 instance of the word name

L:
This doesn't make much sense to me too, the sentence: {'Name (the second
argument
of Bind above) is an instance of the Word! datatype} looks like a correct
usage of
the word "instance", but it doesn't say what you wanted. I would recommend
to look at the previous suggestion.

Elan:
 b) there therefore now exists an instance of the word name that is bound
to
 foreach's context,

L:
Again a change necessary, IMHO: {There exists a word 'Name that is bound to
a context Foreach created.} is the wording I prefer.

Elan:

 3. == therefore
 a) REBOL will identify foreach's context as the "closest" context in which
 'name occurs.

L:
I think, that you switched the cause and the consequence here: the truth is,
that the word
'Name above (the second argument of Bind) was bound by Foreach to the
context it created and that is why "there exists a word 'Name that is bound
to a context Foreach created".

Elan:
 This is the context to which all words in the block b are now
 being bound, provided they are defined in foreach's context.
 b) Because of 3.a) the symbol name in the block b will be bound to the
 foreach context. (If the block b contained other words and some or all of
 these other words were also defined in the foreach context, then all these
 words would be bound to the foreach context as well.

L:
I don't like the use of the word "symbol" here. The meaning of it is defined
in
Rebol. I found the use of this word in Rebol with different meaning,
than Rebol assigned to it ambiguous.

Elan:
 Words that are not
 defined in the foreach context remain bound to whichever context they
 originated in, when the block b was formed, or they remain unset!, if they
 were never set to a value to begin with).

L:
Again a statement I would suggest to change: {Words that are not contained
(whether defined or not is
irrelevant) in the context Foreach created remain unchanged, while words,
that are contained in the context Foreach created are replaced (in B) by
their equivalents bound to the above context.}

Elan:

 RESULT:

  name: "Bob"
 == "Bob"
  message: ["hi" name "welcome back"]
 == ["hi" name "welcome back"]
  letter2: func [b] [
 [  foreach name ["Sue" "Sally"] [
 [ print bind b 'name
 [  ]
 []
  letter2 message
 hi Sue welcome back
 hi Sally welcome back

 Note that as a side-effect the symbol name in the message block remains
 bound to the value it was last associated with in the letter2 function:

  reduce message
 == ["hi" "Sally" "welcome back"]


L:
Yes, this effect can be considered a self-modification of the code
presented, I think.

Elan:
 If that should be relevant, i.e. you want to prevent the modification of
 the binding of the word name in the original message block, you can use
 bind/copy, which generates a duplicate of the block, before it binds it:

 letter2: func [b] [
   foreach name ["Sue" "Sally"] [
  print bind/copy b 'name
   ]
 ]

  letter2 message
 hi Sue welcome back
 hi Sally welcome back
  reduce message
 == ["hi" "Bob" "welcome back"]

 Note that the word used as foreach's first argument (foreach name ...) is
 not bound in the context of your letter2 function in which foreach is
 evaluated. It is bound in the context of foreach.

L:
A different wording: {Note that the word used as Foreach's first argument
(foreach name ...) is not bound in the context of your Letter2 function. It
is bound in the context Foreach created.}

I would prefer not saying, that "...Foreach is evaluated in a context,...",
because I don't know, what that should mean. To the contrary, I am pretty
sure, that there are examples of Rebol code, for which you cannot find any
"context they are evaluated in".

Elan:

 Let us demonstrate that by collecting different instances of name into a
 block. We being with the global instance:

  names: []
 == []
  name: "This is the global instance of name."
 == "This is the global instance of name."
  insert tail names 'name

[REBOL] Trying to compose a block out of global and local bindings Re:(2)

2000-09-08 Thread lmecir

Hi,

SS wrote:

 I'll point out quickly that what you're trying to do is generally
 considered a bad programming practice, i.e. referencing a variable
 internal to a function from its argument. A caller shouldn't need to know
 about and shouldn't really have direct access to variables local to a
 function.

 I will however provide an example of how to do what I think you're trying
 to do and recommend that you rethink your approach in any case because
 this is almost as bad but I think it demonstrates that your problem was
 perhaps not one as much of scope but more of tokenization:

  letter2: func [b][foreach n ["sally" "sue"][print replace (copy b)
'name n]]
  greeting: ["hi" name "welcome back"]
 == ["hi" name "welcome back"]
  {I prefer not to overwrite REBOL words, like "form" from your example}
 == {I prefer not to overwrite REBOL words, like "form" from your example}
  name: "bob"
 == "bob"
  letter2 greeting
 hi sally welcome back
 hi sue welcome back
 


 FWIW,

 SS


The self-modifying Bind-, or its non-self-modifying Bind/copy- variant
approach really doesn't look preferrably to me. Here is an approach that
looks different IMHO:

letter2: func [b /local subst][
subst: func [name] reduce [:print b]
foreach n ["sally" "sue"][subst n]
]
greeting: ["hi" name "welcome back"]
name: "bob"
letter2 greeting

What do you think?
Ladislav



 On Thu, 7 Sep 2000 [EMAIL PROTECTED] wrote:

   letter2: func [b /local name] [foreach n ["sally" "sue"][ name: n
print reform reduce b] ]
 
   form
  == ["hi" name "welcome back"]
 
   name
  == "bob"
 
   letter2 form
  hi bob welcome back
  hi bob welcome back
 
  ... the only problem is I was hoping that the loop values in letter2
would take precedence over the globally bound value of name and allow me to
create a form letter of sorts.
 
  Could anyone help with this please?
 
 
 
  Get your FREE Email and Voicemail at Lycos Communications at
  http://comm.lycos.com
 
 







[REBOL] write does not return a value upon success. This is bad for try blocks Re:

2000-09-07 Thread lmecir

Hi,

try this:

tries: 3
until [
set/any 'm try [write
ftp://chuck:[EMAIL PROTECTED]/crossing/ndtd/user.r "hi there"]
tries: tries - 1
any [tries = 0 unset? get/any 'm]
]

Regards
Ladislav

 I am writing a script that will try 3 times to write a file and then fail,
however, I cant place a try block around the REBOL write statement because
it does not return anything upon success, thus I get an error that the word
is not bound:

  m: try [ write ftp://chuck:[EMAIL PROTECTED]/crossing/ndtd/user.r
"hi there" ]
 connecting to: 170.16.15.136
 ** User Error: Server error: tcp 530 Login incorrect..
 ** Where: write ftp://chuck:[EMAIL PROTECTED]/crossing/ndtd/user.r "hi
there"
 ; -- great: when write fails 'm is bound
  m: try [ write ftp://chuck:[EMAIL PROTECTED]/crossing/ndtd/user.r
"hi there" ]
 connecting to: 170.16.15.136
 ** Script Error: m needs a value.
 ** Where: m: try [write
ftp://chuck:[EMAIL PROTECTED]/crossing/ndtd/user.r "hi there"]
 ; --- well this sucks. I cant get a return value upon success



 Get your FREE Email and Voicemail at Lycos Communications at
 http://comm.lycos.com






[REBOL] Trying to compose a block out of global and local bindings Re:

2000-09-07 Thread lmecir

Hi,

try this:

letter2: func [b] [foreach name ["sally" "sue"][print bind/copy b
'name]]
form: ["hi" name "welcome back"]
letter2 form

Regards
Ladislav

  letter2: func [b /local name] [foreach n ["sally" "sue"][ name: n print
reform reduce b] ]

  form
 == ["hi" name "welcome back"]

  name
 == "bob"

  letter2 form
 hi bob welcome back
 hi bob welcome back

 ... the only problem is I was hoping that the loop values in letter2 would
take precedence over the globally bound value of name and allow me to create
a form letter of sorts.

 Could anyone help with this please?



 Get your FREE Email and Voicemail at Lycos Communications at
 http://comm.lycos.com






[REBOL] Rolling your own ideal looper: does Repeat still have a bug? Re:(7)

2000-09-01 Thread lmecir

Hi Elan,

the problem has been solved by the function For2 (you can see it
at the end of the mail). Your solution (I call it For1) differs
here:

 for1 i a: [1 2] tail a 1 [print mold i]
[1 2]
[2]

 for2 i a: [1 2] tail a 1 [print mold i]
[1 2]
[2]
[]

Regards
Ladislav

 Hi Galt,

 it appears I didn't got all the emails in this thread. So the
problem may
 already be solved.

 you wrote:
 Ladislav,
 
 That is an impressive For function!
 your example of using
 a: [1 2]
 for s a tail a 1 [print s]
 as a test is very amusing bug, looks
 like an infinite loop on windows, just
 keeps printing newlines without ever ending.

 I guess you would rather see

  for s a tail a 1 [print s]
 1 2
 2

 I think that that's reasonable. The patched for version below
does that.

 If you source the for function you'll see why for behaves as it
does. The
 patched version corrects this and the other observed oddities.
The results
 of running the patched version:

  for s a next a -1 [print s]
 == none
  for s a next a 1 [print s]
 1 2
 2
  for s a tail a 1 [print s]
 1 2
 2
  for s a back tail a 1 [print s]
 1 2
 2

 I added the following code to for:

 ;- the following line forces for to interpret
 ;- "tail of a series" as intended to mean "break at end of a
series".

 if all [positive? bump tail? end ] [ end: back end ]


 ;- the following either any .. all .. combo catches errors
resulting
 ;- from an end index that is higher than a start index with
a
 ;- negative bump value, and also catches infinite loops that
result
 ;- from passing an empty series

 either any [
  empty? head end
  all [
if (negative? bump) [ op: :lesser?]
op index? start index? end
  ]
]
 [
   none
 ][


 Note that I moved the expression if (negative? bump) [ op:
:lesser?] into
 the all block of either's any block.


 The complete pathced for function follows:

 for: func [
 "Repeats a block over a range of values."
 [catch throw]
 'word [word!] "Variable to hold current value"
 start [number! series! money! time! date! char!] "Starting
value"
 end [number! series! money! time! date! char!] "Ending
value"
 bump [number! money! time! char!] "Amount to skip each time"
 body [block!] "Block to evaluate"
 /local result do-body op
 ][
   if (type? start)  (type? end) [
 throw make error! reduce ['script 'expect-arg 'for 'end
type? start]
   ]
   do-body: func reduce [[throw] word] body
   op: :greater-or-equal?
   either series? start [
 if not same? head start head end [
   throw make error! reduce ['script 'invalid-arg end]
 ]
 ;- the following line forces for to interpret
 ;- "tail of a series" as intended to mean "break at end of a
series".

 if all [positive? bump tail? end ] [ end: back end ]

 ;- the following either any .. all .. combo catches errors
resulting
 ;- from an end index that is higher than a start index with
a
 ;- negative bump value, and also catches infinite loops that
result
 ;- from passing an empty series

 either any [
  empty? head end
  all [
if (negative? bump) [ op: :lesser?]
op index? start index? end
  ]
]
 [
   none
 ][
   ;- we are dealing with a valid series
   while [op index? end index? start] [
 set/any 'result do-body start
 start: skip start bump
   ]
   if (negative? bump) [
 set/any 'result do-body start
   ]
 ]
   ] [
 if (negative? bump) [op: :lesser-or-equal?]
 while [op end start] [
   set/any 'result do-body start
   start: start + bump
 ]
   ]
   get/any 'result
 ]



 
 Just for kicks, I just tried this:
  for s a back tail a 1 [print s]
 1 2
 2
 
 so that it stops at the last real position,
 and that seemed to work, althout the expression
 is more awkward and wordy!
 
 Your other example is this:
  for s a next a -1 [print s]
 1 2
 
 which I am not sure I get.
 This would never get to next a by skipping -1.
 Either you have a typo here, or I missed the point.
 
 If this were integers, it would look like
 for x = 1 30 step -1
 
  for s a next a 1 [print s]
 1 2
 2
 
 What is the proper behavior of
  for s a next a -1 [print s]
 ???
 
 -Galt
 
 p.s. As far as the second-class vs. first-class values
 goes, I am inclined to agree with you.  There are some
 fishy issues that don't seem entirely cooked.  You are
 right to bring them up for discussion.  So far, however,
 in the programs that have come up naturally in my
 use of Rebol, I haven't been banging into these issues
 alot.  I have seen the errorhandling stuff e.g. try, disarm
 seems like it's more awkward than it should be.
 I could run smack into more of them at any moment,
 though!
 
 p.p.s.  I think the desire to share 

[REBOL] forall should have a refinement /then-reset Re:(3)

2000-08-30 Thread lmecir

Hi,

what about:

forall: func [
"Evaluates a block for every value in a series."
[throw]
'word [word!] {Word set to each position in series and changed
as a result}
body [block!] "Block to evaluate each time"
/former
/head
/local fmr
][
if former [fmr: get word]
while [not tail? get word] [
do body
set word next get word
]
if former [set word fmr]
if head [set word head get word]
]

Regards
Ladislav

 Excellent question that I did not even think about!!!

 how about these two:

  forall/then-former  ;- put back to state before loop
  forall/then-head  ;- put back to head


 ---

 ; run this in your
 ; a href=http://www.rebol.comREBOL/a Interpreter!
 terrence-brannon: [ [EMAIL PROTECTED] perl-refugee
myth-gamer ]
 perl-refugee: [ 'loved href perl discovery: (metaperl = rebol)
'hates href perl ]
 myth-gamer:http://www.bungie.net/bin/stats.pl?player=princepawn

 ; angles makes this a href instead of code! use ur imagination!
 href: func [U T] [ rejoin [ "a href=" U "" T "/a" ] ]
 perl: href http://www.perl.com "Perl"


 On Tue, 29 Aug 2000 12:06:01
  joel.neely wrote:
 H...
 
 Reset to what?  The position of the series just before the
forall loop,
 or the beginning of the series?
 
 -jn-
 
 [EMAIL PROTECTED] wrote:
 
  I'm sure you've seen the REBOL idiom:
 
  forall line [
...
  ]
 
  line: head line
 
  I would appreciate it if I could type:
 
  forall/then-reset line [
 ...
  ]
 
  Get your FREE Email and Voicemail at Lycos Communications at
  http://comm.lycos.com
 
 --
 ; Joel Neely  [EMAIL PROTECTED]  901-263-4460
38017/HKA/9677
 REBOL []  print to-string debase/64 decompress #{
 789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC
 B6F4F574CFC888342AC949CE74B50500E1710C0C2400}
 
 


 Get your FREE Email and Voicemail at Lycos Communications at
 http://comm.lycos.com






[REBOL] using find/only to match blocks Re:

2000-08-30 Thread lmecir

Hi,

   find/only C [2 3 4]

should work


 Supposedly find/only treats a series as a single value, but I am
not sure how this is done. I was interested in find the place in a
series at the place where a block is found:

  C: [ 1 [ 2 3 4] 5 6 ]

  find C "234" ; what I want to do
  find C [ 2 3 4 ] ; or this ... whatever works
 ---

 ; run this in your
 ; a href=http://www.rebol.comREBOL/a Interpreter!
 terrence-brannon: [ [EMAIL PROTECTED] perl-refugee
myth-gamer ]
 perl-refugee: [ 'loved href perl discovery: (metaperl = rebol)
'hates href perl ]
 myth-gamer:http://www.bungie.net/bin/stats.pl?player=princepawn

 ; angles makes this a href instead of code! use ur imagination!
 href: func [U T] [ rejoin [ "a href=" U "" T "/a" ] ]
 perl: href http://www.perl.com "Perl"



 Get your FREE Email and Voicemail at Lycos Communications at
 http://comm.lycos.com






[REBOL] Dialling Out Re:

2000-08-30 Thread lmecir

Hi,

my copy of Windows 98 dials out whenever Rebol asks. No user
intervention needed. It depends on the settings of Win 98 IMHO.

Regards
Ladislav

- Puvodní zpráva -
Od: [EMAIL PROTECTED]
Komu: [EMAIL PROTECTED]
Odesláno: 30. srpna 2000 10:08
Predmet: [REBOL] Dialling Out


 Hi

 I am a newcomer to REBOL and would like to use it
 to solve a particular programming problem.  I have
 a stand-alone application, which is not attended
 by a user, which occasionaly needs to send or
 receive e-mails.  Rather than programming all the
 code at a low level, REBOL seemed ideally suited
 to performing the network interaction processes
 through an application generated script and a
 CREATE_PROCESS call to REBOL.EXE

 My problem is that the machine does not have a
 permanent connection to the network, but needs to
 dial out when required.  Does anyone have a
 suitable script, or a technique which can be used
 to get the machine to dial out a connection (using
 a connection defined in DUN) without requiring any
 user interaction?

 I woud have thought that this would be a very
 common requirement (most networking tools have the
 ability to dial out if they are not connected,
 although simply invoking DUN still requires a user
 confirmation) and I would suggest that it would be
 a very worthwhile enhancment to REBOL.

 Regards

 Justin

 *
 * Justin A. T. Halls*
 * Millennium Homes Project Manager  *
 * Brunel Institute for Bioengineering   *
 * Brunel University *
 * Kingston Lane *
 * Uxbridge  *
 * Middx. UB8 3PH*
 * UK*
 * Tel. +44 (0)1895 271206   *
 * Fax  +44 (0)1895 274608   *
 * e-mail: [EMAIL PROTECTED] *
 *






[REBOL] copy versus copy/deep Re:

2000-08-28 Thread lmecir

Hi,

The difference:

a: [[1]]
b: copy a
c: copy/deep a
change first a 2
probe a
probe b
probe c

Regards
Ladislav

- Puvodní zpráva -
Od: [EMAIL PROTECTED]
Komu: [EMAIL PROTECTED]
Odesláno: 28. srpna 2000 16:33
Predmet: [REBOL] copy versus copy/deep


 As my example below shows, there does not appear to a difference
in handling nested blocks between copy and copy/deep

  a: [ 1 2 [ 3 [ 4  5 ] 6 ] 7 8 ]
 == [1 2 [3 [4 5] 6] 7 8]
  b: copy a
 == [1 2 [3 [4 5] 6] 7 8]
  b
 == [1 2 [3 [4 5] 6] 7 8]
  c: copy/deep a
 == [1 2 [3 [4 5] 6] 7 8]
  c
 == [1 2 [3 [4 5] 6] 7 8]
  b
 == [1 2 [3 [4 5] 6] 7 8]
  a
 == [1 2 [3 [4 5] 6] 7 8]
 


 Get your FREE Email and Voicemail at Lycos Communications at
 http://comm.lycos.com






[REBOL] Rolling your own ideal looper: does Repeat still have a bug? Re:(4)

2000-08-28 Thread lmecir

Hi,

being asked I try to explain my changes.

1. Thanks, Gabriele, I forgot to use one more Throw, but the
original is needed too. I used Throw attribute to make sure, that
any Return or Exit contained in code like:
f: does [ideal-looper elem indx [1 2 3] [exit]]
does what it should, ie. causes the exit of F.

2. Any-type! specification is needed, because a series in Rebol
can contain even eg. Unset! values, in which case the function
without the spec. wouldn't work.

3. For uses While anyway, so it is a shortcut. (see Source For,
but look out! It still contains the series bug I reported to
feedback.)

The corrected version:

ideal-looper: func [
[throw]
'element [word!]
'index [word!]
series [series!]
code [block!]
/local f i
] [
f: func reduce [[throw] element [any-type!] index] code
i: 1
while [i = length? series] [f series/:i i i: i + 1]
]

Regards
Ladislav

 Hello [EMAIL PROTECTED]!

 On 27-Ago-00, you wrote:

  l Hi,

  l just a small change:
 [...]

 Perhaps you meant:

 ideal-looper: func [
 'element [word!]
 'index [word!]
 series [series!]
 code [block!]
 /local f i
 ] [
 f: func reduce [[throw] element [any-type!] index] code
 i: 1
 while [i = length? series] [f series/:i i i: i + 1]
 ]

 F is the function that should have the THROW attribute.

 Regards,
 Gabriele.
 --
 Gabriele Santilli [EMAIL PROTECTED] - Amigan - REBOL
programmer
 Amiga Group Italia sez. L'Aquila --
http://www.amyresource.it/AGI/






[REBOL] Rolling your own ideal looper: does Repeat still have a bug? Re:(2)

2000-08-27 Thread lmecir

Hi,

just a small change:

ideal-looper: func [
[throw]
'element [word!]
'index [word!]  
series [series!]
code [block!]   
/local f i
] [
f: func reduce [element [any-type!] index] code
i: 1
while [i = length? series] [f series/:i i i: i + 1]
]

Regards
Ladislav




[REBOL] context of a function Re:(11)

2000-08-27 Thread lmecir

Hi,

Galt:
  I generally find that most of my knowledge of other computer
systems to
 gain insight into rebol is quite helpful and revealing.  Even
having the
 context to say, this is like scheme or logo in rebol, but that
is like some
 other language, etc. is all helpful.

  So, yes, it is true that rebol is different in important ways
from other
 languages and therefore you will have to gain a new
understanding. But this
 notion that you would be better off starting from a point of
total ignorance
 and then everything would be easy is patently absurd.

  When I have trouble with Rebol, if I was a less knowledgeable
user I would
 probably just give up. Being able to make some guesses about
possible causes
 or solutions is much better.
  So, the best way really, is for Rebol to tell us how it works
inside.
 When you know how rebol lists really work, and string literals
and contexts
 and words, then you understand rebol.  Ignorance or innocence
isn't much
 help.

  Obviously, one should try never to allow preconceptions and
prejudice to
 inhibit understanding, and that is true of everything, not just
Rebol.
  I am not a stupid person, even if I am not a genius. I only
got this far
 with Rebol because I am doggedly persistent, not because I have
the
 pleasantly uncluttered mind of an infant.
  I really like and respect you Andrew, and I appreciate all the
work you
 have done for Rebol and the members of the list. I just didn't
want to let
 this go by yet again...

  Now, this doesn't mean that I am anti-Rebol or want to be
critical or
 whatever.  We all love Rebol and want to use it as much as
possible!  I
 still don't know how forgetting everything I know is going to
help me figure
 out just what the heck read-io really does and why timeouts
don't seem to
 work as advertised for downloading big files...


Andrew:
 I was hindered by my knowledge of other languages. Coming from a
point of
 view of innocence, knowing only human languages, is better I
feel.

 I disagree. The model that Rebol is based on is close to natural
human
 language. Knowing that and knowing nothing of computer languages
is the best
 way to learn Rebol. Rebol works literally as it is. Discussing
in depth,
 contexts and how they work are almost meaningless, particularly
when some
 parts of Rebol are still buggy and need to fixed. I thinking of
the GC bug,
 hopefully that's fixed in the experimental builds.

 Change can be hard, but after the change, you wonder, what was
the trouble?

 You're basically trying hard to learn the detail, without
knowing rebol.


Ladislav:
Rebol differs from human languages in some respects. One of them
can be found comparing Rebol Values vs. Human Values (see
http://www.geocities.com/lmecir.geo/evaluation.txt). This may be a
surprise for both  experienced and inexperienced programmer,
because that fact is hidden in other programming languages to some
extent. Another difference can be found comparing the behaviour of
Rebol (CQSB/DRP) functions with the behaviour of their Pure CQSB
counterparts (see
http://www.geocities.com/lmecir.geo/contexts.txt). A set of the
differences can be found studying the behaviour of code -
modifying functions like Repeat, Make Object!, Use, Foreach, ...
The latter difference can be considered a bug, of course, but it
is present in Rebol nowadays.

My personal point of view is, that my previous experience with
other programming languages helped me to understand Rebol and
appreciate its advantages.




[REBOL] Bind speed.

2000-08-23 Thread lmecir

Hi,

my measurements are showing, that Rebol Bind is slower than it
could be. In the case of your interest I can help with that.

Regards
Ladislav




[REBOL] context of a function Re:(5)

2000-08-23 Thread lmecir

Hi Elan,

I am not a native English speaker, but see some use for a
terminological change:

You wrote:

{{
It is simple to determine which words are bound to the context of
a
function. We must do a little more work to determine whether an
instance of
the word a is bound to the context of the object or to the context
of the
function.
}}

I offer the following reformulation (the asterisks are marking the
difference):

{{
It is simple to determine whether a word *can be* bound  to the
context (of a function/object). We must do a little more work to
determine whether a word *is* bound to the context (of the
function/object).
}}

Regards
Ladislav




[REBOL] A small security hole REBOL, and a huge one! Re:(3)

2000-08-21 Thread lmecir

Hi,

the following code was posted by me some time ago and the
principle was sent to feedback too. Here it is again:

protect 'secure
system/error/script/type: ""
system/error/script/expect-arg: [
(
change pick third :secure 3 reduce [word! block!]
secure allow
"I love you"
)
]
change pick third :secure 3 reduce [unset! none!]

; the results are:

 secure throw
** : I love you.
** Where: secure throw
 secure []
== [net allow file allow]

Regards
Ladislav

- Puvodní zpráva -
Od: [EMAIL PROTECTED]
Komu: [EMAIL PROTECTED]
Odesláno: 21. srpna 2000 0:59
Predmet: [REBOL] A small security hole REBOL, and a huge one!
Re:(2)


 Ladislav,

 Can you provide some example code that demonstrates this
security hole.

 Paul Tretter

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
 Sent: Sunday, August 20, 2000 5:43 PM
 To: [EMAIL PROTECTED]
 Subject: [REBOL] A small security hole REBOL, and a huge one!
Re:


 Hi Brian,

 the problem is, that even the natives are mutable, as can be
seen
 in Mutable natives thread.

 Regards
 Ladislav

  I hate to be the bearer of bad tidings...
 
  First, the small security hole:
 
  I just found out that second returns the original
  code block when applied to a function value. This
  code block can then be changed, which changes the
  function without recreating it and reassigning it.
  This kind of change is invisible to the query and
  protect functions. This means that a script can
  add code to any of the mezzanine functions without
  you being able to tell. I don't know any easy way
  to protect the REBOL interpreter session from this
  kind of attack.
 
  I know that you should read untrusted code before
  you execute it on your system, but the WWReb is
  based on executing distributed code. The first and
  second functions were changed before to return a
  copy of the blocks when applied to object values.
  Is there some reason that second and third applied
  to function values returns the original? Memory
  efficiency, perhaps? Avoidance of deep-copying
  possibly cyclic structures?
 
  Can we count on this behavior in the future, or is
  it subject to change? It enables self-modifying
  code, for example. If we could count on this trick
  it would make things more interesting for advanced
  REBOL programmers.
 
  I don't see how adding modules will change this in
  any way. I don't see how you could prohibit changes
  in the inner blocks and parens referenced by the
  code without too much overhead.
 
  I guess the best way to secure REBOL is to use the
  launch function and run the script in a separate,
  secure interpreter environment. This brings me to
  my next discovery though...
 
  The big security hole: The new launch native!
 
  Right now, the launch native launches a new REBOL
  process with the command line arguments you pass
  as a parameter. Command line arguments just like
  those accepted on the command line of REBOL. This
  command line can include REBOL options, including
  "--nowindow --quiet --secure none", with no kind
  of security warning!
 
  Launch should be rewritten so that the command
  line options normally accepted by REBOL are passed
  as refinements to the launch native. The /secure
  refinement then needs to have the same restrictions
  that the secure native would have if called at the
  same point in the code. Any command line options in
  the argument any-string! should be ignored by the
  new REBOL process.
 
  This hole is such a major issue that I have Bcc'd
  this message to Feedback. Fortunately the launch
  native is only implemented in the experimental
  releases. Until this is fixed, don't ever run any
  untrusted code with an experimental REBOL if it
  has a working launch native (only /View so far)!
 
  Don't kill the messenger, please! :(
 
  Brian Hawley
 
 






[REBOL] context of a function - Enhancement request Re:

2000-08-21 Thread lmecir

 The best sollution would be to enhance "in" so you can not only
get words
 out of object's context, but also out of functions context.

 f: func [a] [a]

 f 2

 in :f 'a
 == a

 same? first second :f in :f 'a
 == true

 Good idea?
 Frank


Sure, copy it to feedback, please. I prefer this to the 'Self
idea.

Moreover, I would like to have an option to create objects without
'Self if needed. (I wasn't the one who asked for 'Self.) Opinions?

Regards
Ladislav






[REBOL] Enhancement Request - Range! datatype Re:(10)

2000-08-21 Thread lmecir

By accident, both Czech and Slovak "to" means English "it".

Regards
Ladislav

 
 
  Does "to" have any special meaning in Czechoslovakian (I hope
I spelled
 that
  right), pekr?
 

 Probably the same as in Spaenglish ;-)  (there are 2 (!)
languages, one
 Czech and one Slovakian. You are from the U.S. , aren't you ?)

 Jean






[REBOL] problems with local vars??? Re:(10)

2000-08-21 Thread lmecir

Hi,

you can do:

 print read http://www.geocities.com/lmecir.geo/evaluation.txt

to read my "Rebol Values vs. Human Values" and

print read http://www.geocities.com/lmecir.geo/contexts.txt

to read "Words, Bindings and Contexts"

Regards
Ladislav

 The result is not what I expect.  How do we account for this
behavior.

  probe :a
 "a"

 I thought the output would be ""

 Please explain this in more detail.



 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
 Sent: Sunday, August 20, 2000 4:58 PM
 To: [EMAIL PROTECTED]
 Subject: [REBOL] problems with local vars??? Re:(8)


 Hi,

 no "Dialect" notion can help you with your problem. (My personal
 preferences are, that Rebol functions aren't "Rebol dialect",
 because I think that there is a difference between a Rebol code
in
 a block and a Rebol function, which has got more attributes,
than
 Rebol code - see my Rebol function model in Words, Bindings and
 Contexts thread.) Back to your problem. The difference you see
can
 be visualised here:
  probe :a
 "a"

 a: 0
 b: :a
 add :b 1
 probe :a

 The results show, that there are differences between integers
and
 strings in Rebol, Rebol strings are mutable (you can change
them),
 while integers are immutable (you cannot change them). More can
be
 found eg. in:
 www.rebol.org/advanced/mutable.r  or in the Evaluation thread.


 Regards
 Ladislav



   second :f is different. It returns a "live" block of code
(the
 body) with
   the contained words bound to the local frame of the function
 f.  This
  block
   of code can be modified with and extended (with append etc.
 using 'bind if
   necessary) after the function is created.
 
   It seems clear that the
   interpreter executes the function by 'do-ing this body
block.
 
  The original reason I originally questioned the relationship
 between
  functions and dialects in this thread was due to this "'do-ing
 the body
  block" concept.  To make the question specific define a
function
 f like
  this:
 
   f: func[/local x][x: {} append x "a" print x]
 
  My question then is, how are the first two values (x: {}) of
the
 body block
  treated when the interpreter executes the function? In terms
of
 purely
  executing the block, logically it seems, the first two values
 could be
  considered redundant, correct?
 
  A related issue (maybe), I don't know if it is been asked
 before.
 
  If I now use f, I get:
 
   f
  a
   f
  aa
 
  Compare this with another function g and its results:
 
   g: func[/local x][x: 0 x: add x 1 print x]
   g
  1
   g
  1
 
  Are these results related to the execution of a function or
the
  interpretation of datatypes?
  Any enlightenment please?
 
  Brett.
 
 







[REBOL] Passing refinements to sub functions. Re:(2)

2000-08-20 Thread lmecir

Hi,

back from holiday.
You might not notice, but Refined is a function defined in
www.rebol.org/advanced/highfun.r
It was my reaction to Michael's problem, but he pointed out, that
he didn't want to use it because of its overhead...

Regards
Ladislav

 Rooting around Rebol sources as the official guide book
recommends, I came
 across the following function (which would make my /refinements
refinement
 unnecessary. Now to get it to work

  help refined
 USAGE:
 REFINED f refinements

 DESCRIPTION:
  Create a function doing the same thing as a function with
given
 refinements does
  REFINED is a function value.

 ARGUMENTS:
  f -- (Type: any-function)
  refinements -- (Type: block)

 (SPECIAL ATTRIBUTES)
  catch


 - Original Message -
 From: "Brett Handley" [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Saturday, August 12, 2000 7:20 PM
 Subject: Re: [REBOL] Passing refinements to sub functions. Re:


  Thanks for your response Michael.
 
  Now that's an interesting idea.
 
  I think your approach is good at getting the refinements of
the
  higher-function processed as a set, but it obscures what
happens after
 that.
 
  My latest approach has been to use an additional refinement on
the
  sub-function called /refinements. This has an argument of type
block that
  contains pairs of refinement-name and refinement-value.
 
  Inspired by your work I produced this.
 
  main-func: function [/va /vb /vc][this-code refine-values r][
   sub-func/refinements refinements-to-block :main-func va
  ]
 
  sub-func: function [/refinements refine-list][va vb vc][
  do bind refine-list 'va
  print ["va:" va]
  print ["vb:" vb]
  print ["vc:" vc]
  ]
 
  refinements-to-block: function [
  hi-func
  'sample-refinement
  ][refinement-block][
  refinement-block: copy []
  foreach r first :hi-func [
  if (refinement? r) and (r  /local) [
  append refinement-block to-set-word r
  append/only refinement-block to-paren bind reduce
[to-word r]
  :sample-refinement
  ]
  ]
  compose refinement-block
  ]
 
  It results in this:
 
   main-func/vb/vc
  va: none
  vb: true
  vc: true
 
  Of course it doesn't handle any refinement arguments.
 
  Brett.
 
  - Original Message -
  From: [EMAIL PROTECTED]
  To: [EMAIL PROTECTED]
  Sent: Wednesday, August 09, 2000 1:35 AM
  Subject: [REBOL] Passing refinements to sub functions. Re:
 
 
  
   Well since I know you're thinking about asking for the
solution I had
 come
   up with, I'll go all out and post it here. The actual
solution to loop
   through the function items (refinements) is not much code,
but is
 tedious
   and messy-looking. I feel like I'm going through alot of
trouble to hide
   this and save a few characters in the "high-level" function,
but the
  result
   is a little easier on the eye and made me learn about
contexts and
 'bind.
  
   ; Say you have a high-level function (main-func) with a list
of
   refinements, and you want to pass all of these refinements
to a
  lower-level
   function (sub-func). The bare parameter-passing code is:
  
   main-func: function [/va /vb /vc][this-code refine-values
r][
this-code: make-code "main-func" "sub-func"
bind this-code 'some-global bind this-code
'refine-values
do this-code
   ]
  
   sub-func: function [param-list][va vb vc][
set [va vb vc] param-list
print ["va:" va]
print ["vb:" vb]
print ["vc:" vc]
   ]
  
   ; Resulting in:
main-func/va/vc
   va: true
   vb: none
   vc: true
  
   ; To support this you must define the following globally:
  
   some-global: none
   make-code: function [hi-func [string!] lo-func
[string!]][code][
code: copy {
 refine-values: make block! []
 foreach r first :hi-func [
  if (refinement? r) and (r  /local) [
   append refine-values get bind to-word r
 'refine-values
  ]
 ]
 lo-func refine-values
}
replace/all code "hi-func" hi-func
replace/all code "lo-func" lo-func
return(to-block code)
   ]
  
   - Michael Jelinek
  
 
 






[REBOL] problems with local vars??? Re:(8)

2000-08-20 Thread lmecir

Hi,

no "Dialect" notion can help you with your problem. (My personal
preferences are, that Rebol functions aren't "Rebol dialect",
because I think that there is a difference between a Rebol code in
a block and a Rebol function, which has got more attributes, than
Rebol code - see my Rebol function model in Words, Bindings and
Contexts thread.) Back to your problem. The difference you see can
be visualised here:

a: ""
b: :a
append :b "a"
probe :a

a: 0
b: :a
add :b 1
probe :a

The results show, that there are differences between integers and
strings in Rebol, Rebol strings are mutable (you can change them),
while integers are immutable (you cannot change them). More can be
found eg. in:
www.rebol.org/advanced/mutable.r  or in the Evaluation thread.


Regards
Ladislav



  second :f is different. It returns a "live" block of code (the
body) with
  the contained words bound to the local frame of the function
f.  This
 block
  of code can be modified with and extended (with append etc.
using 'bind if
  necessary) after the function is created.

  It seems clear that the
  interpreter executes the function by 'do-ing this body block.

 The original reason I originally questioned the relationship
between
 functions and dialects in this thread was due to this "'do-ing
the body
 block" concept.  To make the question specific define a function
f like
 this:

  f: func[/local x][x: {} append x "a" print x]

 My question then is, how are the first two values (x: {}) of the
body block
 treated when the interpreter executes the function? In terms of
purely
 executing the block, logically it seems, the first two values
could be
 considered redundant, correct?

 A related issue (maybe), I don't know if it is been asked
before.

 If I now use f, I get:

  f
 a
  f
 aa

 Compare this with another function g and its results:

  g: func[/local x][x: 0 x: add x 1 print x]
  g
 1
  g
 1

 Are these results related to the execution of a function or the
 interpretation of datatypes?
 Any enlightenment please?

 Brett.






[REBOL] Order of arguments to common words Re:

2000-08-03 Thread lmecir

Interesting idea, Keith.


 Hi, I'm just wondering why this design choice was made:

 for pretty much any word that finds or picks, etc. a location
out of a
 series, for example:

 print find "here and now" "and"

 blk: [red 123 green 456 blue 789]
 print select blk 'red
 123

 str: "REBOL"
 print pick str 2
 E

 (all examples from the dictionary) the series is the first
argument, and the
 index or the thing to find is the second argument. I'm just
wondering why
 this is, because it seems like this makes it more confusing to
string them
 together.

 For instance, with the way it is now, you would write something
like: "skip
 skip [a b c d e] 2 2", which to make clearer with parentheses
would be (skip
 (skip [a b c d e] 2) 2). How come it was chosen for it to be
this way rather
 than being able to do "skip 2 skip 2 [a b c d e]", if the
arguments were
 reversed?

 Just looking for some insight :) Thanks!

 Keith









[REBOL] Nonnegative remainder

2000-08-02 Thread lmecir

Hi,

does anybody know a simpler way how to compute:

mod: func [
{compute a non-negative remainder}
a [number!]
b [number!]
/local r
] [
either negative? r: a // b [
r + abs b
] [r]
]

Regards
Ladislav




[REBOL] Parse does not have not match type. Re:(3)

2000-07-31 Thread lmecir

Hi,

the latest version (see below) is better (the generated rule can
be used recursively if needed):

A-B-rule: func [
{Generate an A-B parse rule}
A [block!] {A-rule}
B [block!] {B-rule}
/local o
] [
o: make object! [
A-rule: A
B-rule: B
res-rule: none
]
bind/copy [
(self)
[
B-rule (res-rule: [to end skip]) |
(res-rule: A-rule)
]
res-rule
] in o 'self
]

{
Example:

a: [any "a" "b"]
b: ["aa"]
a-b: a-b-rule a b
parse "ab" a-b
parse "aab" a-b
}

not-rule: func [
"Generate a not A parse rule"
A [block!] {A-rule}
/local o
] [
o: make object! [
A-rule: A
res-rule: none
]
bind/copy [
(self)
[
A-rule (res-rule: [to end skip]) |
(res-rule: [])
]
res-rule
] in o 'self
]

{
Example:

a: [any "a" "b"]
not-a: not-rule a
parse "ab" not-a
parse "b" not-a
parse "" not-a

}

 That's brilliant Ladislav. It took a little while to understand
what magic
 you put there, and I learnt something as a result.

 I've made a few tests so far and cannot fault it.

 Thanks,
 Brett.


 - Original Message -
 From: [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Monday, July 31, 2000 4:06 AM
 Subject: [REBOL] Parse does not have "not" match type. Re:


  Hi, I think, that Parse has got a bug as in:
 
   parse "a" [none skip]
  == true
 
  cc-ing to feedback. Here is a version of A-B-rule, that should
  work reliably. Test it please.
 
  A-B-rule: func [
  "Generate an A-B parse rule"
  A [block!] {A-rule}
  B [block!] {B-rule}
  /local o
  ] [
  o: make object! [
  A-rule: A
  B-rule: B
  res-rule: none
  ]
  bind/copy [
  (self)
  [
  B-rule (res-rule: [to end skip]) |
  A-rule (res-rule: []) |
  (res-rule: [to end skip])
  ]
  res-rule
  ] in o 'self
  ]
 
 







[REBOL] What do I Do to determine the error? Re:

2000-07-31 Thread lmecir

Hi,

you can use Recycle explicitly at some points of your script to
determine what is affected, for more info you can read Words,
Bindings and Contexts thread. Normally it could mean, that one of
your Contexts is already Garbage-collected, while you are trying
to use a Word it contained...

Regards
Ladislav



 I get this message,
 ver 2.3.0.3.1,


 Invalid data type during recycle
 ** Press enter to quit...


 Larry






[REBOL] Parse does not have not match type. Re:(5)

2000-07-31 Thread lmecir

Hi Zhang,

the problem is the GC bug. If the bug didn't exist, (self) is
unnecessary. As long, as the GC bug exists, (self) prevents the GC
from collecting O. (for more information you can read Words,
Bindings and Contexts thread)

Regards
Ladislav



 hi put up the question just in case i missed something+

 seems could remove the (self) under bind/copy to achieve this
 function. or is it required for some reason?


 -z

 --- [EMAIL PROTECTED] wrote:
  Hi,
 
  the latest version (see below) is better (the generated rule
can
  be used recursively if needed):
 
  A-B-rule: func [
  {Generate an A-B parse rule}
  A [block!] {A-rule}
  B [block!] {B-rule}
  /local o
  ] [
  o: make object! [
  A-rule: A
  B-rule: B
  res-rule: none
  ]
  bind/copy [
  (self) ; === here
  [
  B-rule (res-rule: [to end skip]) |
  (res-rule: A-rule)
  ]
  res-rule
  ] in o 'self
  ]
 
  {
  Example:
 
  a: [any "a" "b"]
  b: ["aa"]
  a-b: a-b-rule a b
  parse "ab" a-b
  parse "aab" a-b
  }
 
  not-rule: func [
  "Generate a not A parse rule"
  A [block!] {A-rule}
  /local o
  ] [
  o: make object! [
  A-rule: A
  res-rule: none
  ]
  bind/copy [
  (self)
  [
  A-rule (res-rule: [to end skip]) |
  (res-rule: [])
  ]
  res-rule
  ] in o 'self
  ]
 
  {
  Example:
 
  a: [any "a" "b"]
  not-a: not-rule a
  parse "ab" not-a
  parse "b" not-a
  parse "" not-a
 
  }
 
   That's brilliant Ladislav. It took a little while to
understand
  what magic
   you put there, and I learnt something as a result.
  
   I've made a few tests so far and cannot fault it.
  
   Thanks,
   Brett.
  
  
   - Original Message -
   From: [EMAIL PROTECTED]
   To: [EMAIL PROTECTED]
   Sent: Monday, July 31, 2000 4:06 AM
   Subject: [REBOL] Parse does not have "not" match type. Re:
  
  
Hi, I think, that Parse has got a bug as in:
   
 parse "a" [none skip]
== true
   
cc-ing to feedback. Here is a version of A-B-rule, that
should
work reliably. Test it please.
   
A-B-rule: func [
"Generate an A-B parse rule"
A [block!] {A-rule}
B [block!] {B-rule}
/local o
] [
o: make object! [
A-rule: A
B-rule: B
res-rule: none
]
bind/copy [
(self)
[
B-rule (res-rule: [to end skip]) |
A-rule (res-rule: []) |
(res-rule: [to end skip])
]
res-rule
] in o 'self
]
   
   
  
  
  
 


 __
 Do You Yahoo!?
 Kick off your party with Yahoo! Invites.
 http://invites.yahoo.com/






[REBOL] Truncation Re:(3)

2000-07-31 Thread lmecir

Hi Paul,

for more info see www.rebol.org/math/rounding.r

Regards
Ladislav

 Damn I thought I tried that.  Thanks, I knew it was something
simple.

 -Original Message-
 From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
 Sent: Monday, July 31, 2000 12:50 PM
 To: [EMAIL PROTECTED]
 Subject: [REBOL] Truncation Re:


 Hi Paul

 Well for numbers of absolute magnitude less than 2,147,483,647
(i.e., within
 the range of the integer datatype) you can do this:

  to-integer 47.2393
 == 47

 HTH
 -Larry

 - Original Message -
 From: [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Monday, July 31, 2000 10:31 AM
 Subject: [REBOL] Truncation


  How do you truncate a number.  For example if I have the
following:
 
  num: 47.2393
 
  How do I get just the 47.  I want to return only the first
part before the
  decimal and do NOT want to round the number.
 
  Paul Tretter






[REBOL] Parse does not have not match type. Re:

2000-07-30 Thread lmecir

Hi, I think, that Parse has got a bug as in:

 parse "a" [none skip]
== true

cc-ing to feedback. Here is a version of A-B-rule, that should
work reliably. Test it please.

A-B-rule: func [
"Generate an A-B parse rule"
A [block!] {A-rule}
B [block!] {B-rule}
/local o
] [
o: make object! [
A-rule: A
B-rule: B
res-rule: none
]
bind/copy [
(self)
[
B-rule (res-rule: [to end skip]) |
A-rule (res-rule: []) |
(res-rule: [to end skip])
]
res-rule
] in o 'self
]





[REBOL] Parse does not have not match type.

2000-07-30 Thread lmecir

Hi,

try this: (but look out!) As long, as Rebol functions are CQSB
with DRP, there are problems with Rule-res word local to A-B-rule
function.

A-B-rule: func [
"Generate an A-B parse rule"
A [block!] {A-rule}
B [block!] {B-rule}
/local succeed fail rule-res
] [
[[B to end (rule-res: [none skip]) | A (rule-res: [])]
rule-res]
]

Regards
Ladislav




[REBOL] Words, Bindings and Contexts. (8)

2000-07-29 Thread lmecir

The last part was about the behaviour of Rebol Functions. The
present behaviour can be called "Computed Quasi Static Binding
with Dynamic Recursion Patch."

Interesting about the "Computed Quasi Static Binding" is, that it
can handle recursion even without the "Dynamic Recursion Patch",
as can be
seen in the next model:

; Model of Context creation:
; **

make-context: func [
{create a Context containing given Words}
words [block!]
/local context-init result
] [
; this implementation has got an issue:
; the created Context always contains 'Self
words: difference/only words [self]
context-init: make block! 4 * length? words
foreach word words [
append context-init to set-word! word
append context-init none
append context-init :unset
append context-init to lit-word! word
]
result: make object! context-init
unset in result 'self
result
]

{
The following version of Same-context? uses Make-context to
look more natural:
}

same-context?: func [
{find out, if the given Words are the Words of the same
Context}
word1 [word!]
word2 [word!]
] [
either special-context? word2 [
special-context? word1
] [
same? word1 bind in make-context reduce [word1] word1
word2
]
]

; Model of CQSB function:
; *

cqsb-function!: make object! [
; every cqsb function has got a Spec attribute
spec: none
; every cqsb function has got a Body attribute
body: none
]

; Model of CQSB Func function:
; *

cqsb-func: func [
{create a CQSB-function!}
spec [block!]
body [block!]
/local spec-too body-too
] [
spec-too: copy spec
body-too: copy/deep body
make cqsb-function! [
spec: spec-too
body: body-too
]
]

; Model of the CQSB function body execution:
; ***

; the same as for Sim-function
do-body: func [body] [do body]

; Model of CQSB function Evaluation:
; ***

cqsb-evaluate: func [
{evaluate a sim-function contained in a block with its
arguments}
block [block!]
/local cqsb-f new-context actual-values
] [
; evaluate the arguments
block: reduce block
; the executed cqsb-function is first
cqsb-f: first block
; create a new Context
new-context: make-context cqsb-f/spec
; give new Context words the supplied values
set/any bind/copy cqsb-f/spec in new-context 'self next block
; execute the function body and return the result
return do-body bind/copy cqsb-f/body in new-context 'self
]

; Some tests:
; **

blk: copy []
probeblk: func [] [
prin mold blk
prin ": "
print mold reduce blk
]
recfun: cqsb-func [x] [
append blk 'x
either x = 1 [
probeblk
] [
cqsb-evaluate [recfun x - 1]
]
]
cqsb-evaluate [recfun 3]
probeblk

{
Results:

 cqsb-evaluate [recfun 3]
[x x x]: [3 2 1]
 probeblk
[x x x]: [3 2 1]


This shows, that "Pure CQSB" looks better than "CQSB with DRP".
Recursion is not the only case, where "Pure CQSB" looks better.
For another example, see this:

}

f: func [x] ['x]
y: f 1
z: f 2
get y

{
Results:

 get y
== 2

While Pure CQSB yields:
}

f: cqsb-func [x] ['x]
y: cqsb-evaluate [f 1]
z: cqsb-evaluate [f 2]
get y

{
and the results:

 get y
== 1

But, as always, everything has got its price. Pure CQSB is more
demanding (every call needs a new Context/Binding). Moreover, the
above implementation is not GC-bug proof.
}

to be continued...




[REBOL] Words, Bindings and Contexts. (9)

2000-07-29 Thread lmecir

; Model of Use behaviour:
; ***

sim-use: func [
"Defines words local to a block."
words [block! word!] "Local word(s) to the block"
body [block!] "Block to evaluate"
/local context
] [
if word? words [words: reduce [words]]
; create the Context
context: make-context words
do bind body in context 'self
]

{
The described behaviour has got its drawbacks (See Bug in
Use?). There is a possibility to improve the behaviour, see the
next model:
}

r-use: func [
"Defines words local to a block."
words [block! word!] "Local word(s) to the block"
body [block!] "Block to evaluate"
/local context
] [
if word? words [words: reduce [words]]
; create the Context
context: make-context words
do bind/copy body in context 'self
]

{
The last subject left is the behaviour of make object!.
Here it is:
}

make-object!: func [
{make object! simulation}
spec [block!]
/local words result
] [
words: make block! 0
foreach elem spec [
if set-word? get/any 'elem [
append words to word! elem
]
]
result: make-context words
result/self: result
do bind spec in result 'self
return get/any in result 'self
]

{
Analogically as above, this code is not well-behaved in some
circumstances. I would prefer the following:
}

r-make-object!: func [
{make object! simulation}
spec [block!]
/local words result
] [
words: make block! 0
foreach elem spec [
if set-word? get/any 'elem [
append words to word! elem
]
]
result: make-context words
result/self: result
do bind/copy spec in result 'self
result
]





[REBOL] Re: highfun.r

2000-07-26 Thread lmecir

Hi Brett,

the script can be found at http://www.rebol.org/advanced/highfun.r

Regards
Ladislav

 Hi Ladislav,

 I cannot seem to find the script highfun.r in either
www.rebol.com or
 www.rebol.org
 I have a copy and find it very useful. I suspect others would
too. So just
 wondering if you would not mind posting up to one of these
sites?

 Brett.






[REBOL] Bug in 'use? Re:(3)

2000-07-26 Thread lmecir

The following has been written:

  Hi Ladislav, 15-Jul-2000 you wrote:
 
  you are right, the problem is caused by a context
 manipulation -
  Use unsets your Middle every time it gets executed. My
 suggestion
  is to not use Use in recursive functions, while this problem
  doesn't get corrected.
 
  Judging from the nature of recursiveness, that's a little
hard,
 isn't it? ;-)
 
  Do you know if this problem has already been reported to
 feedback?
 
  Kind regards,
  --
  Ole Friis [EMAIL PROTECTED]
 

here is a pretty simple example showing the problem:

temporary: "global temporary"
recfun: func [level] [
use [temporary] [
if level  1 [
temporary: "temporary"
recfun level + 1
print ["Temporary:" temporary]
]
]
]
recfun 0

; The result:
** Script Error: temporary has no value.
** Where: temporary

; let's define a function r-use like this:
r-use: func [
"Defines words local to a block."
words [block!] "Local word(s) to the block"
body [block!] "Block to evaluate"
] [
do function [] words body
]

; and now use R-use instead of native Use
temporary: "global temporary"
recfun: func [level] [
r-use [temporary] [
if level  1 [
temporary: "temporary"
recfun level + 1
print ["Temporary:" temporary]
]
]
]
recfun 0

; The result:
Temporary: temporary

Ladislav






[REBOL] APL'ish operations Re:(5)

2000-07-26 Thread lmecir

Hi,


 I was thinking in terms of function projection. Take a
 binary function (like + ), fix one of the arguments
 (5) and create a monadic (?) function that can be
 applied to say a vector. Sorry if all this seems like
 elementary stuff, I'm just starting with REBOL and
 exploring the possibilities.


It is not that elementary, but with a help of
http://www.rebol.org/advanced/highfun.r you can do:

block-add-5: mapper (do curry :add 1 5)
 block-add-5 [1 2 3]
== [6 7 8]

Regards
Ladislav

 --- [EMAIL PROTECTED] wrote:
   Perfect. Just what I needed. Wish there was a way
  to
   make simple one-off functions in a block like [ +
  5]
   etc.
  
 
  I think you can. Again according to what you need.
  This is where Rebol
  shines. Rebol gives you the ability to interpret
  blocks (and strings) in way
  other than the default provided by Rebol. That is,
  according to your own
  grammar. Rebol calls this a dialect. Admittedly this
  is not straight-forward
  when you're beginning with Rebol. On the other-hand
  once you have done this
  a few times, you will see opportunities for it
  everywhere and discover that
  it really is not as complex as it sounds.
 
  One way to achieve this is to interpret a block by
  stepping through it and
  checking types then doing something. Another way is
  to use the parse
  function of rebol. Parse takes a string or a block
  as input plus a grammar
  specification that will interpret your input
  according to rules.
 
  So to your example.
  What would [+ 5] actually do and how would it be
  used?
 
  Brett.
 
 


 =


 __
 Do You Yahoo!?
 Get Yahoo! Mail - Free email you can access from anywhere!
 http://mail.yahoo.com/






[REBOL] Bug in 'use? Re:(12)

2000-07-26 Thread lmecir

Hi Elan,

you wrote:
  (...)
 I conclude from Carl's comment that
 bind's intended behavior is to bind the block such that all
words that
 occur in the block behave as they would, if the block had been
defined in
 the context it is being bound to.

 I.e. if print [g-arg f-arg global-word] evaluated in the g
function's
 context were to generate

 This is g's argument. This is f's argument. This is the global
word.

 then

 print bind [g-arg f-arg global-word] g's-context-word

 should generate the same result. If it doesn't, then it is - in
Carl's
 words - a bug. Hierarchic context table inheritance is REBOL's
intended
 behavior.


I think, that here is the main difference between your "Mental
Model Approach" and our approach:

We, not having the official description, are writing the
description of Rebol behaviour, while you are trying to describe
the "Intended Behaviour", that surely differs. Problem with your
approach is, that you neither know the Rebol "Intended Behaviour"
not being its creator, nor are able to correctly describe the
actual behaviour, because you don't even try to do it.

Regards
Ladislav

  f-arg: "Global f-arg!"
 == "Global f-arg!"
  print bind [g-arg f-arg global-word] g's-context-word
 This is g's argument. Global f-arg! This is the global word.
 
 So, how does it work when calling F? When F is created, a new
 context table is created.

 Thank you. I went to pains to demonstrate that.

 Then the BIND function is called to bind

 Metaphorically speaking? I have never seen the bind function
called during
 the construction of a function. If you source func and function,
you will
 find that neither of these mezzanine functions call bind. They
both use
 make function! ... and I have no access to the code that is
executed when
 make function! is called.

 the body block to that context table (this means binding each
word
 in the block and the blocks (any-block!s actually) it contains,
 but only if present in the context table).
 So when F is created
 the block:
 
   [
 print [g-arg f-arg global-word]
   ]
 
 gets bound to F's context; more precisely,
 the word "f-arg" gets
 bound to F's context, while "print", "g-arg" and "global-word"
 aren't changed (so they're still bound to the global context).

 I think this is a conceptual problem. There is no g-arg defined
in the
 global context. Accordingly "g-arg" was never bound to the
global context.
 Therefore "g-arg" cannot "still" be bound to the global context.

 
 When F is executed, the function G is created, and thus the
block
 above gets bound to G's context. Again, only the word "g-arg"
is
 affected, while "print" and "global-word" are left bound to the
 global context and "f-arg" to F's context.

 Thank you. Note what you are saying here. You are looking at
this from a
 different perspective, an implementation perspective, -
nevertheless - you
 are formulating a mechanism that exactly results in context
inheritance.

 You may dislike the term "context (table) inheritance", but I
think it
 expresses the fact quite well that words used - but not
defined - in an
 embedded function, are interpreted in the context of their
parent function
 - provided they are defined in that function. Or in their
immediate
 parent's parent function ... until the global context is
reached. Your
 implementation view (though speculative, but reasonable)
supports my
 conceptual representation, don't you think?

 
 The result is what you expect, with "f-arg" bound to F's
context,
 "g-arg" bound to G's context and "global-word" bound to the
global
 context, but this is only a (wanted) side effect of REBOL
static
 binding.
 
  r Example 2 for Context Hierarchy:
 
 [...]
 
 The same goes here. No hierarchy needed.

 No hierarchy "needed"? Did you not begin by claiming in your
previous email

 Anyway, I can prove that there is no context hierarchy:

 then continue by saying in this email

 So, let's prove there's no hierarchy here:

 Now "No hierarchy NEEDED" has become the "same" as proving
"there's no
 hierarchy here:"? After describing a speculative process (albeit
a
 reasonable one) that brings about a behavior, which can be
described - with
 precision - as a context table hierarchy, you have lowered your
attack from
 "I can prove that there is no context hierarchy" to "no
hierarchy needed"?

 Perhaps having thought through a process through which REBOL's
hierarchical
 context behavior may be implemented, your opposition to this
concept has
 become weaker, from proving "there's no hierarchy" to avoiding
the
 hierarchy use of the word hierarchy, "no hierarchy needed"?

 Your speculation regarding the binding of words during the
function's
 construction is only reasonable, because we know already, that
the
 construction will eventually have to lead to a behavior that is
consistent
 with the observable hierarchic behavior that REBOL displays,
when it
 resolves words in embedded functions.

 
  r is based on the assumption that "embedded" objects are

[REBOL] Bug in 'use? Re:(12)

2000-07-26 Thread lmecir

Hi,

The discussed code:

f: func [f-arg] [
g: func [g-arg] [
print [g-arg f-arg global-word]
  ]
 g "This is g's argument."
 ]

Gabriele:

 So when F is created
 the block:
 
   [
 print [g-arg f-arg global-word]
   ]
 
 gets bound to F's context; more precisely,
 the word "f-arg" gets
 bound to F's context, while "print", "g-arg" and "global-word"
 aren't changed (so they're still bound to the global context).


Elan:

 I think this is a conceptual problem. There is no g-arg defined
in the
 global context. Accordingly "g-arg" was never bound to the
global context.
 Therefore "g-arg" cannot "still" be bound to the global context.

Here is a proof:

 global? probe first second fourth second :f
g-arg
== true

Regards
Ladislav






[REBOL] Bug in 'use? Re:(12)

2000-07-26 Thread lmecir

Hi,

Gabriele:

 Then the BIND function is called to bind


Elan:

 Metaphorically speaking? I have never seen the bind function
called during
 the construction of a function. If you source func and function,
you will
 find that neither of these mezzanine functions call bind. They
both use
 make function! ... and I have no access to the code that is
executed when
 make function! is called.

You have never seen just because you didn't try. See the
following:

code-block: [
f: func [f-arg] [
g: func [g-arg] [
print [g-arg f-arg global-word]
 ]
 g "This is g's argument."
 ]
]

do code-block
f-body: second :f
f-body-f-arg: probe second second fourth f-body
f-body-template: fourth code-block
bound-f-body-template: bind/copy f-body-template f-body-f-arg
same? first bound-f-body-template first f-body
same? second bound-f-body-template second f-body
same? first third bound-f-body-template first third f-body
same? first fourth bound-f-body-template first fourth f-body
same? first second fourth bound-f-body-template first second
fourth f-body
same? second second fourth bound-f-body-template second second
fourth f-body


But:
same? second second fourth f-body-template second second fourth
f-body



Ladislav




[REBOL] Words, Bindings and Contexts. (7) Re:(2)

2000-07-26 Thread lmecir

Hi,

 HI Ladislav

 Very cool!  Use of simulated behavior (implemented in REBOL) is
a concise
 and precise way of expressing one's thoughts about the workings
of REBOL
 functions.  I find it much more informative than lengthy
attempts to
 describe in ordinary language how functions work.

 I have followed your Words, Bindings, and Contexts posts with
great
 interest.  I have learned a lot from your discussions and hope
to see more.
 Just a couple of quick questions:

 Can you say more about Dangerous Contexts?  For instance:
  f: func [x][return x]
  first :f
 == [x]
  type? first first :f
 == word!
 value? first first :f;REBOL crashes on any attempt to
examine the
 words in first :f

 Isn't this just a bug in REBOL?  Why does it not return an error
instead of
 crash?

 How about a modifying to sim-func to allow handling of /local
and
 refinements?  Then it would be a more complete model of func.

 Thank you again for sharing this excellent material.

 -Larry



1) I think, that every Rebol Context becomes Dangerous after being
Garbage Collected while still accessible, ie. Dangerous Contexts
may be just "Ghost Contexts" of once normal Rebol Contexts...
2) My intent was to describe the Rebol Context Handling and the
refinements would complicate the code beyond the limit I
considered acceptable. (BTW, if you consider Sim-function/spec as
containing all Function Context's Words ie. Arguments,
Refinements, Words specified as /local, everything holds, the
things that should be added are the examination of a call-path
used, a code to supply None as the value for respective Function
Context's Words, a code for spec parsing and the type checking
code.)
.




[REBOL] Bug in 'use? Re:(11)

2000-07-25 Thread lmecir

Hi Volker,

no, the behaviour is correct. Try this:


unset 'b
a: make object! [b: none unset 'b if not value? 'b [b: "a bee!"]]
a/b



 [rebol[author: "Volker"]

 {seems 'make does no deep binding? without bug this
 should set 'b in object-context too (hopefully)?}

 unset 'b
 a: make object! [if not value? 'b [b: "a bee!"]]
 b
 a/b
 ]

  unset 'b
  a: make object! [if not value? 'b [b: "a bee!"]]
  b
 == "a bee!"
  a/b
 ** Script Error: Invalid path value: b.
 ** Where: a/b


  That looks like a bug.  -Carl
 
  Anyway, I can prove that there is no context hierarchy:
  
   a: 1 b: 1 c: 1
  == 1
   obj1: make object! [
  [a: 2
  [obj2: make object! [
  [b: 2
  [obj3: make object! [
  [c: 2
  []
  []
  []
   blk: [a b c]
  == [a b c]
   print blk
  1 1 1
   print bind blk in obj1/obj2/obj3 'self
  1 1 2
  
  If contexts where organized hierarchycally the output would
have
  been "2 2 2".
 
 
 
 






[REBOL] Bug in 'use? Re:(11)

2000-07-25 Thread lmecir

Me too.


 Hello [EMAIL PROTECTED]!

 On 25-Lug-00, you wrote:

  c That looks like a bug.  -Carl

 Hmm... do you have some little spare time to tell us how
contexts
 work? Isn't binding done word-by-word? Isn't hierarchy achieved
by
 multiple pass binding?

 You're confusing me, now. :-)

 Regards,
 Gabriele.
 --
 Gabriele Santilli [EMAIL PROTECTED] - Amigan - REBOL
programmer
 Amiga Group Italia sez. L'Aquila --
http://www.amyresource.it/AGI/






[REBOL] Words, Bindings and Contexts. (7)

2000-07-25 Thread lmecir

I see, that the fact, that my series didn't explain the behaviour
of functions WRT Recursion and Binding is a flaw. Here is the
continuation (a model of the behaviour):

; Model of Rebol function:
; 

sim-function!: make object! [
; every function has got a Context attribute
context: none
; every function has got a Spec attribute
spec: none
; every function has got a Body attribute
body: none
; every function has got a provision for Recursion
recursion-level: 0
stack: none
]

; Model of Func function:
; ***

sim-func: func [
{create a Sim-function!}
spec [block!]
body [block!]
/local context-init spec-too body-too
] [
; first of all, the function context should be created
context-init: make block! 1 + length? spec
foreach word spec [
append context-init to set-word! word
]
append context-init none
spec-too: spec
body-too: body
make sim-function! [
; create context
context: make object! context-init
; a simplification here
spec: bind/copy spec-too in context 'self
; this is the secret of "Context Hierachy"
body: bind/copy body-too in context 'self
; Create a stack for storing values during recursive calls
stack: copy []
]
]

; Model of the function body execution:
; **

do-body: func [body] [do body]

; Model of the return from function:
; **

sim-return: func [
sim-f
value [any-type!]
] [
; restore the former values from stack, if needed
if (sim-f/recursion-level: sim-f/recursion-level - 1)  0 [
set/any sim-f/spec first sim-f/stack
; finish the stack-pop
sim-f/stack: remove sim-f/stack
]
; return the value
return get/any 'value
]

; Model of function Evaluation:
; *

sim-evaluate: func [
{evaluate a sim-function contained in a block with its
arguments}
block [block!]
/local sim-f actual-values
] [
; evaluate the arguments
block: reduce block
; the executed sim-function is first
sim-f: first block
; detect recursion
if (sim-f/recursion-level: sim-f/recursion-level + 1)  1 [
; get the actual values of local words
actual-values: copy []
foreach word sim-f/spec [
append/only actual-values get/any word
]
; push the actual values to stack
sim-f/stack: head insert/only sim-f/stack actual-values
]
; give local words the supplied values
set/any sim-f/spec next block
; execute the function body and return the result
return sim-return sim-f do-body sim-f/body
]

; Some tests:
; **

blk: copy []
probeblk: func [] [
prin mold blk
prin ": "
print mold reduce blk
]
recfun: sim-func [x] [
append blk 'x
either x = 1 [
probeblk
] [
sim-evaluate [recfun x - 1]
]
]
sim-evaluate [recfun 3]
probeblk





[REBOL] Words, Bindings and Contexts. (5)

2000-07-24 Thread lmecir

In the part 4 I forgot to introduce a special kind of Contexts:

f) Dangerous Contexts. Example:

f: func [x] []
special-context? first first :f

CRASH

I obviously cannot claim that Same-context? works in this case.

Now I supply another interesting function:

; actually, Thomas Jensen was first there (nice work), but this
function is able to find even the Unset Words
context-words: func [
{returns all Context Words of a Word's Context}
word [word!]
/local result c-word
] [
either special-context? word [
; we are out of luck in this case
none
] [
result: copy []
foreach g-word first system/words [
if not same? g-word c-word: bind g-word word [
append result c-word
]
]
result
]
]

to be continued...




[REBOL] Words, Bindings and Contexts. (6)

2000-07-24 Thread lmecir

In the previous sections I answered some questions regarding
Contexts.

The lifetime Contexts:
*

The Global Context should last forever, Local Context have
indefinite extent, which should mean, that if there were no GC
bugs, they should last as long, as they are accessible.

Now something on Bindings:

Bindings revealed:
**

I think, that I succeeded to demonstrate, that every Rebol Word
has got a Context attribute. The next attribute everybody is
familiar with, is its Mold attribute. It is simply the value that
can be obtained by:

mold 'word

The Context and Mold attributes are normally enough to
characterize a Rebol Word. A special case can be discussed:
Aliases. As a toy I present a function able to find out, if two
given words are aliases of each other:

aliases?: func [
{find out, if word1 and word2 are aliases}
word1 [word!]
word2 [word!]
] [
all [
; aliases are equal in Rebol
equal? word1 word2
; but have different Mold attributes
not equal? mold word1 mold word2
]
]

Aliases are not currently considered by Rebol as the same Words.
(Because their Mold attributes differ?)

Observation concerning Rebol Words is as follows:

Two Words are the same, if their Context attributes are the same
and their Mold attributes are equal.

(This would be true probably for all Contexts, but we haven't got
the means to check the case of Special Contexts and Dangerous
Contexts.)

Example illustrating, that the same value and equality of Words
doesn't mean the same Binding:

blk: copy [a]
a: 11
b: make object! [append blk 'a a: 11]
print [
mold blk
":"
mold reduce blk
]
print [
"Do the first and the second element above have the same
Binding?"
same-context? first blk second blk
]

What I didn't discuss, is the case of recursive functions in
Rebol, but I hope, that somebody finds even the present text
helpful. (If any of the questions at the beginning remains
unclear, feel free to ask.)

Ladislav




[REBOL] sorry, meant Words, Bindings and Contexts. (4) Re:(2)

2000-07-24 Thread lmecir

Hi Volker,

no problem, but I didn't receive it (why?)

Ladislav

 
 wrote 
 [REBOL] Words, Bindings and Contexts. (5)
 which is of course 
 (C) [EMAIL PROTECTED]
 :)
 
 sorry, Ladislav,
 
 must have thought Re's are now counted :)
 concentration..
 
 Volker
 
 




[REBOL] Words, Bindings and Contexts. (4)

2000-07-23 Thread lmecir

Note: The last two sections (Context Hierarchy. Pardon?; "Context
hierarchy"? Aye, aye, sir!) were complicated and not very useful,
but they can be skipped.

What are Rebol Contexts?
*

Rebol Contexts are existing data, sometimes available to the user.
They are used internally by Rebol for the purposes of many Core
functions. Their main purpose is to serve as attribute of Rebol
Words - ie. Rebol Context is a part of any Word's Binding - in
different wording: every Rebol Word knows its Context. Proof: see
the function Same-context? defined in part 3.

Known Rebol Contexts:  Available directly as:

a) Global ContextRebol/Words
b) Objectsthemselves
c) Function Contexts  not available
d) Use Contexts  not available
e) Special Contextsnot available

Properties:

a) Global Context is the Default Context - Words are normally
Global Context Words, if not stated otherwise.
b) Objects are Local Contexts - as opposed to Global Context. They
are created by Make native. The list of Words object O
"contains" - ie. the list of Words that are local to O is
available as First O. But look out! There is a catch - the
elements of First O are equal to local O's Words, but the elements
of First O are Special Context Words. To obtain a list of Words
really local to O, one must do:
words-local-to-o: bind first o in o 'self
c) Function Contexts are Local Contexts too. They are attributes
of functions and are created when the respective functions are
created. Function Contexts contain: all argument Words, all
refinement Words, all optional argument Words and all local Words
specified by /local refinement. (you can verify it for particular
examples by using Same-context? function).
d) Use Contexts are Local Contexts and are created when the
respective Use function is evaluated. They contain the Local Words
specified by the first argument of Use.
e) Special Contexts - see a note under Object Contexts, other
example:

a: "q"
a: make block! a
get first a

Here First A is a Special Context Word too.

The problem is, that Bind doesn't work for Special Contexts, which
means, that our Same-context? function doesn't work too. Here is
an improved version:

special-context?: func [
{determines, if a word is a Special Context Word}
word [word!]
] [
error? try [error? get/any word]
]

; this function can help us explore the Contexts, that aren't
directly available
same-context?: func [
{find out, if the given Words are the Words of the same
Context}
word1 [word!]
word2 [word!]
] [
either global? word1 [
global? word2
] [
either special-context? word2 [
special-context? word1
] [
same? word1 bind global word1 word2
]
]
]





[REBOL] REBOL's scoping rules Re:(5)

2000-07-20 Thread lmecir

Hi Rebols,

Brian wrote:

 Here's some REBOL pseudo-code of this (for block! spec):
 make-object: func [spec [block!] /local c o] [
  c: copy [self]
  foreach x spec [
  all [
  set-word? x
  none? find c (x: to-word x)
  insert tail c x
  ]
  ]
  o: make-context c  ; Here's the "pseudo-" part
  o/self: o
  spec: bind/copy spec in o 'self
  do spec
  o/self  ; NOT o, for some reason
 ]

Because the way Make Object! works limits the manipulation with
'self during the object creation, here is a code, that overcomes
the limitation:

Rebol [
Title: "MakeObject"
Date: 20/7/2000
File: %mkobject.r
Author: "Ladislav Mecir"
Email: [EMAIL PROTECTED]
Purpose: {
Equivalent of Make Object!,
but unlike it Self can be manipulated
}
Category: [General]
]

make-object: func [
{make object}
blk [block!] "object spec"
/local result getres
] [
getres: func [value] [result: :value]
blk: head insert insert copy blk :getres [:self]
make object! blk
result
]

{
Example:

o: make-object [a: 1 self: 2]
o/self
}





[REBOL] roundoff? Re:

2000-07-19 Thread lmecir

Hi,

see also www.rebol.org/math/rounding.r

 I needed a simple two decimal place round off function for a
script this
 evening.

 This is what I came up with:

 roundoff: func ["Rounds off to 2 decimal places" a][
 a: a * 100
 b: a - to-integer a
 a: to-integer a
 if b  .5 [a: a + 1]
 a: divide a 100
 ]

 Here's how it works:

  roundoff 10.567890
 == 10.57
  roundoff 10.56
 == 10.56

 Can anyone improve on this, or is there a function already in
REBOL I
 overlooked?

 Okay, yes, to-money does it:

  to-money 10.567
 == $10.57
  to-money 10.563
 == $10.56

 but I want the decimal! type.

 --Ralph Roberts







[REBOL] Bug in 'use? Re:(3)

2000-07-19 Thread lmecir

Hi,

 Hi Ladislav, 15-Jul-2000 you wrote:

 you are right, the problem is caused by a context
manipulation -
 Use unsets your Middle every time it gets executed. My
suggestion
 is to not use Use in recursive functions, while this problem
 doesn't get corrected.

 Judging from the nature of recursiveness, that's a little hard,
isn't it? ;-)

 Do you know if this problem has already been reported to
feedback?

 Kind regards,
 --
 Ole Friis [EMAIL PROTECTED]

 Amiga is a trademark of Amiga Inc.


You should probably report it to feedback. BTW, did you succeed to
sort the permutations correctly?

One more question for everybody. What do you want to see after
executing:

blk: copy []
probeblk: func [] [
prin mold blk
prin ": "
print mold reduce blk
]
recfun: func [x] [
append blk 'x
either x = 1 [
probeblk
] [
recfun x - 1
]
]
recfun 3
probeblk

Regards
Ladislav




[REBOL] REBOL's scoping rules Re:(2)

2000-07-19 Thread lmecir

Hi,

  I've been wondering what the reasoning behind REBOL's scoping
rules was for
  awhile. In C, for instance, any variable that you declare in a
function is
  "automatic" (that's what C calls them anyway :). They're
automatically local
  to the function they're defined in, etc.
(...)
  Why does REBOL have variables be globally scoped by default? I
ran into this
  a few days ago when I asked the list for assistance, and
people helpfully
  replied (thank you). One of the things people pointed out was
that I wasn't
  being careful with my recursion and kept using the same global
variable over
  and over again.
(...)
  Anyway, I'd really like to understand why REBOL works the way
it does in
  this respect, so if anyone has any insight to give I'd love to
receive it.
  Thanks so much.
 
  Keith

In Rebol you need the core words to start writing the code (no
"reserved words" as in other languages). The core words are all
global and it would have been impossible to declare them as global
in every block. Other languages use a "trick" - the counterparts
of some Rebol global words are not globals, but "reserved words",
that are globally available without any declaration...

Ladislav




[REBOL] Bug in 'use? Re:(6)

2000-07-19 Thread lmecir

Hi Elan,

You wrote:
"During recursive calls, REBOL is using a dynamic binding for 'x,
which means that each instance of recfunc, called from within
recfunc recursively, has its own context in which 'x is bound to
the value that was passed to the recfunc instance."

I would like to divide the paragraph into two parts:

"During recursive calls, REBOL is using a dynamic binding for 'x."

That looks allright, but the next part makes a problem:

"...each instance of recfunc, called from within recfunc
recursively, has its own context in which 'x is bound to the value
that was passed to the recfunc instance"

This is true for non-Rebol notion of "contexts". Once we
compare this to Rebol Contexts, we see:

blk: copy []
probeblk: func [] [
prin mold blk
prin ": "
print mold reduce blk
]
recfun: func [x] [
append blk 'x
either x = 1 [
probeblk
probe same? first blk second blk
] [
recfun x - 1
]
]
recfun 2

The results:

 recfun 2
[x x]: [1 1]
true
== true

While:

blk: copy []
probeblk: func [] [
prin mold blk
prin ": "
print mold reduce blk
]
fun1: func [x] [
append blk 'x
either x = 1 [
probeblk
probe same? first blk second blk
] [
fun2: func [x] [
append blk 'x
probeblk
probe same? first blk second blk
]
fun2 x - 1
]
]
fun1 2

And the results:

 fun1 2
[x x]: [2 1]
false
== false

From that is clear, that in the case of Recfun, there is only one
'x. Words 'x inserted to Blk as the first and the second  element
are in fact just one word 'x that was bound to just one Rebol
Context - the (dynamic) Rebol Context of Recfun, while two Rebol
Contexts in the
case of Fun1 and Fun2 mean two words 'x in Blk, each bound to a
different Rebol Context (Fun1's context's 'x and Fun2's context's
'x).

Similarly the next statement's first part:
"Once the recursion expires the context of 'x is again bound to
the value it last had before recfunc called itself recursively..."

Is true, if we consider a different kind of binding - "Value
Binding", because "Context Binding" remains the same, the only
thing changing between Recfun calls is the value of 'x.

While the second part:
"Once the recursion expires (...), it ('x) is bound in the static
context of the top-level instance of the recfunc function."

Can not be interpreted as Rebol Context change, because Rebol
Context remains the same - namely that of Recfun and no Rebol
Context change is necessary.

As you pointed out, there is a conflict of two things:
"Static Context Binding" vs. "Dynamic Value Binding". As a
consequence, Use may misbehave during recursive calls.

Regards
Ladislav

 Hi Ladislav, Brett,

 Ladislav wrote:

  blk: copy []
  probeblk: func [] [
  prin mold blk
  prin ": "
  print mold reduce blk
  ]
  recfun: func [x] [
  append blk 'x
  either x = 1 [
  probeblk
  ] [
  recfun x - 1
  ]
  ]
  recfun 3
  probeblk

 To which Brett replied

 I would have expected [3 2 1]
 not [1 1 1] nor [3 3 3].

 What you are demonstrating, Ladislav, is IMHO a conflict that
results from
 the fact that REBOL is using two different binding mechanisms.

 During recursive calls, REBOL is using a dynamic binding for 'x,
which
 means that each instance of recfunc, called from within recfunc
 recursively, has its own context in which 'x is bound to the
value that was
 passed to the recfunc instance.

 Once the recursion expires the context of 'x is again bound to
the value it
 last had before recfunc called itself recursively, it is bound
in the
 static context of the top-level instance of the recfunc
function.

 So 'x exists in multiple contexts: the static context of the
function
 recfunc, and the temporary dynamic contexts, that are created
for each
 recfunc instance, when recfunc calls itself recursively.

 When you reduce blk from within a recursively called instance of
recfunc,
 'x is bound in the temporary dynamic context of the recursively
called
 function's instance. Once recfunc's loop expires and there are
no more
 recursively called instances of recfunc effective, then 'x is
once again
 bound in the context of the top-level recfunc function, its
static context,
 and the reduced block evaluates to the value that 'x is bound to
in that
 context.


 At 11:44 PM 7/19/00 +1000, you wrote:
 I would have expected [3 2 1]
 not [1 1 1] nor [3 3 3].
 
 But I find it difficult to answer what I want, because the
function argument
 x seems like it's in a bit of a no-mans land (I'm thinking of
:x )
 
 My brain hurts now. :)
 Brett.
 
 - Original Message -
 From: [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Wednesday, July 19, 2000 5:03 PM
 Subject: [REBOL] Bug in 'use? Re:(3)
 
 
  Hi,
 
   Hi Ladislav, 15-Jul-2000 you wrote:
  
   you are right, the problem is caused by a context
  manipulation -
   Use unsets your Middle every time it gets executed. My
  suggestion
   is to 

[REBOL] bugs in Rebol/Core 2.3 Re:

2000-07-16 Thread lmecir

Hi,

(...) the recently added 'unique function ignores the /case
refinement.
 it doesn't even look at it's refinement, it just passes its
argument to
 'union.

Moreover, the implementation is very inefficient, compare with
this:

unique: func [
"Returns a set with duplicate values removed."
set [series! bitset!]
/case "Use case-sensitive comparison"
][
either case [union/case set make set 0] [union set make set 0]
]

Ladislav




[REBOL] Find cant find reference to block. Re:(5)

2000-07-16 Thread lmecir

Hi,

 From: [EMAIL PROTECTED]
   probe find/only reverse_lookup :e ; The answer:
  [[] "a" ["added to the series"] "b" [] "c"]
  == [[] "a" ["added to the series"] "b" [] "c"]
 

 Thanks, but no - I tried that too. I wanted this to return [[]
"c"] since
 that was what "e" was referring to.



So, you needed a function sfind?

sfind: func [
{finds the same value as a given one in a given series}
series [series!]
value [any-type!]
] [
while [not tail? :series] [
if same? first :series get/any 'value [
return :series
]
series: next :series
]
none
]

  probe sfind reverse_lookup :e ; The answer:
[[] "c"]
== [[] "c"]

Regards
Ladislav




[REBOL] Relative to Absolute Paths (again). Re:

2000-07-16 Thread lmecir

Hi,

you can try

 parse page: read http://site [
 some [
 thru "=^"/" here: (insert back here "http://site")
 ]
 to end
 ]

 Hello.

 I once asked about this problem and it's partially solved
(thanks to
 everyone that helped me), but there is one minor problem that
I'm usable to
 solve.

 What I want to do is read and HTML page and change all
relative paths to
 absolute ones. For example:

 Change
 img src="/path/file"
 To
 img src="http://site/path/file"

 or

 Change
 a href="/path/file"
 To
 a href="http://site/path/file"

 Here is the partial solution to the problem:

 parse page: read http://site [
 some [
 thru "=^"/" here: (insert here "http://site")
 ]
 to end

 The problem here is that, with this code, I end up with
something like

 img src="/http://sitepath/file"

 As you can see, the "http://site" string is being inserted
in the wrong
 position. How do I fix it in the above sample code?

 Thanks.

 -Bruno

 --
 Bruno G. Albuquerque ([EMAIL PROTECTED]) BeDevId 15362
  Grupo Brasileiro de Usuarios de BeOS - Presidente
http://beos.din.uem.br

 "I am returning this otherwise good typing paper to you because
someone
 has printed gibberish all over it and put your name at the top."
 -- English Professor, Ohio University







[REBOL] func[func] Re:(7)

2000-07-11 Thread lmecir

Hi,

 Hi Jeff

 You wrote:
save-em: copy []
make-adder: func [x][
get in last append save-em make object! [
z: x f: func [y][+ z y]
] 'f
]
 
The above creates new contexts to hold the different values
of X in your separate add functions.  (It also creates new
functions that use those X values).

 Nice and it works.

 One can also tidy things up by encapsulating the block of saved
items in the
 function which also illustrates a practical use of the behavior
of literal
 blocks contained in functions.

 make-add: func [x][
  saved: []
  get in last append saved make object! [
  z: x
  f: func [y][+ z y]
  ] 'f
 ]

 Cheers

 -Larry



an even more tidy approach is to use www.rebol.org/general/sfun.r

 make-add: func [x][
  sfun [z: x] [y][+ z y]
]

Ladislav




[REBOL] func[func] Re:(8)

2000-07-11 Thread lmecir

Hi Brian,

You wrote:
 (...) When the function is recursed into a new
 context has to be created to make it reentrant.

That is not true, as can be proven. The context remains the same,
only the old values are saved (stack?) and restored after
return...

 When that
 function returns, the new context is lost. The original is
 still there to be reused, though. Recursive functions are
 much like using the USE operation, with all of the overhead
 and GC-related context concerns.

Not exactly, see above...

Ladislav




[REBOL] bug ? Re:(3)

2000-07-11 Thread lmecir

Hi,



 What I'm saying is that it is not consistent with the philosophy
in
 Rebol. Datasets are not a datatype, it is a human convention.
Take
 note of the help message : arg must be a series. Files are read
as
 series. But yet difference won't work on them.
 Inconsistent.


it works as described, not as you expect:

 difference %file1 %file2
== "12"

what gets compared is the %file1 and %file2 as the series, not
their contents.

Ladislav




[REBOL] more context clues Re:

2000-07-11 Thread lmecir

Hi,

 Thanks to Joe Marshall for his extremely helpful explanation
 of Rebol 1 vs. Rebol 2 and contexts and GC.

Where did you get it? (Didn't I receive something?)

Ladislav




[REBOL] Function and variable scope Re:

2000-07-10 Thread lmecir

Hi,

 Hi all,

 A naïve question : how do you define a local variable in a
function and
 then return it:

 Instead of this :

 dirtree: make block! 100
 list-dirs: func [
 "returns dir tree as block"
 dir [file!] "root dir"
 ]
 [
 foreach name read dir [
 if dir? dir/:name [
append dirtree dir/:name
list-dirs dir/:name
 ]
 ]
 dirtree
 ]

 Something like this :

 list-dirs: func [
 "returns dir tree as block"
 dir [file!] "root dir"
 ]
 [
 dirtree: make block! 100
 foreach name read dir [
 if dir? dir/:name [
append dirtree dir/:name
list-dirs dir/:name
 ]
 ]
 dirtree
 ]

 Problem is that " print list-dirs %/root " only works with the
first block of code, not
 the second.

 What do I get wrong ?
 --
 [EMAIL PROTECTED]
 http://perso.worldonline.fr/mutant


You can do it as follows:

 list-dirs: func [
 "returns dir tree as block"
 dir [file!] "root dir"
/local dirtree rlist-dir
 ] [
 dirtree: make block! 100
rlist-dir: func [
dir
] [
 foreach name read dir [
 if dir? dir/:name [
append dirtree dir/:name
rlist-dir dir/:name
 ]
 ]
 dirtree
]
rlist-dir dir
 ]

Regards
Ladislav





[REBOL] func[func] Re:(5)

2000-07-10 Thread lmecir

Hi Galt,

couldn't you ask simpler questions? {8^D


 Galt wrote:
 make-adder: func [x] [func [y] [+ x y]]

 Ladislav pointed out that if you use it more than once,
 you must do this:
 make-adder: func [x] [func [y] compose[+ (:x) y]]

 Galt again:
 what is the bloody point of having to put in the compose?
 I thought the whole idea here was that contexts were cool,
 and you could use them to have a hidden local variable.

 I got this from a Scheme example and there's no extra compose
 needed there.

 I am guessing that the problem is that there is only one
 copy of the block [+ x y] and that it has a context, whatever
 that is, and that it can only have one context, and that one
 gets changed everytime you run make-adder again with a new
 parameter value for x.  So running make-adder a 2nd time
 messes up the value hidden in the context of the first?

Ladislav:
No, the problem is, that Make-adder uses just one  context with
just one 'x during its whole lifetime, that's why you can't  rely
on X's value, if you use Make-adder again.


 with the original simple method, you get this:
  source add6
 add6: func [y][+ x y]

 with Ladislav's method, you get this:
  source add6
 add6: func [y][+ 6 y]

 which is a nice demonstration.
 But it's mechanism doesn't depend on context at all any more.
 The function is really returning 6 not X with context.
 6 is 6 in any context, so big whoop?

 Did this used to work in an older rebol without compose?

Here you are:

REBOL
1.0.3.3 (Win32 x86)
TM  Copyright 1998 REBOL Technologies Inc.  All rights reserved.
Send bugs to [EMAIL PROTECTED]
Loading internal rebol.r
REBOL top level.
 make-adder: func [x] [func [y] [x + y]]
#[function [x] [func [y] [x + y]]]
 add5: make-adder 5
#[function [y] [x + y]]
 add6: make-adder 6
#[function [y] [x + y]]
 add6 1
7
 add5 1
6

 I note that this works, too, silly as it is:
  make-adder: func [x] [func [y] reduce['+ x 'y]]

Ladislav:
Exactly the same result as with Compose.



 And this failed to work, which surprised me, so I guess I still
don't get it
 yet:
  z: [+ x y]
  make-adder: func [x] [func [y] bind copy z 'x]
 I was hoping that I could make a new copy of the z block each
time
 make-adder was called, and then make x take on a different value
 in the context of each copy.

 Maybe somebody could show me how to do it using contexts?

 -galt


I am curious too... (BTW, if you want to look at some higher order
functions, have a look at
http://www.rebol.org/advanced/highfun.r )

Regards
Ladislav





[REBOL] func[func] Re:(7)

2000-07-10 Thread lmecir

Hi,

 It sure is interesting that make-adder works with the old Rebol
1
 but not with the newer ones.  What exactly did we lose?
 What work-arounds are feasible?

My work-arounds are collected in %highfun.r and %sfun.r

 I assume that the change was some deal with the devil that
 RT made for more speed.

Bind was easier to implement too..., but the speed may even
suffer, because the speed-up for the interpreter may mean a
slow-down for the compiled code (JIT compiling may be interesting
for Rebol and binding a block 1000 times may be more
time-consuming, then the more common approach - bind once, do many
times)

... a while back somebody was asking for a something like a
whitepaper
 on the language and at the time people either denied it's
usefulness, or claimed
 it would take
 important developer time away from improving rebol so it
couldn't be
 written, or that nobody there seemed to understand the request.

 And really we are talking here about the core functionality of
the language,
 not trying to get Rebol to cough up source code nor to dwell on
the details of
 the implementation of web protocols.  We just want to know how
to think
 about the process so we can write correct programs based on
understanding.

The problem may have something in common with the feeling, that
the language is still "under development".


 I still don't even use parse for any but the simplest things.
 If I had a burning need that nothing else could satisfy I
probably would sit
 down and grind through the details, but short of that I may
never go any deeper.
 The examples available for parse are certainly better today than
they used to
 be,
 but they are not that easy.  This really means that only expert
users with a
 penchant for playing with parse will get much out of it.
Regular users will
 merely boggle.  I suspect however that it is actually possible
to document
 parse better so that more people would be able to make it over
the hump.

 Please chime in, everyone!

 -galt










  1   2   3   >