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

Confusion on when a block gets evaluated

 [1/10] from: massung::gmail::com at: 5-Mar-2006 23:38


I'm getting a tad bit confused on when REBOL decides to treat something as code. If I open up the console and type a couple snippets of code, the language doesn't quite work the way I expect it to (coming from Lisp). I'm hoping some of the more experienced here can lend me a quick explanation... :) Here I'll show my little test in REBOL along with a Lispy counterpart to show what I think should happen.
>> test: [ repeat i 9 [ prin i ] ]
== [ repeat i 9 [ prin i ] ] Okay, now I have a word (test), which is bound to a list of data consisting of words, an integer, and another list of words. Simple enough: (setf test '(repeat i 9 (prin i))).
>> do test
123456789 Looks good. It treated the list as a block of code and executed it. (eval test)
>> print test
123456789?unset? Huh? Shouldn't it have just printed the list like the original assignment return value? (print test) -> (repeat i 9 (prin i)) I know that I can get the original list by doing:
>> get 'test ; or :test
== [ repeat i 9 [ prin i ] ] But I just figured for the print statement, test would just be evaluated (after all, test is just a list, evaluating the list would be an extra step, which is what I assume is what DO does, but it seems that PRINT does it, too)? So, now assuming that maybe PRINT is a special case senario, I decided to try another simple function: JOIN. I get the same "quirkyness" (well, quirky being defined as "not what I expect :)"):
>> join "foo" test
123456789 == "foo?unset?"
>> join "foo" get 'test
123456789 == "foo?unset?"
>> join "foo" :test
123456789 == "foo?unset?"
>> join "foo" [test]
== "foorepeat i 10 prin i" I would have expected the first to do what the last did. So, for now, I gather that that words are evaluated (completely) before being passed on to another function. So, to test that theory, here's my next statement: foo: func [block] [ prin "**" do block print "**" ]
>> foo test
**123456789** If the my hypothesis was correct, what I would have expected as output would have been: 123456789**?unset?** So, now I'm utterly confused. :) Now, I'm sure there's just one tiny snippet of REB-know-how that I'm missing (or a trivial step in the evaluation process that I'm not aware of) at the moment that will make this all just "come together" for me. Consider me waiting to be enlightened. :) Thanks! Jeff M. -- massung-gmail.com

 [2/10] from: pwawood:gmai:l at: 6-Mar-2006 14:09


I'm sure some of the list gurus will have a fuller explanation but this may help: On Monday, Mar 6, 2006, at 13:38 Asia/Kuala_Lumpur, Jeff Massung wrote:
>>> print test > 123456789?unset? >> print mold test
[repeat i 9 [prin i]]
>> ? mold
USAGE: MOLD value /only /all /flat DESCRIPTION: Converts a value to a REBOL-readable string. MOLD is a native value. ARGUMENTS: value -- The value to mold (Type: any) Hope this gives you a start. Regards Peter

 [3/10] 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

 [4/10] from: pwawood:gmai:l at: 6-Mar-2006 14:26


Jeff Ladislav Mecir's excellent "essays" may help, particularly http://en.wikibooks.org/wiki/REBOL_Programming/Advanced/Interpreter You can access Ladislav's other work via http://www.fm.vslib.cz/~ladislav/rebol/ Regards Peter On Monday, Mar 6, 2006, at 13:38 Asia/Kuala_Lumpur, Jeff Massung wrote:

 [5/10] from: lmecir::mbox::vol::cz at: 6-Mar-2006 8:33


Gregg Irwin napsal(a):
>Hi Jeff, >First, you're jumping into deeper water that most newbies, so it's
<<quoted lines omitted: 26>>
>123456789** Script Error: mold is missing its value argument >** Near: print mold do test
or this: type? do test ; == unset!
>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 ;). >
LOL ... maybe a short explanation will suffice: reduce [1 + 2 3 + 4] ; == [3 7] form [1 + 2 3 + 4] ; == "1 + 2 3 + 4" form reduce [1 + 2 3 + 4] ; == "3 7" You should be aware of the fact, that Print reduces a block it obtains. You will find out, that there is a couple of functions in Rebol that reduce their block argument in addition to Print and Join. (e.g. Repend, c.f. source join) -L

 [6/10] from: massung::gmail at: 6-Mar-2006 9:13


Are these functions documented? I thank everyone for their replies. As per the ?unset?, that wasn't really bothering me, it was more a question of when 'test' was being evaluated (which is why I was using PRINT). I gather from the responses (especially this one) that certain functions just have an inherent "DO" inside them. That's fine as long as I know which ones they are. :-) Thanks again! Jeff M. -- massung-gmail.com On 3/6/06, Ladislav Mecir <lmecir-mbox.vol.cz> wrote:

 [7/10] from: tim-johnsons:web at: 6-Mar-2006 17:07


* Peter Wood <pwawood-gmail.com> [060305 21:34]:
> Jeff > > Ladislav Mecir's excellent "essays" may help, particularly > http://en.wikibooks.org/wiki/REBOL_Programming/Advanced/Interpreter > > You can access Ladislav's other work via > http://www.fm.vslib.cz/~ladislav/rebol/
You can also use the rebol word unset? which is a predicate that checks to see if a value is unset. example:
>> unset? print "yes"
yes == true This is useful when using a loop to accumulate values. You can use to first check to see something is unset before adding it to whatever you are using to accumulate the values. I generally use unset? inside of small functions, using it by itself, has caused me some heartburn in the past. example: =s: func [ "Check for unset or none values and return an empty string if found" v [any-type!] ][ either unset? get/any 'v [""] [any[v ""]] ] ;; end function In the interpreter window, enter
>> help unset?
;; and
>> help get
-- Tim Johnson <tim-johnsons-web.com> http://www.alaska-internet-solutions.com

 [8/10] from: pwawood:gma:il at: 7-Mar-2006 11:19


Jeff I find the Rebol function dictionary, http://www.rebol.com/docs/dictionary.html , the best source of documentation followed by the topic index at http://www.rebol.org/cgi-bin/cgiwrap/rebol/ml-topic-index.r. Regards Peter On Monday, Mar 6, 2006, at 23:13 Asia/Kuala_Lumpur, Jeff Massung wrote:

 [9/10] from: massung::gmail::com at: 6-Mar-2006 21:36


Thanks! I use the dictionary all the time, but didn't know about the topic index. Great! Jeff M. -- massung-gmail.com On 3/6/06, Peter Wood <pwawood-gmail.com> wrote:

 [10/10] from: robert::muench::robertmuench::de at: 7-Mar-2006 13:57


On Tue, 07 Mar 2006 04:19:56 +0100, Peter Wood <pwawood-gmail.com> wrote:
> the best source of documentation followed by the topic index at > http://www.rebol.org/cgi-bin/cgiwrap/rebol/ml-topic-index.r.
Hi, I must have missed something over the years but this is pretty cool. Thanks for pointing it out. -- Robert M. M=FCnch Mobile: +49 (177) 245 2802 http://www.robertmuench.de

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted