[REBOL] Re: Confusion on when a block gets evaluated
From: greggirwin:mindspring at: 5-Mar-2006 23:12
Hi Jeff,
First, you're jumping into deeper water that most newbies, so it's
expected that you'll hit some confusing twists and turns (wait until
you have a local series value in a function! :). It should all make
sense before long and, hopefully, whatever I do to confuse you further
will be addressed by somebody else. :)
>>> test: [ repeat i 9 [ prin i ] ]
JM> == [ repeat i 9 [ prin i ] ]
The main thing to note about this snippet is that REPEAT will return
the last value evaluated in the body block. In this case, that value
is a block containing the result of the PRIN function, which is an
unset! value.
>>> do test
JM> 123456789
Notice that there's no "==" since the result of DOing the block was
unset. Try REDUCE to see the result:
>> reduce test
123456789== [unset]
or try this:
>> print mold do test
123456789** Script Error: mold is missing its value argument
** Near: print mold do test
Now, you can see that DOing the test returns a single unset value,
which PRINT can't consume (it's not a real value...until Ladislav
jumps in to explain that it is, sort of, sometimes, but maybe it
shouldn't be, because it's confusing ;).
>>> print test
JM> 123456789?unset?
Now, you're telling PRINT to print the block *containing* the unset
value returned by evaluating 'test ([unset]). e.g.
>> print [prin '.]
.?unset?
PRINT evaluates on its own, so you don't have to take the extra step
of REDUCE-ing blocks you give to it.
Same issue for JOIN, but you also get into how values are coerced when
they are joined. The main thing is that JOIN is evaluating the block
too.
>>> join "foo" test
JM> 123456789 == "foo?unset?"
That's like this:
>> b: reduce [prin '.]
.== [unset]
>> join "foo" b
== "foo?unset?"
Here JOIN evaluates the block *containing* 'test, which produces a
block that is then coerced to a string, because that's what it is
being JOINed to.
>>> join "foo" [test]
JM> == "foorepeat i 10 prin i"
e.g.
>> form test
== "repeat i 9 prin i"
JM> foo: func [block] [
JM> prin "**" do block print "**"
JM> ]
>>> foo test
JM> **123456789**
JM> If the my hypothesis was correct, what I would have expected as output would
JM> have been:
JM> 123456789**?unset?**
The result of DO is being discarded. The first PRIN call consumes
**
(and nothing more), same for the last PRINT; DO BLOCK returns a
result that isn't used at all. PRINT and PRIN consume a single
argument, be it a block, string, or something else.
Does any of that make sense?
-- Gregg