[REBOL] Re: [subject: error and trial]
From: holger:rebol at: 5-Mar-2002 10:59
On Tue, Mar 05, 2002 at 12:41:50PM -0500, alan parman wrote:
> How about a new value confusing?
> As in confusing? 'undefined? ==> true :)
A little background information:
In REBOL everything is a value. That includes words. So internally, something
like 'foo or first [foo] is a value just like any other value (integers,
blocks etc.).
Values have properties that distinguish them from other values of the same
type. For instance the (only) property of an integer! value is the number
itself. block! values have two properties: a reference to the block series
(which can be shared with other block! values), and an index.
With this point of view, values of type word! have properties, too, exactly
two of them: one is the spelling of the word, the other one is the context the
word is bound into. Contexts are name-value lookup tables which are used to
hold "variables" for functions, objects and use []. A context consists of two
tables: a table of words and a table of corresponding values. For object!s
you can actually look at those two tables:
>> a: make object! [b: 1 c: 2]
>> first a
== [self b c] ; The table of all words in the context
>> second a
== [ ; The table of all corresponding values in the context
make object! [ ; the first one being the object itself (self)
b: 1
c: 2
] 1 2]
There is also one "global context" in REBOL that is used for globally defined
variables. Almost all words used in REBOL are automatically bound into the
global context (usually during 'load). Some words are later rebound into a
different context, but only after they were first bound into the global
context. For instance the words that appear inside of the body of a function
are first bound into the global context when your script is loaded. Later, when
REBOL executes the function definition, the words in the body of the function
are rebound into the context created for the function.
As a result, all words in a normally loaded REBOL script are always bound into
some context, either the global context or some other context.
Binding a word into a context does not assign a value to it. It only associates
a word with a context. The value of a word in a context is defined separately,
e.g. using 'set or the set-word notation.
It IS possible to create words which are not bound into any context at all, and
that is what Ladislav's undefined? function detects. A better name would be
unbound?. It is not possible to assign a value to unbound words, because there
is no context to hold the value.
Unbound words are relatively rare in normal use (which is why you rarely see
undefined? return true), but they do occur, usually in one of three ways:
- Some natives that return words as symbols return unbound words.
An example is "type?". It returns a word describing the datatype of
the argument. That word is an unbound word:
>> undefined? type? 1
== true
- "first" applied to an object! returns a block of words (the "left"
half of the name-value lookup table used by the context of the
object!). The words in that table are unbound. This also includes
first system/words (because system/words is an object representing
the global context).
>> a: make object! [b: 1]
>> undefined? second first a
== true
- to-block applied to a string! is similar to "load", but, unlike
"load", does not bind the resulting words into the global context.
All words remain unbound.
>> a: to-block "b"
>> undefined? first a
== true
In almost every other situation undefined? returns false, because the word
has been bound into a context. In contrast, value? only returns true if
a word is bound into a context AND in that context the value of the word
has been defined (i.e. is different from unset!). The effect of the
unset native is only to set the value of a word in its context to unset!
(so value? subsequently returns false). It does not "unbind" a word from
a context, i.e. the value returned by undefined? is not affected by it.
The part that, at first, may make these concepts a little confusing, is
that many users intuitively associate a word only with its spelling, and
ignore the context. For instance:
>> type? 1
== integer!
>> undefined? type? 1
== true
>> undefined? integer!
== false
In this example two different values representing words are used, which are
both spelled "integer!": the first is the one returned by "type? 1". It is not
bound into a context, so undefined? returns true. The second is the one typed
into the console. When REBOL interprets the sequence of characters you type,
it first loads it, which binds all words into the global block, so for THAT
instance of the word "integer!" undefined? returns false.
--
Holger Kruse
[kruse--nordicglobal--com]