[REBOL] Re: Elegant way to reference a function?
From: joel:neely:fedex at: 4-Dec-2001 8:50
Hi, Patrick,
pat665 wrote:
> Hi Chaz,
>
> I did not know what a context was so I went for the doc. It
> reads "This is a shortcut for MAKE OBJECT!. ". So a context
> is an other name for an object. I'm afraid I don't understand
> how it will help me. Do you have more on this ?
>
Unfortunately the context to Chaz referred is not the CONTEXT
word pre-defined to the interpreter.
curmudgeonly-opinion: {
Of all the examples of nearly-useless redundant words,
creating a "shortcut" for the two-word phrase MAKE OBJECT!
(thus saving a whole 4 keystrokes!) is The Worst Example
of A Bad Idea, most especially because it overloads what
is already a barely-documented concept central to
understanding REBOL.
}
Here's the meaning of "context" (the idea, not the so-called
shortcut...) by comparison/contrast with other languages:
In many programming languages, variables are just names for
addresses in memory into which one may store data. The job
of the compiler was to generate code by translating variable
names into the corresponding memory addresses.
Once we programmers started breaking programs into idea-sized
chunks (such as FORTRAN subroutines -- this is a very old
issue in programming ;-), we had to deal with the idea
of the "scope" of a variable, which was the portion of the
source code within which a particular name had a particular
address associated with it. Languages such as C are the
endpoint of that evolutionary path, with various keywords
to control the visibility and lifetime of these names and
the associated memory addresses.
In a radical departure from this model, LISP introduced the
idea that symbols/names in a program were more like words
in a dictionary; to find the value associated with a name,
you look that name up in an appropriate dictionary and take
the corresponding value found there. (Most of the LISP
literature calls these dictionaries "environments".)
This opened the possibility that there could be multiple
dictionaries, with one or more of them being relevant for
a particular range of time or code.
A REBOL "context" is such a dictionary, and there are
several features of REBOL which cause contexts to be
created: defining a function, evaluating a USE expression,
and making an object all do that.
Consider this example:
>> generate-pairs: func [n [integer!] /local pair-with result] [
[ result: clear []
[ pair-with: func [m [integer!] n [integer!] /local result] [
[ result: clear []
[ repeat i n [repend/only result [m i]]
[ ]
[ repeat i n [append result pair-with i n]
[ ]
>> result: "this is some other thing"
== "this is some other thing"
>> generate-pairs 3
== [[1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3]]
>> result
== "this is some other thing"
(not written for maximum efficiency, but to make a point)
The word RESULT appears many times in the above transcript, but
in one sense there are three words named "result". There's a
global context which includes the following mapping
'result --> "this is some other thing"
a context associated with GENERATE-PAIRS which includes (at the
end) the mappings
'result --> [[1 1][1 2][1 3][2 1][2 2][2 3][3 1][3 2][3 3]]
'pair-with --> (...a function value...)
and a context associated with that last function value above which
includes (at the end)
'result --> [[3 1][3 2][3 3]]
These hidden dictionaries are central to the behavior of REBOL,
but their nature is for the most part undocumented. About the
only semi-explicit appearance they make in REBOL is through the
BIND native, which causes one or more words to become associated
with a different context, based on a word from that context.
Evaluating a REBOL word doesn't mean looking at a corresponding
memory address fixed at compile time. Instead it means checking
the context to which that word is bound, and seeing what value
is associated with that word in the context "dictionary". (And
there's more that may happen, depending on the type of the value
that is found there, but that's a different discussion.)
AFAICT (and there are many wizards on this list who will correct
me if I'm wrong), one can imagine something like this:
'generate-pairs ---+
|
V (global context)
+----------------+---+
: ... : :
'result ----> +----------------+---+
| result | *------> "this is some other thing"
+----------------+---+
| generate-pairs | *------> +-----------
+----------------+---+ | ... whatever a function!
: ... : : | looks like inside the
+----------------+---+ | REBOL interpreter...
| *
+-|---------
|
+--------------------------+
'pair-with ---+ |
| |
V V (context for GENERATE-PAIRS)
'result ----> +-----------+---+
| result | *------> [[1 1]...]
+-----------+---+
| pair-with | * |
+-----------+-|-+
|
V
+-----
| ...whatever a function!
| looks like inside the
| REBOL interpreter...
| *
+-|---
V
... you get the idea...
What value you get for the symbol 'result depends on which
dictionary you look it up in.
Finally, since an object has a context, somebody decided that
the word CONTEXT could be used as a "shortcut" for the two-word
phrase MAKE OBJECT! thus providing an opportunity to confuse the
two meanings.
HTH!
-jn-
--
; sub REBOL {}; sub head ($) {@_[0]}
REBOL []
# despam: func [e] [replace replace/all e ":" "." "#" "@"]
; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"}
print head reverse despam "moc:xedef#yleen:leoj" ;