Nice work as always Bo. "Nesting Functions" led me to think the section was about nested function defintions, not calls in a call chain using returned expressions.
Thanks for the feedback! What chapter should I write next? Or does anyone have a topic they've already covered that they'd like me to add?
Values and datatypes.
I would like to know step by step what happen during words and block evaluation and how rebol inner strucuture works.
Good timing! I just posted thoughts about that in the #Red group. Wait for feedback before assuming what I wrote is correct though. And it is only a first step. The details of evaluation can be tricky (think of things like inline set-words, and how much evaluation is applied to different types). Even "how much" is not a clear description, but rather how each type is evaluated, and the control you have over it.
Another question: If I define some words inside to body of a FUNC or a FUNCTION, are they available outside the fuction itself ?
If did not provide the local words then yes, they will be available outside of the current function scope. See the SOURCE of FUNCTION.
Good points about evaluation. Knowing what happens could have a direct effect on programming. For example, when I pull things out of a database with SQL, and I want to set a word to refer to, say, the first item in the block of columns that is the result of the SQL, I find myself doing something like "DISPLAY-ITEM: to-string to-integer copy SQL-RESULT/1" or something like that, details not important. The important point is that I am doing copying and converting only beause I want to be absolutely sure I get the result I want, and some of that probably is not necessary because it already is done as part of the word evaluation. I just don't know. I suppose that is an implicit admission that I am too lazy to do a little experimenting to find out. I do like my ruts.
Any clever ideas on how to push past a error in DO/NEXT? do/next [1 / 0 2 + 2] 'var I'd be very happy if I could get [2 + 2} into 'var
I was going to suggest something like:
b: [1 / 0 2 + 2] while [not tail? b] [ if error? try [set [res b] do/next b] [b: next b] ]
But that's too simplisitic. In your example, it will skip the first 1, then / will act as a prefix func and consume the rest of the block.
Which brings up a good question, related to the other "How is DO special" chat. Can you safely push past an error? Probably not.
Thanks Gregg -- I tried various things, but none of them work very reliably in all conditions - like pushing correctly past, say [divide 9 + 4 / 0 2 + 2] It seems likely that DO knows exactly which args were consumed, and so could return the block with those skipped past. If only we could make it talk :)
DO could, but, not in all cases, or rather, not correctly in all cases. But, yeah, you'd need a new refinement that returns the error instead of causing it.
Thanks Gabiele - glad to know it is at least technically possible (within limits)
This there anyy clever, quick, way to turn these two blocks into a single object? names: [field1 field2 field3] values: ["a" "b" "C"]
I've already done it the long way around: blk: copy  for nn 1 length? names 1 [append blk reduce [to-set-word names/:nn values/:nn]] probe make object! blk
I wrote a build-object function does that, not more quicker/clever though
build-object: funct [names values] [ o: copy  parse compose names [some [set name [word! | set-word!] (append o to-set-word name) | skip]] set/pad words-of o: context append o none compose values o ]
probe build-object names values
== make object! [ field1: "a" field2: "b" field3: "C" ]
My more general version is a bit longer, but works without values, word! or set-word!s:
build-object: func [ "Builds an object from a block" names [block!] "Words or word/value pairs" /values val [block!] "Initial values" /local o name value ][ o: copy  o: either values [ parse compose names [some [set name [word! | set-word!] (append o to-set-word name) | skip]] set/pad reflect o: context append o none 'words compose val o ] [ if any [ parse compose names [some [set name [word! | set-word!] (append o reduce [to-set-word name none])]] parse compose names [some [set name [word! | set-word!] set value any-type! (append o reduce [to-set-word name :value])]] ] [context o] ] o ]
build-object [a b c] build-object [a 1 b "2"] build-object [a: 1 b 2] build-object [a: 1 b 'c] build-object/values [a: b] [c 1] x: 1 build-object/values [a: b] [c (x)]