Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Context - code included- 2nd version

From: lmecir:mbox:vol:cz at: 13-Sep-2001 22:29

Hi all, ----- Original Message ----- From: Holger Kruse <[holger--rebol--com]> To: <[rebol-list--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
some
> > points made in the latest discussions. > > Unfortunately your major misconceptions are still in there. The
highlights:
> - 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? ...snip...
> 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. ...snip...
> - There is no "Special Context" and there are no "Special Words". What you
call
> 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
definitions.
> It refers to the existance of a word in the global context, whereas all
the
> 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
implementation):
> 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
and many
> of the individual observations you made seem interesting and significant
only because
> your somewhat arbitrary definitions obscure the actual meaning. Once those
terms
> are replaced by their meanings most observations follow logically and
become
> redundant.
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. ...snip...
> - 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
words
> to be rebound during block evaluation. That's how words can refer to
different
> contexts even though their scope is lexical. "Scope hierarchies" imply
some
> kind of tree, which does not exist, so using that term is probably a bad
idea.
> Calling a scope hierarchy "virtual" is yet another definition which
obscures
> 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
functions
> ('use etc.) change the binding of words. That is all there is to it, and
the
> "scope" of a word at any given time is simply determined by the last
bind
> 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
contexts
> 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
language:
> - Using a hidden context pointer. That's what C does, using the stack
pointer.
> REBOL does not (and cannot) do it, because the only local environment
REBOL
> has when executing a function body is that particular function body,
which is
> a simple block, and the association from a function to its block is
one-way (like
> all references in REBOL). This means the function body has no hidden
reference
> back to the function itself, and therefore cannot access its
arguments.
> - By creating a completely new "environment" for each function. That
includes
> a new argument and variable space (context) AND a new function body
(deep-copied).
> This way all words in the function body can be rebound into the new
context.
> 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
dynamically
> rebinding it to a different context, one for each invocation, every
time a
> function is called or returns. This generates O(n) complexity for each
function
> call, where n is the size of the function, i.e. performance is
prohibitive as
> well for large functions, and it has other practical problems. > > - By keeping a single function body for all function invocations, bound
to the
> 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
virtual
> stack). This is what REBOL does. The "bug" you describe is a normal
and
> inevitable side effect of this, and not a "bug" at all. Your "fix"
changes the
> function execution model in a way that generates unacceptable
performance.
> If you really need the behavior you describe then you are, of course,
free to
> write your own functions which implement it, as you have done, but for
performance
> reasons that behavior should not be the default in REBOL. > > - The drawback you describe in regard to what you call the Dynamic
Recursion Path
> is actually caused by the fact that the context of the outer function
remains
> intact (indefinite extent) AND retains its values after the outer
function
> returns (for non-recursive function invocations), under certain
circumstances.
> This is an implementation detail you should not rely on, because it is
likely to
> change in future versions, i.e. there is a good chance that in the
future after
> a (non-recursive) function invocation the values of that function's
context are
> set to unset!. This would break the way your inner function references
the
> 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
function returns
> is that the referenced values do not get garbage-collected, even though
no (apparent)
> reference exists any more, until the function is called again. In some
situations
> (e.g. when trying to close and garbage-collect an unreferenced port)
this can be very
> problematic. > > Relying on the values of a function's context beyond the life time of
the corresponding
> 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 > [holger--rebol--com] >
Cheers Ladislav