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.
Sunanda
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
Gregg
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.
Sunanda
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 :)
Gabriele
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.
Sunanda
Thanks Gabiele - glad to know it is at least technically possible (within limits)
Sunanda
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
Endo
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)]