Hi Ladislav,

At 04:01 AM 12/22/99 -0800, I wrote. And I should have been in bed fast
asleep. Sorry for taking up so much unnecessary bandwidth. My imagination
was running wild.

Two points I'd like to make:

in 1. I comment on the unlikelyhood of there being a "return context".

in 2. I provide a simple illustration for what I spent too much time on
earlier this morning.

1. I mentioned the "return context of reduce". I have no proof that there
is a return context. On the contrary, it appears much more likely that
there is no return context. The following code certainly demonstrates that
a word returned from a function is bound in the function's context and not
in some return context:

>> f: func [/local a] [ a: 4 return 'a ]
>> b: f
== a
>> get b
== 4

As expected. Now let us modify the value of a in the function's evaluation
block:

>> set first second :f 10
== 10

b's version of 'a is apparently bound the context of the function's body,
since it also returns the new value:

>> get b
== 10

2. After a few hours of sleep, I think I also came up with a much better
example to illustrate what I'm driving at with the literal string thing:

Assume the following function
>> f: func [] [ 
     insert "" "bcd" 
     insert make string! 0 "xyz" 
]

Before we evaluate 'f, let's see what the function's body contains:

>> token: second :f

;- You could use probe or mold here:

>> forall token [ 
     print [
       rejoin [mold first token ":"] 
       mold type? first token
     ] 
]
insert: word!
"": string!
"bcd": string!
insert: word!
make: word!
string!: word!
0: integer!
"xyz": string!

Now we evaluate 'f:

>> f
== ""

Let's see what the function's body contains after the evaluation:
>> token: second :f

;- You could use probe or mold here:

>> forall token [ 
     print [
       rejoin [mold first token ":"] 
       mold type? first token
     ] 
]
insert: word!
"bcd": string!
"bcd": string!
insert: word!
make: word!
string!: word!
0: integer!
"xyz": string!

a) The literal string retains its modification: it was "", has now become
"bcd". We expected that. 
b) Where did the string returned by make string! 0, into which we inserted
"xyz" go? 

I conclude from 2 that besides - as you pointed out - 'b being assigned to
a new string returned by copy each time your function was called, there is
another, underlying phenomenon. That phenomenon is documented in my 'f
function above: The return value of make string! (or copy ""), is not
retained from one function call to the next. In this respect the literal
string and the string returned by make string! "" are different. It was
this difference I had been commenting on.

The literal string continues to exist - and with it the modifications made
to it. The string returned by copy is not retained and the modifications
made to it disappear with it. 

What determines whether a value continues to exist or not? The extent of
its context. The literal string is created in the global context. The
string returned by copy is created in the context of the function body at
the time the expressions in the body are evaluated. 

My hypothesis is that as a result of being created during the time the
function's body is evaluated, its context is the function's evaluation
context. In saying that I'm assuming that a function has an evaluation
context. When the function ceases to be evaluated, its context ceases to be
valid and the string returned by copy is eventually garbage collected.

When I assign a word as a reference to the string returned by copy, I
extend that string's context. The extent of the set-word! b: is the
function body's context. When the string returned by copy becomes
referenced by 'b, the string's context is extended. That is why you can
retrieve the string returned by copy after the function body has been
evaluated, provided you reference it with a word:

>> f: func [/local b] [ b: copy "xyz" ]
>> f
== "xyz"
>> get first second :f
== "xyz"

Last I remember, the REBOL Tech crew commented on the extent of words local
to the body of a function saying that the persistence of their value
binding between function calls is not guaranteed.

Hope this helps,

Elan



Reply via email to