[REBOL] Series essay Re:(6)

1999-12-27 Thread joel . neely

[EMAIL PROTECTED] wrote:
> 
> On 12/27/1999 at 1:15 PM [EMAIL PROTECTED] wrote:{{
> It seems clear that context-juggling is implicitly performed via
> entry and exit to the bodies of functions and 'use, as in:
> >> a: "global a"
> == "global a"
> >> f: func [][print a]
> >> g: func [/local a][a: "g's local a"  print a  f  print a]
> >> h: func [][use [a][a: "h's local a" print a g print a]]
> >> h
> h's local a
> g's local a
> global a
> g's local a
> h's local a
> >>
> }}
> 
> So, how is this any different than something like (it's been a while):
> 
> var a: string;
> 
> procedure g;
> var a: string;
> begin a:= "g's local a"; write (a) end;
> 
> procedure h;
> var a: string;
> begin a:= "h's local a"; write (a); g; write (a) end;
> 
> begin a:="global a"; h end.
> 
> -Ted.

(It's been a while since I've dealt with Pascal, too!  However, I
 think I remember enough to understand your example.  ;-)

In terms of the behavior of this simple example, the results
(printed output) are similar.  The differences (actual behaviors
by which the outputs are produced) are huge.

In the standard implementation model, Pascal local variables are
allocated on the stack upon entry to a procedure, and deallocated
upon exit from the procedure.  There's no way to make a local
var from one procedure refer to the content of a local var from a
different procedure (except via pointers, and then one gets into
the danger of the "dangling reference" problem).  

OTOH, by using 'bind it IS possible to make the word/value
association that exists within one context available to another.
That's a very large difference, IMHO.

-jn-



[REBOL] Series essay Re:(6)

1999-12-28 Thread joel . neely

[EMAIL PROTECTED] wrote:
> 
> Hi, Joel,
> 
> although not been asked, trying to answer some questions.
> 
> 1) The model of binding Gabriele (not Gabrielle)

[sigh...]  It seems I am unable to type these days without making a
typo!  [My apollogies, Gabriele!]

>
> proposed was proposed as a
> hypothesis, that could explain the Rebol behaviour. Since then it has
> succeeded to explain every situation encountered and to make valid
> predictions, so it's validity is much less questionable than validity of any
> other binding model proposed.
>  

Gabriele's email to which I was responding certainly expressed some
ideas that were helpful to me.  My questions were intended to help me
understand it better.  I appreciate your assistance in that regard.

So, let me do a sanity check by attempting to answer the questions I
raised, based on my understanding of what you and Gabriele have said.

> > You've persuaded me that one part of that concept does NOT apply to
> > REBOL -- that of searching a chain of environments...

There is no "chain of environments".  Each word directly refers to its
own context.

> > >> e
> > == [a b c]
> > >> print e
> > 1 2 12
> > >> c
> > ** Script Error: c has no value.
> > ** Where: c
> > >> same? 'c third e
> > == false

The 'c at the third element of 'e ['s value] had been bound to the
local context of a function (value of 'f), and was therefore a
different word from a global 'c (although spelled the same).

> > >> h: func [][bind e third e  print e]
> > >> h
> > 20 21 12
> >
> > H.  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.

Precisely because global 'a and 'b aren't in the context to which the
third element of 'e ['s value] is bound, and therefore aren't changed
by the 'bind within 'h ['s value].

> > >> 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

The last one is the only one I'm still trying to understand.  Running
the following (in a fresh REBOL console) highlights my question.

>> a: 1
== 1
>> b: 2
== 2
>> e: [a b c]
== [a b c]
>> print e
** Script Error: c has no value.
** Where: c
>> f: func [n /local c][c: n  bind e 'c  print e]
>> f
** Script Error: f is missing its n argument.
** Where: f
>> f 99
1 2 99
>> print e
1 2 99
>> bind e 'e
== [a b c]
>> print e
** Script Error: c has no value.
** Where: c

What I think you've said is that the bind in f affects only the
third element of e because the other elements refer to words not
in the context used for the bind.  c is bound, but a and b are
left alone.

OTOH, the last bind above affects all of a, b, and c, because it
the target context is the global context.  Therefore, a and b
get bound back to a context where they already have values, but
c gets bound to a context where it does NOT have a value.

Did I interpret your description correctly?

Thanks for your feedback (and patience) !

-jn-



[REBOL] Series essay Re:(6)

1999-12-28 Thread news . ted

{{
Actually, nothing happens when entering or exiting the functions.
The binding is done when they are created. That is, make function!
creates a new context based on the spec, and then binds the body
block to that context.
}}

Which also neatly explains why local values are persistent. They are
(apparently) intialized to none when the block is made, and continue
through the session. It's only our prior knowledge of other languages
that lead us think locals might wax and wane whenever a function is
evaluated. 

{{
Because 'c actually exists in the global context, and its value is
unset!. Look:
>> c
** Script Error: c has no value.
** Where: c
>> type? get/any 'c
== unset!
}}

Since this works as the first statement in a new session, I guess that,
theoretically, this would mean all words exist, but are initially
'unset.

-Ted.





[REBOL] Series essay Re:(6)

1999-12-28 Thread 70740 . 503

Gabriele,

I think, using your example, that I have found a bug in REBOL.
>> block: copy [] repeat i 4 [use [x] [x: i * i append block 'x]]
== [x x x x]
>> do x/1
== 1
>> do x/2
== 4
>> x/1 = x/2
== true
>> x/1 == x/2
== true
>>
What do you think? Is it a bug?

Jerry