Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

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

From: joel:neely:fedex at: 11-Oct-2000 12:42

Hello again, Ladislav, [lmecir--geocities--com] 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!!!!! 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 to do as 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 [joel--neely--fedex--com] 901-263-4460 38017/HKA/9677 REBOL [] print to-string debase decompress #{ 789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC B6F4F574CFC888342AC949CE74B50500E1710C0C24000000}