Model hacking
[1/13] from: joel::neely::fedex::com at: 21-Jun-2001 4:23
I (personally) think that the recent discussions on mutability
and SAME? vs. EQUAL? may have narrowed our scope and bogged
us down a bit too much (and I hereby claim my share of the
blame for that! ;-)
I think we'd agree that understanding the rich set of available
data types is one of the keys to using REBOL more effectively
and accurately. One of the issues I've been pondering lately
is the kinds of characteristics that allow us to group,
distinguish, and describe this embarrasment of riches.
I thought I'd make it an "open source" pondering and toss out
some ideas for expansion, refinement , pruning, and improvement
by the community. I've made up some terms here, and am very
open to suggestions for better jargon. Some of these
distinctions are:
1) LITERAL -- Some types (e.g., decimal!, time!, block!) have
the property that you can explicitly represent
a value of that type in REBOL source code. For other types
(e.g., list!, object!, or function!) you can only write
expressions (e.g., make or copy) that cause such a value to
be constructed with the expression is evaluated.
2) REFERENCE vs. SCALAR -- Values of some types (series!, for
example) are "referred to" in a
way that lets them be shared among words, blocks, etc. Other
type (such as integer!) are not shared.
3) ELEMENTARY vs. COMPOSITE -- Values of some types have
"sub-"components that REBOL
explicitly lets us talk about (e.g., time! values with their
/hour, /minute, and /second fields). Other types (e.g. char!
and logic!) do not.
4) ACTIVE vs. PASSIVE -- Values of some types actually "take
some action" when evaluated, while
others are "just there". This is tied to the distinction
between
a: b
and
a: :b
of course. "Active" types include function! and tuple!, while
passive
types include issue! and money!.
5) SYSTEM vs. USER -- Some types are predefined by REBOL and
the user cannot create values of that
type (e.g., op!) while other types can be created at will
by the user's expressions (object! and function!)
6) CLOSED vs. OPEN -- Some types (logic! and datatype!) have
a set-in-concrete set of possible
values, while others are open-ended and new values may be
created at will (function! and block!)
7) MUTABLE vs. IMMUTABLE -- ... I don't think I'll say any more
about this one right now! ;-)
Are these useful distinctions? Are there others that would
be helpful? Can we actually identify how each type fits into
each of these?
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[2/13] from: robbo1mark:aol at: 21-Jun-2001 12:25
JOEL,
Iam happy to "collaberate" with you on discussing these items at as "high level" / natural
language or as "low level" / some bits or compiled language as you & others wish.
You all know what my preferred end use for knowledge gleaned from these discussions is
so I'll make it explicity clear right here right now, I *want* to glean as much knowledge
and as much understanding of the structure and composition of REBOL and REBOL values
which I can hopefully use for my own ends which is formulating sufficient information
and understanding to some day implement my own *bastardized* REBOL at some unspecified
future date.
However, whatever our motives we can all benefit in our understanding in sharing knowledge
& model "hacking" as Joel calls it, so hopefully others will participate too.
Hopefully you will Count me in! if my motives don't exclude me?
cheers,
Mark
In a message dated Thu, 21 Jun 2001 10:36:20 AM Eastern Daylight Time, Joel Neely <[joel--neely--fedex--com]>
writes:
<< I (personally) think that the recent discussions on mutability
and SAME? vs. EQUAL? may have narrowed our scope and bogged
us down a bit too much (and I hereby claim my share of the
blame for that! ;-)
I think we'd agree that understanding the rich set of available
data types is one of the keys to using REBOL more effectively
and accurately. One of the issues I've been pondering lately
is the kinds of characteristics that allow us to group,
distinguish, and describe this embarrasment of riches.
I thought I'd make it an "open source" pondering and toss out
some ideas for expansion, refinement , pruning, and improvement
by the community. I've made up some terms here, and am very
open to suggestions for better jargon. Some of these
distinctions are:
1) LITERAL -- Some types (e.g., decimal!, time!, block!) have
the property that you can explicitly represent
a value of that type in REBOL source code. For other types
(e.g., list!, object!, or function!) you can only write
expressions (e.g., make or copy) that cause such a value to
be constructed with the expression is evaluated.
2) REFERENCE vs. SCALAR -- Values of some types (series!, for
example) are "referred to" in a
way that lets them be shared among words, blocks, etc. Other
type (such as integer!) are not shared.
3) ELEMENTARY vs. COMPOSITE -- Values of some types have
"sub-"components that REBOL
explicitly lets us talk about (e.g., time! values with their
/hour, /minute, and /second fields). Other types (e.g. char!
and logic!) do not.
4) ACTIVE vs. PASSIVE -- Values of some types actually "take
some action" when evaluated, while
others are "just there". This is tied to the distinction
between
a: b
and
a: :b
of course. "Active" types include function! and tuple!, while
passive
types include issue! and money!.
5) SYSTEM vs. USER -- Some types are predefined by REBOL and
the user cannot create values of that
type (e.g., op!) while other types can be created at will
by the user's expressions (object! and function!)
6) CLOSED vs. OPEN -- Some types (logic! and datatype!) have
a set-in-concrete set of possible
values, while others are open-ended and new values may be
created at will (function! and block!)
7) MUTABLE vs. IMMUTABLE -- ... I don't think I'll say any more
about this one right now! ;-)
Are these useful distinctions? Are there others that would
be helpful? Can we actually identify how each type fits into
each of these?
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[3/13] from: lmecir:mbox:vol:cz at: 22-Jun-2001 21:42
Hi,
> OBTW, I really liked your article
>
> http://www.rebolforces.com/articles/series.html
>
> Would it do violence to your model to address the notion that
>
> index? foo
>
> must lie within the range 1 thru 1 + LENGTH? FOO and that
yes, it is incorrect in my model... ;-) ,
I would say, that it must lie within the range 1 thru 1 + LENGTH? HEAD FOO
> tail? foo
>
> is equivalent to
>
> index? foo = (1 + length? head foo)
>
That wouldn't do any violence, I may try to find an appropriate place for it
> > > 1) LITERAL -- Some types (e.g., decimal!, time!, block!) have
> > > the property that you can explicitly represent
<<quoted lines omitted: 7>>
> > "literal" in a composed block.
> >
...snip...
> Part of the motivation has to do with our old friend...
>
> koan: func [x /local z] [
> z: [] append z x mold head z
> ]
>
...snip...
> Finally, if we
> wished KOAN to deal with LIST! instead of BLOCK! data, we are
<<quoted lines omitted: 11>>
> we cannot create the situation that occurred in the first
> case.
My motivation was exactly the same: you can create almost anything
(especially in Rebol!), if you will:
koan: func [x /local z] reduce [
first [z:] make list! 0 'append 'z 'x 'mold 'head 'z
]
source koan
; koan: func [x /local z][z: make list! [] append z x mold head z]
koan 4 ; == "make list! [4]"
koan 6 ; == "make list! [4 6]"
koan 17 ; == "make list! [4 6 17]"
This doesn't mean I have got anything against the classification you
proposed :-)
LM
[4/13] from: lmecir:mbox:vol:cz at: 22-Jun-2001 22:44
ROTFL :-)
> Inspired by the style of your "Evaluation" essay, this leads me
> to define
>
> >> elementary?: func [x] [error? try [first x]]
> >> composite?: func [x] [not elementary? x]
Now I know.
Another one:
5) SYSTEM vs. USER -- Some types are predefined by REBOL and
the user cannot create values of that
type (e.g., op!) while other types can be created at will
by the user's expressions (object! and function!)
6) CLOSED vs. OPEN -- Some types (logic! and datatype!) have
a set-in-concrete set of possible
values, while others are open-ended and new values may be
created at will (function! and block!)
5) and 6) look like being "unifiable"
LM
[5/13] from: joel:neely:fedex at: 22-Jun-2001 12:56
Ladislav Mecir wrote:
> Another one:
> 5) SYSTEM vs. USER -- Some types are predefined by REBOL and
<<quoted lines omitted: 6>>
> created at will (function! and block!)
> 5) and 6) look like being "unifiable"
I pondered that issue, and freely admit that I decided to
separate them primarily on philosophical grounds. (However,
I was in a hurry and confused the issue by a VERY poor
choice of examples.) Let me go to extremes first:
LOGIC! - Not only "closed", but closed "in principle".
It wouldn't seem to make sense for RT to release
a new version of /core or /view with new values of this type.
BLOCK! - Open "in principle". Anyone may evaluate code that
creates a block that has never existed before (with
arbitrarily high probability, at least ;-)
>> reduce ["Joel's birthday might be"
[ to-date reduce [random 2000 random 12 random 31]
[ "which would make him"
[ random 2000
[ "years old"
[ ]
== ["Joel's birthday might be" 6-May-0283
"which would make him" 489
"years old"]
In between those extremes are:
EVENT! - I thought I saw an email about users not being
able to create events. Whether memory serves me
correctly or not, it seems that "in principle" RT could
define a datatype that could be created by the interpreter
but not directly by the user.
OP! and NATIVE! - Although a given release has a finite,
specific set of these, each new release
can (and usually does) contains an expanded set, drawn
from a seemingly inexhaustible fount which remains beyond
the reach of mere mortals! (The DATATYPE! type should have
been in this category, but I rushed through my typing too
quickly. Mea culpa!)
Now for the slightly more controversial cases ;-)
CHAR! and INTEGER! - I propose that these are CLOSED (in
that the set of *possible* character
and integer values are finite) but USER (in the sense that
I can make one whenever I want).
One issue wrt calling INTEGER! a closed type is that if RT
were to add a BIGNUM! type (integral of arbitrary precision)
to a future version of REBOL, I'd think of BIGNUM! as
OPEN/USER (no a priori upper limit, except for the size of
your swap file ;-)
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[6/13] from: joel:neely:fedex at: 22-Jun-2001 12:35
Hi, Ladislav,
Perhaps this is a more concise response...
Ladislav Mecir wrote:
> >
> > 3) ELEMENTARY vs. COMPOSITE -- Values of some types have
<<quoted lines omitted: 5>>
> attribute of any Rebol value?
>> first 12:34:56
== 12
>> first [1 2 3 4]
== 1
>> first 12.34.56.78
== 12
versus
>> first true
** Script Error: first expected series argument of type:
series pair event money date object port time tuple
any-function library struct event
** Where: halt-view
** Near: first true
>> first #"X"
** Script Error: first expected series argument of type:
series pair event money date object port time tuple
any-function library struct event
** Where: halt-view
** Near: first #"X"
Inspired by the style of your "Evaluation" essay, this leads me
to define
>> elementary?: func [x] [error? try [first x]]
>> composite?: func [x] [not elementary? x]
as in
>> map :elementary? reduce [
[ 12:34:56 [1 2 3 4] 12.34.56.78 true #"X" ]
== [false false false true true]
and
>> map :composite? reduce [
[ 12:34:56 [1 2 3 4] 12.34.56.78 true #"X" ]
== [true true true false false]
-jn-
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[7/13] from: jeff:rebol at: 22-Jun-2001 8:26
> callable?: func [
> {finds out, if a Rebol value is callable}
<<quoted lines omitted: 9>>
> ]
> ]
callable?: func ['v][
parse compose [(:v)][
lit-word! | set-word! | set-word! |
lit-path! | path! | set-path!
]
]
;-- :-)
[8/13] from: gjones05:mail:orion at: 22-Jun-2001 11:02
From: "Jeff Kreis"
> callable?: func ['v][
> parse compose [(:v)][
<<quoted lines omitted: 3>>
> ]
> ;-- :-)
You clever dog!
--Scott Jones
[9/13] from: joel:neely:fedex at: 22-Jun-2001 11:54
Hi, Ladislav,
Specific observations further below...
OBTW, I really liked your article
http://www.rebolforces.com/articles/series.html
Would it do violence to your model to address the notion that
index? foo
must lie within the range 1 thru 1 + LENGTH? FOO and that
tail? foo
is equivalent to
index? foo = (1 + length? head foo)
or is that there and I just missed it?
>> phlarp: ["a" "b" "c" "d"] == ["a" "b" "c" "d"]
>> length? phlarp == 4
<<quoted lines omitted: 5>>
>> tail? gloop == true
>> map func [s] [(index? s) = (1 + length? head s)] reduce [
[ phlarp
[ tail phlarp
[ gloop]
== [false true true]
>> map func [s] [tail? s] reduce [
[ phlarp
[ tail phlarp
[ gloop]
== [false true true]
Ladislav Mecir wrote:
> Hi,
>
> I modified (again) the http://www.sweb.cz/LMecir/evaluation.html
>
> It now sports three functions: IDENTICAL?, EQUAL-STATE? and
> FIND-OCCURRENCE.
>
I'm looking forward to re-reading it (but it may take a couple
of days to fit it in...)
> See my notes below:
> >
<<quoted lines omitted: 7>>
> loud) is, that if you want, you can use any Rebol value as
> "literal" in a composed block.
Perhaps the problem is my explanation. If by "in a composed block"
you mean something like
>> gorp: [1 12:34:56 [1 2] (make list! [1 2])]
== [1 12:34:56 [1 2] (make list! [1 2])]
>> length? gorp
== 4
>> foreach item gorp [print type? :item]
integer
time
block
paren
>> glop: compose gorp
== [1 12:34:56 [1 2] make list! [1 2]]
>> length? glop
== 4
>> foreach item glop [print type? :item]
integer
time
block
list
then I'd say that it illustrates the distinction I'm trying to
draw. There was no LIST! until the paren got evaluated by the
COMPOSE. As another demo, given a file named foo.r containing
1 12:34:56 [1 2] make list! [1 2]
we can say
>> foo: load %gorp.r
== [1 12:34:56 [1 2] make list! [1 2]
]
>> length? foo
== 6
>> foreach item foo [print type? item]
integer
time
block
word
word
block
>> foo: reduce load %gorp.r
== [1 12:34:56 [1 2] make list! [1 2]]
>> length? foo
== 4
>> foreach item foo [print type? item]
integer
time
block
list
Again, there's no LIST! until after the REDUCE evaluated the
MAKE... expression.
Part of the motivation has to do with our old friend...
koan: func [x /local z] [
z: [] append z x mold head z
]
>> koan 4
== "[4]"
>> koan 6
== "[4 6]"
>> koan 17
== "[4 6 17]"
The second element of the body of KOAN is a "literal" block.
Once Z refers to that block, any changes via Z are changing the
second element of the body of KOAN.
On the other hand, in this version...
koan: func [x /local z] [
z: make block! 0 append z x mold head z
]
>> koan 4
== "[4]"
>> koan 6
== "[6]"
>> koan 17
== "[17]"
...there is no literal block, only instructions to make a new
one. There's no persistence to trouble us. Finally, if we
wished KOAN to deal with LIST! instead of BLOCK! data, we are
forced to write...
koan: func [x /local z] [
z: make list! 0 append z x mold head z
]
>> koan 4
== "make list! [4]"
>> koan 6
== "make list! [6]"
>> koan 17
== "make list! [17]"
...because there's no "literal" syntax for list. Consequently,
we cannot create the situation that occurred in the first
case.
> >
> > 3) ELEMENTARY vs. COMPOSITE -- Values of some types have
<<quoted lines omitted: 4>>
> A rather subjective notion. Don't you think, that type is an
> attribute of any Rebol value?
It is certainly something I can say *about* the value, but it
is not a sub-component *of* the value IMHO. Jeff recently had
quite a bit to say in a recent post about viewing a series as
a single value vs. considering it as a collection of values.
I can do that with (e.g.) time! or tuple! values as well,
taking them apart...
>> t: now/time == 11:45:41
>> t/hour == 11
<<quoted lines omitted: 5>>
>> third u == 56
>> fourth u == 78
...or putting them together...
>> tt: make time! reduce [t/hour t/minute t/second]
== 11:45:41
>> uu: make tuple! reduce [u/1 u/2 u/3 u/4]
== 12.34.56.78
...but I know of no corresponding way in which REBOL invites me
to think about the "parts" of a logic! value.
> >
> > 4) ACTIVE vs. PASSIVE -- Values of some types actually "take
<<quoted lines omitted: 14>>
> 2) how a value behaves as a "contents" of a word ...
> 3) all other values I call Passive
Let me think about that one for a while.
> 8) Second class values: ERROR! and UNSET! datatypes
>
> the ERROR! values cannot be normally obtained as a result of a block
> evaluation, e.g. For more see REP.html
>
> UNSET! type value isn't considered a value by Rebol sometimes
>
Thanks! A distiction between FIRST-CLASS and SECOND-CLASS seems
useful for the kinds of categorizations I had in mind
-jn-
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[10/13] from: joel:neely:fedex at: 22-Jun-2001 12:07
Hi, Jeff,
Jeff Kreis wrote:
> callable?: func ['v][
> parse compose [(:v)][
> lit-word! | set-word! | set-word! |
> lit-path! | path! | set-path!
> ]
> ]
>
So SET-WORD! is twice as callable as (e.g.) PATH! and FUNCTION!
is not callable? ;-)
-jn-
--
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[11/13] from: lmecir:mbox:vol:cz at: 22-Jun-2001 15:38
Hi,
I modified (again) the http://www.sweb.cz/LMecir/evaluation.html
It now sports three functions: IDENTICAL?, EQUAL-STATE? and FIND-OCCURRENCE.
Sample code:
a: []
insert/only a a
b: []
insert/only b b
o: make object! [a: 1]
p: make object! [a: 1]
identical? a b ; == false
identical? o p ; == false
equal-state? a b; == true
equal-state? o p; == true
Warning! Don't try to use SAME? or EQUAL? instead!
See my notes below:
----- Original Message -----
From: Joel Neely <[joel--neely--fedex--com]>
To: <[rebol-list--rebol--com]>
Sent: Thursday, June 21, 2001 11:23 AM
Subject: [REBOL] Model hacking
> I (personally) think that the recent discussions on mutability
> and SAME? vs. EQUAL? may have narrowed our scope and bogged
<<quoted lines omitted: 16>>
> expressions (e.g., make or copy) that cause such a value to
> be constructed with the expression is evaluated.
This is an interesting category. The only "problem" (thinking out loud) is,
that if you want, you can use any Rebol value as "literal" in a composed
block.
> 2) REFERENCE vs. SCALAR -- Values of some types (series!, for
> example) are "referred to" in a
> way that lets them be shared among words, blocks, etc. Other
> type (such as integer!) are not shared.
Let me translate the last sentence to something that might be correct:
INTEGER! type values are (probably) implemented as non-shared values in a
Language I Do Not Want To Name Here in the current implementation of Rebol
from RT.
If RT implemented them as shared values in a LIDNWTNH, you would
have no chance to see any difference observing the behaviour of your
programs. In different words: this notion is not saying anything about the
properties of Rebol.
> 3) ELEMENTARY vs. COMPOSITE -- Values of some types have
> "sub-"components that REBOL
> explicitly lets us talk about (e.g., time! values with their
> /hour, /minute, and /second fields). Other types (e.g. char!
> and logic!) do not.
A rather subjective notion. Don't you think, that type is an attribute of
any Rebol value?
> 4) ACTIVE vs. PASSIVE -- Values of some types actually "take
> some action" when evaluated, while
<<quoted lines omitted: 5>>
> of course. "Active" types include function! and tuple!, while
> "passive" types include issue! and money!.
I see three categories here:
1) how a value behaves as a "literal" in a block - Activity. Active values
are:
active?: func [
{finds out, if a Rebol value is active}
value [any-type!]
] [
found? any [
any-function? get/any 'value
get-word? get/any 'value
lit-word? get/any 'value
set-word? get/any 'value
word? get/any 'value
lit-path? get/any 'value
path? get/any 'value
set-path? get/any 'value
]
]
2) how a value behaves as a "contents" of a word - Callability. Callable
values are:
callable?: func [
{finds out, if a Rebol value is callable}
value [any-type!]
] [
found? any [
any-function? get/any 'value
lit-word? get/any 'value
set-word? get/any 'value
lit-path? get/any 'value
path? get/any 'value
set-path? get/any 'value
]
]
3) all other values I call Passive
> 5) SYSTEM vs. USER -- Some types are predefined by REBOL and
> the user cannot create values of that
<<quoted lines omitted: 9>>
> be helpful? Can we actually identify how each type fits into
> each of these?
8) Second class values: ERROR! and UNSET! datatypes
the ERROR! values cannot be normally obtained as a result of a block
evaluation, e.g. For more see REP.html
UNSET! type value isn't considered a value by Rebol sometimes
[12/13] from: joel:neely:fedex at: 23-Jun-2001 8:14
rehi, Ladislav,
Ladislav Mecir wrote:
> > Would it do violence to your model to address the notion
> > that
<<quoted lines omitted: 4>>
> I would say, that it must lie within the range 1 thru
> 1 + LENGTH? HEAD FOO
My typo, oops! (corrected a few lines further on)
> >
> > tail? foo
<<quoted lines omitted: 10>>
> > > > copy) that cause such a value to be constructed when the
> > > > expression is evaluated.
I should add that LOGIC! and NONE! are (in the terms above)
non-literal types. Failure to understand this is another
fruitful source of confusion for REBOL beginners.
> > > This is an interesting category. The only "problem"
> > > (thinking out loud) is, that if you want, you can use any
> > > Rebol value as "literal" in a composed block.
>
As COMPOSE is a native which causes further evaluation of (parts
of) its argument, I view COMPOSE (and REDUCE, for that matter)
in the same category as MAKE and COPY. If one of them is
required to cause the construction of values of a given type
at run time
, then that type is not "literal" in the sense I
was attempting to define.
> > Part of the motivation has to do with our old friend...
> >
<<quoted lines omitted: 10>>
> > z: make list! 0 append z x mold head z
> > ]
...
> > Consequently, we cannot create the situation that occurred
> > in the first case.
<<quoted lines omitted: 3>>
> first [z:] make list! 0 'append 'z 'x 'mold 'head 'z
> ]
...
> koan 4 ; == "make list! [4]"
> koan 6 ; == "make list! [4 6]"
> koan 17 ; == "make list! [4 6 17]"
>
While a nice demonstration of the REBOL's subtlety, this is
IMHO a *different* subtlety than the one I was discussing as
the situation
above. Since it uses REDUCE to construct the
function body prototype, we're no longer dealing with literal
values.
What I mean by "the situation" was the case in which the
programmer uses in his/her source code a literal value
instead of an expression that evaluates to a value of the
same type, and where that substitution causes different
(side-)effects in later evaluations. I conjecture that your
demonstration above was not an oversight, but rather that
you deliberately thought about how to obtain the effect you
wanted to demonstrate! (i.e., you're too bright for me to
believe it was an accident ;-)
Now, confession time. I wimped out.
I had originally considered calling this characteristic
LEXICAL
instead of "LITERAL", but backed off in hopes of
avoiding the issue of whether that word was too technical.
Lo and behold, R/CUGV2.3 states on page A-19
Hash blocks must be constructed by using MAKE or
TO-HASH. They have no lexical format.
and again on page A-24
List blocks muste be constructed by MAKE or TO-LIST.
They have no lexical format.
Clearly I should have had the courage to stick with "lexical"!
I now propose, with reddened face, that this property take
its rightful name.
In the interest of precision, here's a proposed test. Given
a file named lexical.r which contains
8<------------------------------------------------------------
REBOL []
123
123.4
1.2.3
[1 2 3]
12:34:56
2001-06-23
now is the time
{those were the days}
true
false
none
8<------------------------------------------------------------
I can ask REBOL to evaluate the following:
>> foo: load %lexical.r
== [
123
123.4
1.2.3
[1 2 3]
12:34:56
23-Jun-2001
"now is the time"
"those were the days"
...
>> length? foo
== 11
>> foreach item foo [print [type? item "^-" item]]
integer 123
decimal 123.4
tuple 1.2.3
block 1 2 3
time 12:34:56
date 23-Jun-2001
string now is the time
string those were the days
word true
word false
word none
as the basis for stating that integer!, decimal!, tuple!,
block!, time!, date!, and string! are lexical types and that
logic! and none! are not. Further, if I insert another line
at the beginning of the file, so that it begins
8<------------------------------------------------------------
REBOL []
make list! [1 2 3]
123
123.4
1.2.3
8<------------------------------------------------------------
... and so on ...
I can repeat the experiment.
>> foo: load %lexical.r
== [
make list! [1 2 3]
123
123.4
1.2.3
...
>> length? foo
== 14
>> foreach item foo [print [type? item "^-" item]]
word make
word list!
block 1 2 3
integer 123
decimal 123.4
... etc.
Since I did not suceed in getting a list! as the first
element of FOO, I consider list! as non-lexical. I'd be
very interested to see any demonstration of text typed
into the front of the file that actually does load to a
list! value.
We can continue the experiment by performing an additional
evaluation step, as in
>> baz: reduce foo
== [make list! [1 2 3]
123
123.4
1.2.3
[1 2 3]
...
>> length? baz
== 12
>> foreach item baz [print [type? item "^-" item]]
list 1 2 3
integer 123
decimal 123.4
tuple 1.2.3
...
but there was no list! until the REDUCE performed its
evaluation.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[13/13] from: lmecir:mbox:vol:cz at: 26-Jun-2001 7:19
Hi Joel,
...snip...
> I had originally considered calling this characteristic
> "LEXICAL" instead of "LITERAL", but backed off in hopes of
> avoiding the issue of whether that word was too technical.
...snip...
the problem seems to be the need to use an appropriate set of notions. I
don't know how to call a value contained in a computed block, as e.g. in
block: reduce [:do] ; == [native]
,"literal" may be confusing.
Regards
Ladislav
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted