Hi Don,

I think this is easier to understand if we keep in mind the difference
between two distinct any-word! datatypes: word! and lit-word!.

s: "some string"
>> type? probe first [s]
s
== word!
>> type? probe first ['s]
's
== lit-word!

Notice that PROBE is really handy here - it prints out the best
representation of the value possible, and passes its argument unchanged.
When PROBE sees a string, what it prints out looks like a string:

>> type? probe first ["s"]
"s"
== string!

So if PROBE shows us the ' it's a lit-word!, and if it just shows us letters,
it's a word! . Now REDUCE doesn't do anything to either:

>> type? probe reduce first [s]
s
== word!
>> type? probe reduce first ['s]
's
== lit-word!

Here FIRST extracted the value from the block unchanged, and passed that
value on to REDUCE, which passes it on unchanged, and PROBE shows us that it
really is unchanged. (Now you have to be careful with NONE, TRUE, FALSE and
datatypes, because PROBE can't show you the difference between the words that
represent those types, and the values they represent - but we'll ignore that
problem here.)

In fact, REDUCE only affects blocks.

>> reduce ['s]
== [s]
>> reduce [s]
== ["some text"]

So, to reiterate, although it looks like REDUCE is returning a different
value here:

>> reduce probe 's
s
== s

it isn't. All REDUCE ever saw was a word!, and that's what it gives back. The
same goes for PRINT:

>> print probe 's
s
s


You can describe what REDUCE does to a block as follows: (This is just a
model, not necessarily what it really does!)

1. makes an empty block
2. evaluates each complete expression in the argument block
3. appends each return value in turn to the new block

[example deleted for clarity!]


So let's see how this explains your original problem:

>   s: "some text"    ===>    'some text"
>   reduce 's           ===>     s                  ;  (first s )
>   print (reduce 's) ===>     s                ;  (second s)
>   reduce ['s]        ===>    [s]                 ;  (third s )
>
> These 3 s symbols look the same on the console but are all different.
> So, though  (reduce 's) appears to give s,  it is not the same s
>  which the console will use if we enter:   print s  ===> some text
>   or   do reduce ['s]  ===>  "some text"

First, the symbols    's    and    s   are different - the first is a
lit-word! that evaluates to a word!, the second is a word! that evaluates to
whatever value it refers to.

The   s    you get from     reduce 's   represents just the word! that   's
evaluated to automatically - the intervening REDUCE is irrelevant.

The   s    you get from     print (reduce 's)    is how PRINT represents the
word!   s    that gets returned from    (reduce 's) .  Note that PRINT has no
usable return value - it just displays characters on your console, and PRINT
would have done just the same with the string "s".

Finally, the  [s]  you get from   reduce ['s]   is the result of the
evaluation of the  's    within the argument block of REDUCE.


As you noted, repeated use of REDUCE on a block can progressively evaluate
the values in the block, and PRINT does one more REDUCE before it shows you
its representation of the block.

How about this:

>> reduce [to-word "to-lit-word" to-string 's]
== [to-lit-word "s"]
>> reduce reduce [to-word "to-lit-word" to-string 's]
== ['s]
>> reduce reduce reduce [to-word "to-lit-word" to-string 's]
== [s]
>> reduce reduce reduce reduce [to-word "to-lit-word" to-string 's]
== ["some string"]


Hope this helps,

Eric

Reply via email to