[REBOL] problems with local vars??? Re:(6)
From: larry:ecotope at: 18-Aug-2000 17:34
Hi Galt
You raise some interesting questions. I don't have time right now to go into
much detail on this, so just a couple of quick comments.
> p.s. although Rebol may be "interpreted",
> the body and params and etc. have been fully
> "load"-ed and that means they are like typed
> tokens and bound words that are ready to roll.
make function! which can be used directly and is called by 'func and
'function takes two block args: spec and body. The spec block contains a
spec which is a REBOL dialect. It is parsed (internally) with the spec
dialect rules to determine the meaning. make function! creates a local
enviroment or frame with bindings for the local words. The local words
include each arg, each refinement (as a word!), each refinement arg, as well
as each local specified with /local. These are all bound locally and have
the value unset!.
When the function is executed, the interpreter evaluates the refinements to
true or false, and evaluates the args and refinement args and binds the
local words in the local frame to those values or, as appropriate to none.
The interpreter then simply evaluates 'do body-block.
third :f gives the original spec and first :f gives the word list including
/local to separate those values specified with local. In both cases, the
words in the returned block are not bound to the local context of the
function. These are "dead" blocks, the original versions in the function
cannot be modified by appending something to the "dead" blocks. In other
words, the spec cannot be modified after the function is created, it is used
during the function creation process (i.e. by make). After creation, these
blocks provide reflective info about the function. Of course, they *can* be
used to create a new function with the same spec or with a modification of
the spec.
second :f is different. It returns a "live" block of code (the body) with
the contained words bound to the local frame of the function f. This block
of code can be modified with and extended (with append etc. using 'bind if
necessary) after the function is created. It seems clear that the
interpreter executes the function by 'do-ing this body block.
> It's not like a lot of simple interpreters which are converting
> straight from source as just a string of characters
> for each and every line.
Well, it is not a string, it is a block defined within a context.
> when the function definition is executed
> that baby creates the function! value and
> assigns it to the function's name word,
> and that value sure isnt just a string! of code.
As above, I think the body is a block of code with words bound in a private
frame, which *is* actually evaluated by the interpreter each time the
function is called. Of course, the arg values are bound to the local words
first. Recursion requires more explanation. See some of the recent posts on
contexts by Ladislav.
> so that makes sense and the interpreter can run
> pretty fast. I am sure that it is the same
> with Logo, Lisp, Scheme, etc... I think the
> series type is also something that helps make
> Rebol fast. I don't recall seeing its like
> in those other cousins of Rebol.
REBOL blocks and more generally series combine the access and modification
features of Scheme lists (head, tail, next, first) and Scheme vectors (pick,
poke, at).
Most of the above is just my current best guess about how function creation
works.
Cheers
-Larry
--------snip