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

2000-10-12 Thread joel . neely

[EMAIL PROTECTED] wrote:
> 
> [EMAIL PROTECTED] wrote:
> 
> > I had expected that the argument type check would barf on my little
> > pathological case, but it didn't!
> 
> It doesn't for the simple reason that:
> 
> >> type? :b
> == paren!
> >> probe :b
> (a: negate a)
> == (a: negate a)
> >> type? b
> == integer!
> >> probe b
> -1
> == -1
> 
> So you're actually passing an integer, not a paren, to IFS.
> 

Yes.  It finally sunk in...  ;-)

>
> > so you can imagine my surprise to obtain these results!
> [...]
> 
> You're still passing an integer, here. (You get "zero" because you
> have written IFS as:
> 
>ifs: func [[throw] cexp pblk zblk nblk /local cval] [ ...
> 
> notice PBLK ZBLK NBLK instead of PBLK NBLK ZBLK.)
> 
> > Well, it appears that   do   does NOT distribute over evaluation of its
> > argument!
> 
> It does, don't worry. :-)
> 

I'm delighted to stand corrected.  To quote someone from an earlier
post, "Silly me!"

>
> Anyway, let me partecipate with my own version:
> 
> >> sign: func [num [number!]] [either zero? num [0] [divide num abs num]]
> >> sign 2
> == 1
> >> sign -2
> == -1
> >> sign 0
> == 0
>

Nice!  Let me further suggest

signum: func [val [number! char! money! time!]] [
either zero? val [0] [either negative? val [-1] [1]]]

The change of name is suggested to reduce reading-aloud confusion
betweeen "sign" and "sine" -- from an old math textbook.

The replacement of your elegant division with more explicit logic
is to allow the domain to include all argument types accepted by
Positive? , Negative? , and Zero? .

>
> >> ifs: func [
> [[throw]
> [num [number!]
> [if-pos [block!]
> [if-zero [block!]
> [if-neg [block!]
> [] [
> [do get pick [if-neg if-zero if-pos] add 2 sign num
> []
>

An elegant solution to the multiple-evaluation problem!  My
compliments!

>
> >> ifs -2 ["positive"] ["zero"] ["negative"]
> == "negative"
> >> ifs 0 ["positive"] ["zero"] ["negative"]
> == "zero"
> >> ifs 2 ["positive"] ["zero"] ["negative"]
> == "positive"
> 
> Seems to work as expected. With B also:
> 
> >> ifs b ["positive"] ["zero"] ["negative"]
> == "positive"
> >> ifs b ["positive"] ["zero"] ["negative"]
> == "negative"
> >> ifs b ["positive"] ["zero"] ["negative"]
> == "positive"
> 
> Notice that:
> 
> >> ifs :b ["positive"] ["zero"] ["negative"]
> ** Script Error: ifs expected num argument of type: number.
> ** Where: ifs :b ["positive"] ["zero"] ["negative"]
> 

Inspired by your Ifs above, let me offer to remove the type
constraint...

ifs: func [
[throw]
num if-pos [block!] if-zero [block!] if-neg [block!]
][
do get pick [if-neg if-zero if-pos] add 2 signum num]

...provide another pathological B ...

>> a: 1   == 1
>> b: to-paren [a: a + 2 // 3 - 1]== (a: a + 2 // 3 - 1)
>> b  == -1
>> b  == 0
>> b  == 1
>> b  == -1
>> b  == 0
>> b  == 1

Which seems to work both with B and :B ...

>> ifs b ["pos"] ["zero"] ["neg"] == "neg"
>> ifs b ["pos"] ["zero"] ["neg"] == "zero"
>> ifs b ["pos"] ["zero"] ["neg"] == "pos"
>> ifs :b ["pos"] ["zero"] ["neg"]== "neg"
>> ifs :b ["pos"] ["zero"] ["neg"]== "zero"
>> ifs :b ["pos"] ["zero"] ["neg"]== "pos"

-jn-




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

2000-10-11 Thread joel . neely

Right, again, Ladislav!  ;-)

[EMAIL PROTECTED] wrote:
> 
> Hi Joel,
> 
> you wrote:
> 
> > 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
>

You're right... I should have thought more carefully about how the
type check would deal with the paren! value supplied.

However, I didn't follow the next comment at all.

>
> 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.
> 

In the case I supplied, the multiple evaluation DOES cause a bug (or
did I misunderstand you?) as can be seen in the results of "zero",
which occurred every other time.  That failure mode occurs when the
evaluation of   b   returns -1 during the   positive? condition   test
and then returns 1 during the subsequent   negative? condition   test,
thus failing both and falling through to the last alternative (which
presumably represents a zero argument value).  The supplied argument,
in fact, NEVER evaluates to zero; by alternating between positive and
negative one on subsequent re-evaluations, it can "fake out" any of
the earlier implementations of   ifs   (the ones that don't evaluate
it once, saving the result).


OBTW, I'm still very interested in whether you have any light to shed
on why the two versions of   ifs   below behave differently.

>
> >
> > 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"
> >

versus

> >
> > ifs: func [[throw] cexp pblk zblk nblk /local cval] [
> > do either positive? cval: cexp [pblk] [
> > either negative? cval [nblk] [zblk]
> > ]
> > ]
> >
> > >> ifs b ["positive"] ["negative"] ["zero"]
> > == "zero"
> > >> ifs b ["positive"] ["negative"] ["zero"]
> > == "positive"
> > >> ifs b ["positive"] ["negative"] ["zero"]
> > == "zero"
> > >> ifs b ["positive"] ["negative"] ["zero"]
> > == "positive"
> >
> > Well, it appears that   do   does NOT distribute over evaluation of its
> > argument!
> >

Thanks!

-jn-

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