Hi Joel,

hope you don't mind my butting in.

>
>    >> e
>    == [a b c]
>    >> print e
>    1 2 12
>    >> c
>    ** Script Error: c has no value.
>    ** Where: c
>    >> same? 'c third e
>    == false
>
>This WASN'T what I expected.  It appears that the third element of
>'e is a different 'c from the one whose name I can type into
>the console.

Unless you explictly modify the context (/local in a function, object
construction, use context or using bind) words entered at the console are
bound globally. That is REBOL's default behavior. Binding 'c to the
function's local context has not modified the status of 'c globally. 

When REBOL tries to resolve 'c globally it looks up 'c in the global
context. There is no 'c defined there. When REBOL tries to resolve the 'c
contained in the block 'e, it looks up c's value in the function's context,
because e's 'c has explicitly been bound to that f's private context. 


>    >> h: func [][bind e third e  print e]
>    >> h
>    20 21 12
>
>Hmmmm.  Within 'f (where we've bound 'c) the words 'a and 'b would
>have evaluated globally.  However, attempting to bind 'e back to
>that context doesn't restore 'a and 'b (in e!) to refer to the
>global 'a and 'b.

When you bind a block of words to a context, only those words are affected
that are private to that context. 'a and 'b are accessible from within 'f.
But they are not part of f's context. They are not private to f's context.

>
>
>    >> bind e 'f
>    == [a b c]
>    >> print e
>    ** Script Error: c has no value.
>    ** Where: c
>    >> a
>    == 1
>    >> print first e
>    a
>    >> print get first e
>    1
>    >>
>
>But 'f is defined in the global context for which 'a -> 1, 'b -> 2,
>and 'c is undefined.  So, although it seems clear why this last use
>of 'bind restored 'a and 'b (in 'e!) to their global binding, it's
>not immediately obvious to me why 'c (in 'e) got clobbered (when
>the 'bind in 'g didn't affect it).
>
>Any suggestions?

That's an easy one. A word or a block is bound to a context identified by a
sample word of that context. Here you bound 'e to the context identified by
the sample word global 'f. c is not defined in the global context. Ergo, 'c
was not bound. 

Recall that your function 'f includes code that explicitly performs the bind. 

If you want to bind e to the function's context without evaluating the
function 'f you must provide a sample word from f's context, which you
didn't do above. You provided the sample word 'f bound in the global context. 

Note that your function 'f does not provide a local word to bind to. The
only local word is c and c is never used as a word, only as a set-word! and
a lit-word!. If we modify f like this:

f: func [n /local c] [c: n c bind e 'c  print e]

adding the word c for no good reason before the bind instruction, then we
evaluate f 12 and we enter 'e again, (if we don't evaluate 'f, 'c has no
value to reference, if we do evaluate 'f 'e will already have been bound
within 'f), we can now say:

>> f 12
1 2 12
>> e: [a b c]
== [a b c]
>> bind e third second :f
== [a b c]
>> print e
1 2 12

third second :f retrieves the word c I added.

>
>> 
>> So, every word simply mantains a reference to a context (and
>> probably, for efficiency, directly to its value in that context
>> --- this could be proven in the previous version of REBOL),
>
>Fascinating!  Could you provide a code speciment that demonstrates?
>
>> and
>> all the functions that modify the binding of a word simply change
>> that reference.
>> 
>> This has allowed me to explain almost every case I encountered in
>> REBOL so far; I hope it can be useful. I don't know how much
>> accurate it is.
>> 
>
>I'm still puzzled about what appears to be evidence of TWO words
>named 'c above.  I'd be very interested in your thoughts on that.

TWO words named 'c? Did I miss something?

Hope this helps.

Elan

Reply via email to