----- Original Message -----
From: Holger Kruse <[holger--rebol--com]>
Sent: Thursday, September 13, 2001 2:39 AM
Subject: [REBOL] Re: Context - code included- 2nd version
> On Wed, Sep 12, 2001 at 11:26:57PM +0200, Ladislav Mecir wrote:
> > The latest version of http://www.sweb.cz/LMecir/contexts.html reflects
> > points made in the latest discussions.
> Unfortunately your major misconceptions are still in there. The
> - Words do not "store" values,...
Would you like to change it to: "...words represent values...", "values are
represented by words..." [RCUG 2.3 p. 3-13], or something different?
> The properties of word! (and lit-word!,
> set-word!, get-word!) are, precisely, a reference to the context the
word is bound
> to (if any) and its spelling.
I like the notion of Spelling.
> - There is no "Special Context" and there are no "Special Words". What you
> a "Special Word" is in reality a word not bound into a context.
You are contradicting yourself above, aren't you? In the first sentence you
are telling that there are no "Special Words" and in the second one you are
telling, that you call them "words not bound into a context".
As to whether the "Special Context" exists: here you are making the same
mistake. Because you admit that the words ("words not bound into a context")
exist, the collection of such words exists too. The only point you can make
is, that the collection specified is not a context. But, that is again a big
trouble, because I found out, that every "word not bound to any context" is
actually bound to the Special Context (to translate it to your terminology:
has got a reference, that is the same as the reference that any other "word
not bound to any context" has).
> - Your distinction between local, global, special etc. words is a little
> confusing, mostly because "Loaded Word" is orthogonal to the other
> It refers to the existance of a word in the global context, whereas all
> other definitions refer to the binding of an individual word.
The notion of "Loaded Word" is indeed incoherent with the other notions I
used. It served well as an illustrative example of an incoherent notion,
which was its main use.
> Better, more consistent with the documentation (not to mention
> Replace "Special Word" with "word not bound into a context".
> Replace "Loaded Word" with "word which exists in the global context".
> Replace "Global Word" with "word bound into the global context".
> Replace "Local Word" with "word bound into a non-global context".
> These are the major problems with your document. A lot of the complexity
> of the individual observations you made seem interesting and significant
> your somewhat arbitrary definitions obscure the actual meaning. Once those
> are replaced by their meanings most observations follow logically and
This is a legitimate POV, of course. I am motivated by those, who don't
think that the "replacement of the terms" is enough to be able to understand
the rules of the game.
> - Aliases are not properties of contexts and therefore do not show up in
> visualizations of contexts. That's because aliases are global, not local
> per context.
This is an explanation of the phenomena, but I woudn't understand it without
seeing an illustrative Rebol code sample.
> - Scoping: REBOL uses lexical scoping, not dynamic scoping, but allows
> to be rebound during block evaluation. That's how words can refer to
> contexts even though their scope is lexical. "Scope hierarchies" imply
> kind of tree, which does not exist, so using that term is probably a bad
> Calling a scope hierarchy "virtual" is yet another definition which
> facts rather than illustrates them.
I don't like the notion of scope hierarchy too. The only problem with it is,
that there are some who are asking: "How come, that I see the scope
hierarchy and you are telling there is none?" I too wanted to tell them that
the scope hierarchy didn't exist in Rebol and the behaviour they were seeing
was just a result of a different mechanism, i.e. it was not the real thing,
it just looked so (a virtual thing).
> The facts are: words live inside of blocks.
I would add: not always. In Rebol it is possible to create words that don't
live inside of blocks
> When a block is created all words
> in it are either bound into a context, or remain unbound. Certain
> ('use etc.) change the binding of words. That is all there is to it, and
> "scope" of a word at any given time is simply determined by the last
> operation on it before the word gets evaluated.
This is correct but misleading, if you don't define the notion of "the last
bind operation" and what you mean by scope.
> - The "bug" you described when combining 'use with functions and other
> is not a bug. It is intentional.
I admit that it may be a bit unfair to call it a "bug".
> There are only four ways how a function can
> (theoretically) access its local variables and arguments, in any
> - Using a hidden context pointer. That's what C does, using the stack
> REBOL does not (and cannot) do it, because the only local environment
> has when executing a function body is that particular function body,
> a simple block, and the association from a function to its block is
> all references in REBOL). This means the function body has no hidden
> back to the function itself, and therefore cannot access its
> - By creating a completely new "environment" for each function. That
> a new argument and variable space (context) AND a new function body
> This way all words in the function body can be rebound into the new
> That's what your 'cfunc does, but it is unacceptable performance-wise.
Yes, the CFUNC-generated functions are performance-wise unacceptable for
some uses. The performance of CFUNC-generated functions might become more
satisfactory if it were implemented natively using a highly optimized
algorithm. OTOH, in that case the performance might be even better than the
performance of the functions generated by FUNC now.
> - By keeping a single function body for all function invocations, and
> rebinding it to a different context, one for each invocation, every
> function is called or returns. This generates O(n) complexity for each
> call, where n is the size of the function, i.e. performance is
> well for large functions, and it has other practical problems.
> - By keeping a single function body for all function invocations, bound
> same context, and changing the context on the fly (i.e. exchanging the
> "value" part of the name-value table for each function call, using a
> stack). This is what REBOL does. The "bug" you describe is a normal
> inevitable side effect of this, and not a "bug" at all. Your "fix"
> function execution model in a way that generates unacceptable
> If you really need the behavior you describe then you are, of course,
> write your own functions which implement it, as you have done, but for
> reasons that behavior should not be the default in REBOL.
> - The drawback you describe in regard to what you call the Dynamic
> is actually caused by the fact that the context of the outer function
> intact (indefinite extent) AND retains its values after the outer
> returns (for non-recursive function invocations), under certain
> This is an implementation detail you should not rely on, because it is
> change in future versions, i.e. there is a good chance that in the
> a (non-recursive) function invocation the values of that function's
> set to unset!. This would break the way your inner function references
> outer function's arguments after the outer function has returned.
That might be an improvement, because it may increase effectivity (garbage
collection) and safety, exactly as you are saying below. OTOH I know, that
there is a way how to implement Rebol, improve the performance and have the
closures as the default behaviour.
> The problem with function contexts keeping their values after the
> is that the referenced values do not get garbage-collected, even though
> reference exists any more, until the function is called again. In some
> (e.g. when trying to close and garbage-collect an unreferenced port)
this can be very
> Relying on the values of a function's context beyond the life time of
> function call should be considered illegal, i.e. you need to, e.g.,
'reduce the body of your
> inner function so the argument gets replaced by its value before the
function is returned.
> This also resolves the drawback you mentioned, i.e. use
> f: func [x] [func  reduce [x]]
> and the behavior is as expected and compatible with future versions.
> Holger Kruse