On mutability and sameness
[1/114] from: agem:crosswinds at: 5-Jun-2001 16:59
a: now
? a
A is a date of value: 5-Jun-2001/17:29:40+2:00
a/time: 00:00 ; this way!
? a
A is a date of value: 5-Jun-2001/0:00+2:00
General rule: if it fits in a »rebol-slot«, ~ 8 (?) byte, it is copied
by value.
like for tuple! , pair! , time! ..
If its bigger, its referenced. Usually ;)
Since it can have multiple components (pair!/x pair!/y) we can assign
them seperate.
That has nothing to do with referencing.
Thanks for the interesting topic.
-Volker
>>>>>>>>>>>>>>>>>> Ursprüngliche Nachricht <<<<<<<<<<<<<<<<<<
Am 05.06.01, 14:45:41, schrieb Joel Neely <[joel--neely--fedex--com]> zum
Thema [REBOL] On mutability and sameness:
[2/114] from: sanghabum:aol at: 5-Jun-2001 12:33
Hi Joel
> Conclusions? I'm not sure, except that I haven't figured out
> a simple model for what's going on with DATE! values, and
> therefore don't have a simple model for REBOL values in general.
Some of it might simply be oversights in the depth of the Rebol code. Take
another example, this one with tuples:
>> mytuple: 1.2.3.4.5
== 1.2.3.4.5
>> poke mytuple 3 88
== 1.2.88.4.5
>> mytuple/2: 99
== 99
>> mytuple
== 1.99.3.4.5
>>
The Poked 88 has vanished! Magic!! Or maybe just a fault awaiting a fix.
(Reported as helpdesk ref #5630)
--Colin.
[3/114] from: gjones05::mail::orion::org at: 5-Jun-2001 13:24
From: "Colin"
> Some of it might simply be oversights in the depth of the Rebol code.
Take
> another example, this one with tuples:
> >> mytuple: 1.2.3.4.5
<<quoted lines omitted: 7>>
> >>
> The Poked 88 has vanished! Magic!! Or maybe just a fault awaiting a
fix.
> (Reported as helpdesk ref #5630)
I got caught by a similar problem once.
USAGE:
POKE value index data
DESCRIPTION:
Returns value after changing its data at the given index. (See
manual)
POKE is an action value.
ARGUMENTS:
value -- (Type: series money date time object port tuple)
index -- (Type: number logic)
data -- new value (Type: any)
One might argue that this description might be worded more clearly, but
poke is doing what its says it is doing:
mytuple: 1.2.3.4.5 ; == 1.2.3.4.5
poke mytuple 3 88 ; == 1.2.88.4.5
;it presents a changed value, but doesn't "change" mytuple
mytuple ; == 1.2.3.4.5
mytuple: poke mytuple 3 88 ; == 1.2.88.4.5
mytuple ; == 1.2.88.4.5
For what its worth...
--Scott Jones
[4/114] from: lmecir:mbox:vol:cz at: 5-Jun-2001 21:43
Hi Joel,
(it's in my REP somewhere :-)
Seriously: I was curious about the case of DATE! values too.
> >> a: now/date == 5-Jun-2001
I came to the conclusion, the DATE! values are immutable. The expression:
> >> a/day: 6 == 6
may not change a DATE! value. What is going on? See the following functions:
test1: func [
date [date!]
day [integer!]
] [
date/day: day
]
test2: func [
'date [word!]
day [integer!]
] [
set date poke get date 3 day
]
a: now
test1 a 6
a
a: now
test2 a 6
a
You know what is going on in the case of TEST1 and TEST2. I think, that
TEST2 simulates what is going on in the case of a set-path.
Regards
Ladislav
[5/114] from: joel:neely:fedex at: 5-Jun-2001 8:45
Just another bit of REBOL "particle physics"...
At one time (REBOL/Core 2.3?) values of type DATE! were
immutable. Now they're not. Well, not exactly! But they
also now don't behave as mutable reference values.
ON SAME AND EQUAL:
In most programming language (that make the distinction!),
two values are "equal" at a given moment if they can are
equivalent for some useful set of purposes (at that moment!)
Two values are "same" if they are *always* equivalent for
*all* purposes.
For a real-world example, if Ladislav and I win a contest
and are each awarded a Swiss bank account containing 1000
francs, we have "equal" account balances (at the time of
the award). Subsequent deposits and/or withdrawals will
probably render Ladislav's balance and my balance "unequal".
OTOH, if Carl and Cindy win a contest and are awarded a
*joint* Swiss bank account containing 2000 francs, they
have the "same" account balance. No subsequent deposits
and/or withdrawals can make their balance(s) unequal, as
they are the "same" balance.
ON MUTABILITY:
Mutable values can be modified "in place", while immutable
values cannot. One can replace a resistor in a discrete
circuit breadboard without changing the identity of the
circuit or its other attributes (location, owner, etc.)
One *cannot* replace a resistor in the CPU I'm using to
type this email, but can only unplug the CPU and plug in
a replacement CPU. The breadboard is mutable; the CPU is
immutable.
ON REFERENCE:
Reference values are "stored elsewhere" and represented by
some form of identifier, while non-reference values (AKA
primitive
, "elementary", or "atomic" values) do not need
that level of indirection. Reference values are typically
sharable, while non-reference values are often not sharable.
Life becomes a bit simpler if only sharable reference values
may be mutable, because the following general rules apply:
For mutable values, same IMPLIES equal.
For immutable values, same IS EQUIVALENT TO equal.
But, as we all know, sometimes REBOL isn't simple! ;-)
SIMPLE CASES IN REBOL:
INTEGER! values are non-reference, immutable values.
>> i: 1 + 1 + 1 + 1 == 4
>> j: 6 - 2 == 4
>> same? i j == true
>> equal? i j == true
STRING! values are mutable reference values (as are other
series values).
>> r: "hi!" == "hi!"
>> s: r == "hi!"
<<quoted lines omitted: 5>>
>> r/1: #"H" == "Hi!"
>> s == "Hi!"
Object values are mutable reference values, but do not admit
an EQUAL?ity test independent of SAME?ness (perhaps because
the general case is computationally non-trivial?)
>> o: make object! [x: 17 y: 42]
>> p: o
<<quoted lines omitted: 5>>
>> o/x: 19 == 19
>> source p
p:
make object! [
x: 19
y: 42
]
NOT-SO-SIMPLE CASES IN REBOL:
Once upon a TIME! (groan, sorry ;-), the DATE! type was
immutable. One *FORMERLY* could do something like this:
>> a: now/date == 5-Jun-2001
>> a/day: 6 == 6
>> a == 5-Jun-2001
Now the above sample works like this:
>> a: now/date == 5-Jun-2001
>> a/day: 6 == 6
>> a == 6-Jun-2001
making it appear that DATE! values are mutable. Perhaps, as
with series values, they're mutable references?
>> a: now/date == 5-Jun-2001
>> b: a == 5-Jun-2001
>> same? a b == true
>> equal? a b == true
Encouraged by our success thus far, we try the mutability
test for referencehood...
>> b/day: 6 == 6
>> a == 5-Jun-2001
>> same? a b == false
Wot?!?
Well, this begins to smell like the implementation technique
we called "self-relative descriptors" back in the late 60's
and early 70's!
However, they're are more surprises! Consider this:
>> a: now == 5-Jun-2001/8:31:47-5:00
>> b: a == 5-Jun-2001/8:31:47-5:00
>> c: b/date == 5-Jun-2001
>> b/date/day: 6 == 6
>> b == 5-Jun-2001/8:31:47-5:00
Hmmm... are DATE! values not mutable?
>> b/day: 6 == 6
>> b == 6-Jun-2001/8:31:47-5:00
Yes, so perhaps /DATE does an implicit copy? How can we tell?
>> b/time/hour: 9 == 9
>> b == 6-Jun-2001/8:31:47-5:00
So, "second-level" mutability does not apply? What about
first-level mutability
?
>> b/hour: 9 ** Script Error: Invalid path value: hour
** Where: halt-view
** Near: b/hour: 9
>> b/hour ** Script Error: Invalid path value: hour
** Where: halt-view
** Near: b/hour
Hmmm. There is no first-class access to the time fields of a
date.
>> b/time/hour == 8
>> c/time/hour ** Script Error: Cannot use path on none!
value
** Where: halt-view
** Near: c/time/hour
>> type? b == date!
>> type? c == date!
>> b/time
== 8:31:47
>> c/time
== none
Conclusions? I'm not sure, except that I haven't figured out
a simple model for what's going on with DATE! values, and
therefore don't have a simple model for REBOL values in general.
-jn-
PS: It *does* appear that a date is a composite entity with
some "refinements" that mimic simple component access,
but there seems to be more to the picture.
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[6/114] from: sanghabum:aol at: 5-Jun-2001 18:07
Hi Scott,
> One might argue that this description might be worded more clearly, but
> poke is doing what its says it is doing:
<<quoted lines omitted: 4>>
> mytuple: poke mytuple 3 88 ; == 1.2.88.4.5
> mytuple ; == 1.2.88.4.5
Well, it is certainly odd, and non-orthogonal. For example, the same Poke on
a Block or an Object does change it:
>> myblock: copy [1 2 3 4 5]
== [1 2 3 4 5]
>> poke myblock 3 99
== [1 2 99 4 5]
>> myblock
== [1 2 99 4 5]
>>
But Poke on a Tuple or Money does not chance the underlying item.
Poke accepts any of these data types: series money date time object port
tuple. If it was orthogonal, I wouldn't have to try each type to see if it
changes the value or not. Any guesses what it does to a Date or a Port?
--Colin.
[7/114] from: gjones05:mail:orion at: 5-Jun-2001 17:35
From: <[Sanghabum--aol--com]>
> Hi Scott,
>
> > One might argue that this description might be worded more clearly,
but
> > poke is doing what its says it is doing:
> >
<<quoted lines omitted: 5>>
> > mytuple ; == 1.2.88.4.5
> Well, it is certainly odd, and non-orthogonal. For example, the same
Poke on
> a Block or an Object does change it:
> >> myblock: copy [1 2 3 4 5]
<<quoted lines omitted: 6>>
> But Poke on a Tuple or Money does not chance the underlying item.
> Poke accepts any of these data types: series money date time object
port
> tuple. If it was orthogonal, I wouldn't have to try each type to see
if it
> changes the value or not. Any guesses what it does to a Date or a
Port?
Your point is well-taken, and needless to say I have no explanation. I
thought I recognized it as being a similar oversite that I had made, but
this one is different. Sorry to dilute the point you were making.
:-)
--Scott Jones
[8/114] from: sanghabum:aol at: 5-Jun-2001 19:41
Hi Scott,
> Your point is well-taken, and needless to say I have no explanation. I
> thought I recognized it as being a similar oversite that I had made, but
> this one is different. Sorry to dilute the point you were making.
> :-)
No worries. I think the only point I was making was that Joel *may* be
mistaking a bug for an esoteric, and hard-to-model, feature.
I don't even have much of a problem knowing Rebol has bugs in it (or
confusing quirk
to use the term Feedback used to describe why "face/data:
copy []" won't clear a VID text-list---you have to write "clear face/data").
All software has bugs, and given the speed the Rebol guys are moving, it's
astounding there are so few....They write quality code with a vengeance!
But I would appreciate (and I know I'm not the first to ask) a bug
list.....I've spent an embarrassing amount of time "debugging" (or stumbling
over) things like Poking a Tuple or clearing a Text-list or DOing a string. A
simple, searchable database of reported problems and known workarounds would
help us all.
--Colin.
[9/114] from: larry:ecotope at: 5-Jun-2001 16:51
Hi Joel
You pose some interesting examples. I agree the implementation of the date
and time datatypes in REBOL are a bit irregular. Just a couple of quick
comments. You wrote:
> Yes, so perhaps /DATE does an implicit copy? How can we tell?
> >> b/time/hour: 9 == 9
<<quoted lines omitted: 20>>
> >> c/time
> == none
Consider this:
>> d: make date! [5 6 2001 19:23:15 -7:0]
== 5-Jun-2001/19:23:15-7:00
So a date can be made from a block containing 3 integers for day, month and
year, consecutively followed by 2 times, the time of day and the time-zone
offset.
>> t: make time! [10 23 17]
== 10:23:17
So a time can be made from a block of 3 integers for hour minute second,
consecutively.
These two things can be combined to deal with the full form of date which
includes time and time-zone.
>> d: poke d 4 poke pick d 4 1 9
== 5-Jun-2001/9:23:15-7:00
>>
or
>> poke d 4 poke d/4 1 10
== 5-Jun-2001/10:23:15-7:00
The individual time fields can be accessed and modified with pick and poke,
but these access functions, including poke (this differs from poke used on
series), return a value rather than modifying the original date, so we have
to reassign the var name.
Regards
-Larry
[10/114] from: lmecir:mbox:vol:cz at: 6-Jun-2001 7:47
Hi Colin,
> No worries. I think the only point I was making was that Joel *may* be
> mistaking a bug for an esoteric, and hard-to-model, feature.
>
> I don't even have much of a problem knowing Rebol has bugs in it (or
> "confusing quirk" to use the term Feedback used to describe why
face/data:
> copy []
won't clear a VID text-list---you have to write "clear
face/data").
> All software has bugs, and given the speed the Rebol guys are moving, it's
> astounding there are so few....They write quality code with a vengeance!
>
> But I would appreciate (and I know I'm not the first to ask) a bug
> list.....I've spent an embarrassing amount of time "debugging" (or
stumbling
> over) things like Poking a Tuple or clearing a Text-list or DOing a
string. A
> simple, searchable database of reported problems and known workarounds
would
> help us all.
>
> --Colin.
I am pretty sure, that the feature you are describing is not a bug. The
reason for the behaviour is pretty simple. Rebol values of type TUPLE! DATE!
INTEGER! and some other types are immutable - Mark Dickson uses the word
constant to express the same feature. What does the strange word mean? No
Rebol function can change these values. Example:
try-to-change1: func [
value [tuple!]
] [
either value = 1.1.1 [value: 1.1.2] [value: 1.1.1]
value
]
a: 1.1.2 ; == 1.1.2
try-to-change1 a ; == 1.1.1
a ; == 1.1.2
As you can see, the function I wrote wasn't able to change the supplied
value, instead it computed a new different value.
How about another function:
try-to-change2: func [
'value [word!]
] [
either (get value) = 1.1.1 [set value 1.1.2] [set value 1.1.1]
get value
]
a: 1.1.2 ; == 1.1.2
try-to-change2 a ; == 1.1.1
a ; == 1.1.1
Here it looks like I succeeded to change the supplied value 1.1.2. In fact I
didn't change the value 1.1.2. I computed a new value 1.1.1 instead and
stored it to the supplied word 'a , which now contains a different value
than before.
the same effect I can achieve using a set-path:
a: 1.1.2 ; == 1.1.2
a/3: 1 ; == 1
a ; == 1.1.1
Regards
Ladislav
[11/114] from: ingo:2b1 at: 5-Jun-2001 22:24
Hi Scott,
well I'd argue, there must be an error somewhere ...
>> a: "000000"
== "000000"
>> poke a 3 #"x"
== "00x000"
>> a
== "00x000"
... strings! are changed ...
kind regards,
Ingo
Once upon a time GS Jones spoketh thus:
[12/114] from: sanghabum:aol at: 6-Jun-2001 5:05
Hi Ladislav,
> I am pretty sure, that the feature you are describing is not a bug. The
> reason for the behaviour is pretty simple. Rebol values of type TUPLE!
DATE!
> INTEGER! and some other types are immutable - Mark Dickson uses the word
> constant to express the same feature. What does the strange word mean? No
> Rebol function can change these values. Example:
<snip>
Bug, feature, or quirk --- any of them are acceptable. But if it is a feature
(and if it is, it's a fairly fundamental one), it would help if the
documentation mentioned it. The users' guide's simply says there are two
fundamental datatypes: scalars and series. We now seem to be discovering each
of these can be mutable or immutable.
That leaves me with a much more complex model of what is going on. Add in the
fact that Poke will operate on a two-part item like Money!, but not on a
two-part item like Pair! and some of the dazzling simplicity starts to slip
away....I now have to remember to use Poke in two different ways:
Poke MyBlock 2 5 ;;--to update a Block
MyTuple: poke MyTuple 2 5 ;; -- to update a Tuple
Plus, I can't use it at all on a Pair, so I need to write:
Mypair/2: 5 ;;-- to update a Pair
Thanks for the analysis,
--Colin.
[13/114] from: joel:neely:fedex at: 6-Jun-2001 7:55
Hi, Colin and Ladislav,
First of all, let me restate my underlying goal: to have a
robust mental model of REBOL that allows one (i.e, me) to
understand what a piece of code does BY READING THE CODE,
and NOT having to depend on "let's try it out and see what
happens". I think it's obvious that the more exceptions one
has to memorize, the more difficult it is to construct and
use such a mental model.
As I don't have time personally to try out all possible REBOL
utterances to observe their effect, I'm grateful when others on
this list provide descriptions of exceptional behavior. I try
to return the favor when possible.
Ladislav Mecir wrote:
> Hi Colin,
>
> > No worries. I think the only point I was making was that
> > Joel *may* be mistaking a bug for an esoteric, and
> > hard-to-model, feature.
> >
Ummmm. I think I need to clarify. I'm not asserting either,
so I don't think I've made a mistaken assertion.
I deliberately avoided the word "bug": in the absence of a
published spec for what REBOL is *intended* to do, all I can
say is, "That's surprising to me!" when I encounter behavior
which I didn't expect.
Of course, I'll be grateful for any explanations that anyone
can offer to reduce my level of surprise in the future! ;-)
> I am pretty sure, that the feature you are describing is not
> a bug. The reason for the behaviour is pretty simple. Rebol
> values of type TUPLE! DATE! INTEGER! and some other types
> are immutable ...
>
Part of my point was that the above assertion is no longer
strictly true (I believe there's been a change at some point),
at least with regard to DATE! values. Comparing
>> a: make date! [2001 6 6] == 6-Jun-2001
>> a/day: 7 == 7
>> a == 7-Jun-2001
with
>> a: make object! [x: 17 y: 42 show: does [print [x y]]]
>> a/show 17 42
>> a/x: 19 == 19
>> a/show 19 42
it seems reasonable to conclude that the first transcript
demonstrates changing a component of a date "in place", which
would mean that DATE! values *are* mutable. However,
>> a: make date! [2001 6 6] == 6-Jun-2001
>> b: a == 6-Jun-2001
>> a/day: 7 == 7
>> a == 7-Jun-2001
>> b == 6-Jun-2001
provides evidence that DATE! is not a "reference" type.
> try-to-change2: func [
> 'value [word!]
<<quoted lines omitted: 12>>
> supplied word 'a , which now contains a different value
> than before.
As you correctly point out, the old value of A has been
*replaced*, and not mutated. But the key to seeing this
(by reading the code and not by trial-and-error) is to
know that the SET operates on A (the value of 'VALUE) and
not on the value of A (the value of the value of 'VALUE).
The same would have applied to any use of A: of course.
> The same effect I can achieve using a set-path:
>
> a: 1.1.2 ; == 1.1.2
> a/3: 1 ; == 1
> a ; == 1.1.1
>
Here our interpretations differ. By analogy with
>> a: make object! [x: 17 y: 42 show: does [print [x y]]]
>> a/show 17 42
>> a/x: 19 == 19
>> a/show 19 42
and with
>> a: [x 6 y 7 z 42] == [x 6 y 7 z 42]
>> a/x == 6
>> a/x: 9 == [x 9 y 7 z 42]
>> a == [x 9 y 7 z 42]
it seems reasonable to understand a SET-PATH! as mutation; it
seems to change an element of a composite structure "in place",
rather than computing and returning a modified copy of the
entire structure.
This is why I found the following behavior to be inconsistent:
>> a: now == 6-Jun-2001/7:49:06-5:00
>> a/date/day: 7 == 7
>> a == 6-Jun-2001/7:49:06-5:00
>> a/day: 7 == 7
>> a == 7-Jun-2001/7:49:06-5:00
The effect of A/DAY: appears to be typical for SET-PATH!
behavior -- a component of the original structure seems to
have been modified in place. However, the effect of A/DATE/DAY:
seems to involve a copy-and-modify behavior that is *NOT*
typical for SET-PATH! expressions.
Hence, an exception that simply must be memorized (at least
until someone provides a more comprehensive mental model of
*why* such an inconsistency is "natural").
-jn-
[14/114] from: joel:neely:fedex at: 6-Jun-2001 9:11
Hi, again,
Minor update to previous message...
Ladislav Mecir wrote:
> I am pretty sure, that the feature you are describing is not a
> bug. The reason for the behaviour is pretty simple. Rebol values
> of type TUPLE! DATE! INTEGER! and some other types are immutable...
>
The oddity I described appears to reside in the /DATE "refinement"
itself, based on this:
>> a: now == 6-Jun-2001/9:05:53-5:00
>> a/date == 6-Jun-2001
>> a/date/date == 6-Jun-2001
>> a/date/date/date/date/date/day == 6
so that /DATE behaves less like a component selector and more like
a function that takes a (complete) DATE! value and returns another
DATE! value with the TIME! component set to none.
-jn-
[15/114] from: gjones05:mail:orion at: 6-Jun-2001 10:13
From: "Joel Neely"
> Hi, again,
> Minor update to previous message...
<<quoted lines omitted: 13>>
> a function that takes a (complete) DATE! value and returns another
> DATE! value with the TIME! component set to none.
I think you are on to something with this hypothesis. I have expounded
on a concept from an earlier post. This gives more proof in the
pudding:
;First, the components of the full date time and zone
a/now ; == 6-Jun-2001/10:04:33-5:00
a/1 ; == 2001
a/2 ; == 6
a/3 ; == 6
a/4 ; == 10:04:33
a/4/1 ; == 10
a/4/2 ; == 4
a/4/3 ; == 33
a/5 ; == -5:00
;Now for just the "date" portion, notice the zone element (#5)?
a: now ; == 6-Jun-2001/10:04:33-5:00
a/date ; == 6-Jun-2001
a/date/1 ; == 2001
a/date/2 ; == 6
a/date/3 ; == 6
a/date/4 ; == none
a/date/5 ; == 0:00
--Scott Jones
[16/114] from: agem:crosswinds at: 6-Jun-2001 17:11
Hi Joel, Colin, Ladislav, Scott
>>>>>>>>>>>>>>>>>> Ursprüngliche Nachricht <<<<<<<<<<<<<<<<<<
Am 06.06.01, 13:55:38, schrieb Joel Neely <[joel--neely--fedex--com]> zum
Thema [REBOL] Re: On mutability and sameness:
> Hi, Colin and Ladislav,
> First of all, let me restate my underlying goal: to have a
<<quoted lines omitted: 7>>
> Of course, I'll be grateful for any explanations that anyone
> can offer to reduce my level of surprise in the future! ;-)
Me too tries it :)
<snip>
> Part of my point was that the above assertion is no longer
<<quoted lines omitted: 11>>
> demonstrates changing a component of a date "in place", which
> would mean that DATE! values *are* mutable. However,
they are
> >> a: make date! [2001 6 6] == 6-Jun-2001
> >> b: a == 6-Jun-2001
<<quoted lines omitted: 6>>
> rather than computing and returning a modified copy of the
> entire structure.
yes
> This is why I found the following behavior to be inconsistent:
> >> a: now == 6-Jun-2001/7:49:06-5:00
<<quoted lines omitted: 7>>
> seems to involve a copy-and-modify behavior that is *NOT*
> typical for SET-PATH! expressions.
It is typical for set-path-expressions. But
> Hence, an exception that simply must be memorized (at least
> until someone provides a more comprehensive mental model of
> *why* such an inconsistency is "natural").
There are scalars and references. References have the behavior
of scalars for copying, but references reference!!
they are like internal telephone-numbers.
So if you copy a telephone-number and copy it for me,
and i call with it, we both call the same person.
Same with references to series or objects.
Scalars are copied, but they are »self-containing«.
If you photocopy me an telephone-number and i paint on the paper,
your paper does not change.
Same with pairs, tuples ..
so if you use a/b/c , rebol gets a/b, copies it, but its a reference!
So changes apply to the same »person« as with the old a/b.
Then it does the-copy/c . You don't notice the copy between.
if you use a/date/day, rebol gets a/date, copies it,
but its a scalar! »self-containing«. So the conection to the original
a/date is lost.
Then with this copy it does the-copy/day.
>> ;scalar copies
>> a: now
== 6-Jun-2001/17:53:46+2:00
>> b: a/date
== 6-Jun-2001
>> b/day: 7
== 7
;different!!
>> a
== 6-Jun-2001/17:53:46+2:00
>> b
== 7-Jun-2001
>> ;reference references, changes the same
>> a: context[date: context[day: 6]]
>> b: a/date
>> b/day: 7
== 7
>> ? a
A is an object of value:
make object! [
date:
make object! [
day: 7
]
]
>> ? b
B is an object of value:
make object! [
day: 7
]
AFAIK Rebol has only the distinction of this two,
so there is not to much to remember?
Check if its a series? Or an object?,
otherwise it should be copied by value.
personal rule is
»self-containing if it fits in ~8 byte and is not like a string«
BTW i think Ladislav creates some confusion with his »immutable«.
I think what he means is: functions get always copies
of their argument. If you pass a reference, you can modify
the same »person« like with the original, »mutable«.
if you pass a scalar, it gets copied..
so a function can not modify this arguments.
BTW poke has to return a copy when poking to scalars,
to avoid an exception.
Pathes on the other hand are not exactly like functions, so they
can modify parts.
Hope this makes sense
> -jn-
-Volker
[17/114] from: lmecir:mbox:vol:cz at: 6-Jun-2001 19:31
Hi Joel,
...snip...
> > I am pretty sure, that the feature you are describing is not
> > a bug. The reason for the behaviour is pretty simple. Rebol
<<quoted lines omitted: 21>>
> >> b == 6-Jun-2001
> provides evidence that DATE! is not a "reference" type.
...snip...
> Here our interpretations differ. By analogy with
> >> a: make object! [x: 17 y: 42 show: does [print [x y]]]
<<quoted lines omitted: 10>>
> rather than computing and returning a modified copy of the
> entire structure.
...snip...
I see, that the only reason why you think, that set-path is a DATE! mutation
instrument is the analogy with the behaviour of set-path for objects. I have
a different POV, because I know, that the behaviour of set-path for objects
nor is analogical to the set-path behaviour for DATE! type values, neither
it was analogical before.
That is why I used a different instrument - my own definition of
mutability/immutability for values, a definition helping me to find out
whether a value has/ hasn't been mutated/altered or not. Here it is:
Let's have a Rebol function F and a DATE! value VALUE. I tell, that F
can mutate i.e. alter VALUE, if the following expression yields true:
do function [
{does F alter VALUE?}
f [any-function!]
value [date!]
] [camera picture] [
camera: func [value [date!]] [
reduce [
type? value
value/1
value/2
value/3
value/4
value/5
]
]
picture: camera value
(f value)
not equal? picture camera value
] :f :value
Moreover, I call a DATE! value immutable, if there isn't a function F able
to mutate it. In this sense all DATE! values are immutable. Just an
illustration:
f: func [value [date!]] [
either value/1 = 2000 [
value/1: 2001
] [value/2: 2000]
]
value: now
the result we get is:
== false
Does this make sense to you?
Regards
Ladislav
[18/114] from: sanghabum:aol at: 6-Jun-2001 14:39
Hi Volker,
> AFAIK Rebol has only the distinction of this two,
> so there is not to much to remember?
> Check if its a series? Or an object?,
> otherwise it should be copied by value.
Thanks for the various examples and explanations.
But I think I'm still with Joel here when it comes to having either a
confused mental model,---or out on my own with a suspicion that the manual
(Core Users' Guide 2.2.0) is wrong, or the code a tad buggy....Tuples are
defined as Series, not Scalars: so, by your explanation, they should be
modifiable.
--Sill puzzled!
--Colin.
[19/114] from: larry:ecotope at: 6-Jun-2001 13:18
Hi Colin
Just a quick comment. Tuples are not series.
>> series? 1.2.3
== false
>> tuple? 1.2.3
== true
I think Volker's overview is a good one.
-Larry
[20/114] from: lmecir:mbox:vol:cz at: 6-Jun-2001 22:16
Hi Volker,
...snip...
> > it seems reasonable to conclude that the first transcript
> > demonstrates changing a component of a date "in place", which
> > would mean that DATE! values *are* mutable. However,
>
> they are
>
try to mutate/alter (i.e. not replace) the first element of BLOCK:
block: [1/1/2001]
Regards
Ladislav
[21/114] from: lmecir:mbox:vol:cz at: 6-Jun-2001 22:38
Hi,
a: now ; == 6-Jun-2001/22:36:26+2:00
b: a ; == 6-Jun-2001/22:36:26+2:00
same? a b ; == true
a/day: 7 ; == 7
same? a b ; == false
provides evidence that the value of 'a has been replaced instead of mutated.
Regards
Ladislav
[22/114] from: gjones05:mail:orion at: 6-Jun-2001 16:03
From: "Ladislav Mecir"
> Hi Volker,
> ...snip...
<<quoted lines omitted: 6>>
> try to mutate/alter (i.e. not replace) the first element of BLOCK:
> block: [1/1/2001]
Hi, Ladislav,
How about this approach? Does this work?
b1: [1/1/2001] ;== [1-Jan-2001]
b2: b1 ;== [1-Jan-2001]
same? b1 b2 ;== true
b1/1/3: 3 ; == 3
b1 ; == [3-Jan-2001]
b2 ; == [3-Jan-2001]
same? b1 b2 ; == true
Cheers,
--Scott Jones
[23/114] from: sanghabum:aol at: 6-Jun-2001 17:34
Hi Larry,
> Just a quick comment. Tuples are not series.
>
> >> series? 1.2.3
> == false
> >> tuple? 1.2.3
> == true
Yes and No......There seem to be two definitions of Series
1. From the User Guide:
Series
Series values hold a sequential collection of elements whether characters
(string!, email!, url!, etc.), integers (tuple!), bits (binary!), or elements
(block!, list!, hash!, etc.).
=====
That makes Tuple a Series by Definition 1.
But:
2. Also from the manual:
Following is the hierarchical classification of REBOL pseudotypes and the
datatypes they identify. Note that all datatypes are identifiable with the
any-type! pseudotype:
any-type
<snip>
series
any-block
block
list
lit-path
hash
paren
path
set-path
any-string
binary
email
file
issue
string
tag
url
symbol
time
tuple
unset
======
Tuple is not a subtype of Series by Definition 2.
Conclusion: Tuple is a Series Datatype but not a a subtype of the Series
Pseudotype. That's almost a tonguetwister.
I still think it's confusing!
> I think Volker's overview is a good one.
So do I. Something of the sort needs to be incorporated in the Guide, or a
FAQ or something.
--Colin.
[24/114] from: agem:crosswinds at: 6-Jun-2001 23:02
>>>>>>>>>>>>>>>>>> Ursprüngliche Nachricht <<<<<<<<<<<<<<<<<<
Am 06.06.01, 21:38:13, schrieb "Ladislav Mecir" <[lmecir--mbox--vol--cz]> zum
Thema [REBOL] Re: On mutability and sameness:
> Hi,
> a: now ; == 6-Jun-2001/22:36:26+2:00
<<quoted lines omitted: 3>>
> same? a b ; == false
> provides evidence that the value of 'a has been replaced instead of
mutated.
Veto!
My POV: same? Checks if two »slots« are »binary« the same.
For references this means »calling the same people«.
For scalars this means the same value.
Of course the value is changed. But in place.
>> a: [ 1 2 3]
== [1 2 3]
>> b: next a
== [2 3]
>> same? a b
== false
>> b: back b
== [1 2 3]
>> same? a b
== true
[25/114] from: agem:crosswinds at: 6-Jun-2001 23:02
>>>>>>>>>>>>>>>>>> Ursprüngliche Nachricht <<<<<<<<<<<<<<<<<<
Am 06.06.01, 22:03:52, schrieb "GS Jones" <[gjones05--mail--orion--org]> zum
Thema [REBOL] Re: On mutability and sameness:
> From: "Ladislav Mecir"
> > Hi Volker,
<<quoted lines omitted: 20>>
> b2 ; == [3-Jan-2001]
> same? b1 b2 ; == true
Hey, Scott, that's unfair. Was just posting that!
Remind me to delete my mail ;-)
[26/114] from: joel:neely:fedex at: 6-Jun-2001 17:00
Hi, Ladislav,
I'm not Volker, but may I play???
Ladislav Mecir wrote:
> try to mutate/alter (i.e. not replace) the first element of BLOCK:
>
> block: [1/1/2001]
>
> Regards
> Ladislav
>
Do you mean something like the following?
>> blk: [1/1/2001] == [1-Jan-2001]
>> blk/1/day == 1
>> blk/1/day: 2 == 2
>> blk == [2-Jan-2001]
Hence my belief that DATE! values now are actually mutable
(sort of).
-jn-
[27/114] from: joel:neely:fedex at: 6-Jun-2001 17:04
Hi, Larry,
Larry Palmiter wrote:
> Hi Colin
>
> Just a quick comment. Tuples are not series.
>
> >> series? 1.2.3
> == false
> >> tuple? 1.2.3
> == true
>
But it is equally inaccurate to assume that they are fixed-size
scalar values, isn't it?
>> foo: 9.8.7.6.5.4.3.2.1.0
== 9.8.7.6.5.4.3.2.1.0
>> repeat i 10 [print foo/:i]
9
8
7
6
5
4
3
2
1
0
-jn-
[28/114] from: larry:ecotope at: 6-Jun-2001 16:07
Hi Joel
> But it is equally inaccurate to assume that they are fixed-size
> scalar values, isn't it?
>
> >> foo: 9.8.7.6.5.4.3.2.1.0
> == 9.8.7.6.5.4.3.2.1.0
> >> repeat i 10 [print foo/:i]
>> foo: 1.2.3.4.5.6.7.8.9.10.11
** Syntax Error: Invalid tuple -- 1.2.3.4.5.6.7.8.9.10.11
Not necessarily, they could be fixed size at 10 bytes (which BTW shows that
Volker's rule of 8 bytes does not hold). The "scalar" types could be tagged
pointers (references) as suggested by Volker. A few bits in the pointer
could designate the type and whether the value is contained within the
pointer. As you probably know this is a common way of implementing "scalar"
types in Scheme. For tuples, there could some bits in the pointer that say
how long the tuple is with a max of 10.
It is interesting to note that when an empty block is created:
>> b: make block! 10000
system/stats shows that 16 bytes of memory have been allocated for each
block element. This might indicate that REBOL "pointers" or "references" are
16 bytes in length. Just a speculation...
Regards
-Larry
PS This is fun too:
>> foo: 1.........
== 1.0.0.0.0.0.0.0.0.0
[29/114] from: larry:ecotope at: 6-Jun-2001 16:46
Hi Colin
> 1. From the User Guide:
>
> Series
> Series values hold a sequential collection of elements whether characters
> (string!, email!, url!, etc.), integers (tuple!), bits (binary!), or
elements
> (block!, list!, hash!, etc.).
>
> > That makes Tuple a Series by Definition 1.
I would say that the description of series you quote is over-simplified and
misleading in a couple of respects:
1) It conflicts with the built-in definition, namely that which returns true
for
series? x
which shows that a tuple is not a series.
2) A binary is an ordered collection of bytes, not bits, because it's length
in bits must be a multiple of 8. The access functions index and return
bytes. It is of the pseudotype any-string! and can be converted directly to
a string of 8 bit bytes with TO-STRING. Unfortunately there is no built-in
conversion function to do the reverse (irregular).
Personally, at the present time, I find it easier to maintain my sanity by
using the built-in type system and REBOLS reflective capabilities to get
working answers to questions when possible. The docs (although invaluable)
are sometimes misleading, often incomplete or outdated, and rarely just flat
out wrong.
I certainly agree that some further explanation from RT on the
implementation of datatypes would be extremely useful. I also agree that
there are "irregularities" in the implementation of some REBOL datatypes and
their associated manipulation functions, which are impediments to a clear
and quick understanding of the language. I heartily support your (and Joels)
efforts to coax some more information from RT about language details. I am
cautiously optimistic that this will happen (but probably not any time
soon).
Regards
-Larry
BTW is the quote above from the REBOL/Core users guide? If so, we should
send feedback a msg to fix it.
[30/114] from: lmecir:mbox:vol:cz at: 7-Jun-2001 11:02
The problem with the proof of DATE! mutability is, that it doesn't work. The
same "proof" could e.g. prove, that integers are mutable:
a: 11
bm [a/1] ; == 1
bm [a/1: 0] ; == 0
a ; == 9
block1: [11]
block2: :block1
bm [block1/1/1] ; == 1
bm [block1/1/1: 0] ; == 0
block1/1 ; == 9
same? block2 block1 ; == true
The bit-manipulation is described below:
bit: func [
i [integer!]
bitno [integer!]
] [
(to integer! i / (2 ** bitno)) // 2
]
bm: function [
block [block!]
] [path part-path integer bitno old-bit new-bit to-add len block-path] [
(path: copy first block)
(block-path: to block! :path)
len: (length? :block-path) - 1
(part-path: to path! copy/part block-path len)
(integer: part-path)
(bitno: last block-path)
(old-bit: bit integer bitno)
either path? :path [
return old-bit
] [
(part-path: load mold to set-path! copy/part block-path len)
(part-path: first bind reduce [:part-path] first :path)
new-bit: second block
if old-bit <> new-bit [
to-add: to integer! 2 ** bitno
if new-bit < old-bit [to-add: - to-add]
part-path integer + to-add
]
new-bit
]
]
[31/114] from: agem:crosswinds at: 7-Jun-2001 10:54
>>>>>>>>>>>>>>>>>> Ursprüngliche Nachricht <<<<<<<<<<<<<<<<<<
Am 07.06.01, 00:07:53, schrieb "Larry Palmiter" <[larry--ecotope--com]> zum
Thema [REBOL] Re: On mutability and sameness:
> Hi Joel
> > But it is equally inaccurate to assume that they are fixed-size
<<quoted lines omitted: 6>>
> ** Syntax Error: Invalid tuple -- 1.2.3.4.5.6.7.8.9.10.11
> Not necessarily, they could be fixed size at 10 bytes (which BTW shows
that
> Volker's rule of 8 bytes does not hold). The "scalar" types could be
tagged
> pointers (references) as suggested by Volker. A few bits in the
pointer
> could designate the type and whether the value is contained within the
> pointer. As you probably know this is a common way of implementing
scalar
> types in Scheme. For tuples, there could some bits in the pointer that
say
> how long the tuple is with a max of 10.
> It is interesting to note that when an empty block is created:
> >> b: make block! 10000
> system/stats shows that 16 bytes of memory have been allocated for
each
> block element. This might indicate that REBOL "pointers" or
references
are
> 16 bytes in length. Just a speculation...
Ok, correction: max slot size 10 byte. Not much different to ~8
(around 8). ;-)
i was speculationg a usual floating point number needs 8 byte,
a pair! 2* 4-byte integer, so 8 sounded good.
Well, with 16 bytes there is space for
1 native pointer/handle(4 bytes)
+ 10 bytes data
+ 2 byte something. some kind of type-description + tuple-length?
i think this would be most simple to implement
> Regards
> -Larry
Regards
-Volker
[32/114] from: joel:neely:fedex at: 7-Jun-2001 8:08
Hi, Ladislav,
Clearly Doug Henning and David Copperfield could use a man of
your talents!
Ladislav Mecir wrote:
> The problem with the proof of DATE! mutability is, that it
> doesn't work. The same "proof" could e.g. prove, that
> integers are mutable:
>
Of course it doesn't, but it was an interesting exercise in
how not to be deceived by the traditional parlor magic devices
of smoke and mirrors. ;-)
You've constructed a complex variation on the following theme:
incr: func ['wd [word!]] [
set :wd 1 + get :wd
]
>> a: 9 == 9
>> incr a == 10
>> incr a == 11
>> incr a == 12
>> a == 12
Of course we all know that INCR is not mutating the integer,
but constructing another integer from the content of A and
then replacing the old content of A with that new one.
We can, of course make this a little more obscure by hiding
the use of SET as follows:
sneaky-incr: func ['wd [word!] /local trick] [
trick: to-set-word :wd
trick (1 + get :wd)
]
>> sneaky-incr a == 13
>> sneaky-incr a == 14
>> sneaky-incr a == 15
>> a == 15
In which TRICK hides the setting of A (or whatever).
Your BM function adds to the above trick the ability to unwind
paths for access into blocks, as well as the *very* nice twist
of binding the constructed set back to the original argument's
context. (Since SNEAKY-INCR doesn't do the BIND, it will fail
when used in the following way
>> a
== 15
>> foo: func [arg /local a] [
[ a: arg
[ sneaky-incr a
[ print [a arg]
[ ]
>> foo 3
3 3
>> a
== 4
as the created set-word tampers with the global context rather
than the context of FOO.)
Nice touch!
...
> bm: function [
> block [block!]
...
> ] [
> (part-path: load mold to set-path! copy/part block-path len)
<<quoted lines omitted: 3>>
> to-add: to integer! 2 ** bitno
> if new-bit < old-bit [to-add: - to-add]
; All of which sets up PART-PATH as a setter, and
> part-path integer + to-add
; has the effect of REPLACING an integer, not MUTATING one.
> ]
> new-bit
> ]
> ]
>
That was a stimulating puzzle!
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[33/114] from: joel:neely:fedex at: 7-Jun-2001 8:23
Hello, Volker,
Volker Nitsch wrote:
> Am 07.06.01, 00:07:53, schrieb "Larry Palmiter"
> <[larry--ecotope--com]> zum
<<quoted lines omitted: 9>>
> > >> foo: 1.2.3.4.5.6.7.8.9.10.11
> > ** Syntax Error: Invalid tuple -- 1.2.3.4.5.6.7.8.9.10.11
You're right. Experiments confirm that ten is the maximum
number of elements in a tuple.
> > The "scalar" types could be tagged pointers (references)
> > as suggested by Volker. A few bits in the pointer could
> > designate the type and whether the value is contained
> > within the pointer. As you probably know this is a common
> > way of implementing "scalar" types in Scheme.
...
> Ok, correction: max slot size 10 byte. Not much different
> to ~8 (around 8). ;-)
<<quoted lines omitted: 6>>
> some kind of type-description + tuple-length?
> i think this would be most simple to implement
Yes. This was what I referred to earlier as a "self-relative
descriptor". That technique has been around since the late
60's. A data value is represented by a descriptor, which
contains type information and a "pointer" to the data.
To save space and time, however, data which can fit into the
pointer
portion of the descriptor are placed there. There
are some variations on this theme. The decision as to where
to allocate the data storage may be determined solely by the
data type (e.g., integer). In this case, such data values
are not "sharable". OTOH, the decision may be deferred, in
which case there is a need for a separate bit in the
descriptor -- the "self-relative" bit -- that indicates whether
the data is inside the descriptor or simply referenced by the
descriptor. In this case, even "small" data values may be
shared.
The behavior we've been exploring is consistent with the idea
that REBOL uses a type-dependent descriptor, and implements
the refinements on DATE! values as special-purpose mutations
on the self-relative value.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[34/114] from: joel:neely:fedex at: 7-Jun-2001 8:47
Hello, all!
Of course, the point of all this discussion of mutability,
representation, etc. is not merely idle speculation. The
goal (at least for me) is to develop the simplest possible
(accurate!) model of REBOL data type behavior.
It must be "simplest" to maximize learnability.
It must be "accurate" to allow correct interpretation and
prediction of the behavior of a piece of REBOL code, based
on reading the code and not by trial-and-error experiment.
So... Here's a revised cut based on what's been said thus
far in this thread.
=============================================================
Class of data SAME?-ness EQUAL?-ity Values
Sample types in class based on based on mutable?
======================== ========== ========== ========
Atomic scalar data value data value no
CHAR!, INTEGER!
Composite scalar data value data value yes, via
DATE!, TIME! refinemts
Built-in reference reference content yes
STRING!, BLOCK! comparison comparison
User-defined reference reference unsupported yes
OBJECT! comparison (always false)
=============================================================
Comments, changes, corrections welcome.
Next step -- place all REBOL data types at the correct spot in
the above table.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[35/114] from: agem:crosswinds at: 7-Jun-2001 18:57
Hello Joel
>>>>>>>>>>>>>>>>>> Ursprüngliche Nachricht <<<<<<<<<<<<<<<<<<
Am 07.06.01, 14:23:11, schrieb Joel Neely <[joel--neely--fedex--com]> zum
Thema [REBOL] Re: On mutability and sameness:
> Hello, Volker,
> Volker Nitsch wrote:
<<quoted lines omitted: 56>>
> the refinements on DATE! values as special-purpose mutations
> on the self-relative value.
ah! thanks for another part for my lexicon :-)
it's nice to have a more »sound« definition than my
»hm, this piece is here and that's there«
which makes my talking somtimes hard ;-)
Thanks.
> -jn-
Volker
[36/114] from: agem:crosswinds at: 7-Jun-2001 18:57
>>>>>>>>>>>>>>>>>> Ursprüngliche Nachricht <<<<<<<<<<<<<<<<<<
Am 07.06.01, 14:47:15, schrieb Joel Neely <[joel--neely--fedex--com]> zum
Thema [REBOL] Re: On mutability and sameness:
> Hello, all!
> Of course, the point of all this discussion of mutability,
<<quoted lines omitted: 18>>
> OBJECT! comparison (always false)
> =============================================================
and suddenly i see a clear picture of what i was trying
to explain. Wonderfull!
hm, maybe we should put the need for [new: copy []] somewhere in?
its redundant with data/reference, but fits somehow?
just an idea.
> Comments, changes, corrections welcome.
> Next step -- place all REBOL data types at the correct spot in
> the above table.
have done [help datatype!] already.
now putting this in a block with 1/2/3/4 for type.
then some dump-routine.. /view or <html> ?
> -jn-
-Volker
[37/114] from: agem:crosswinds at: 8-Jun-2001 11:53
Hi Joel and all
>Next step -- place all REBOL data types at the correct spot in
>the above table.tryied to sort
tried that a bit. with some /view around it ;-)
Comments & Corrections welcome :)
-Volker
the code:
[REBOL [title: {describe behavior of types as arguments}]
;protect-system
;???: func ['word value] [ print [mold :word " : " mold :value]
word :value]
/do [
echo %echo.txt
help datatype!
echo none
]
colors1: reduce [beige orange gold cyan]
special-color: red
legend: [origin 0x0 size 500x480 backdrop white
style tta tt as-is 500
tta {
=============================================================
Class of data SAME?-ness EQUAL?-ity Values
Sample types in class based on based on mutable?
======================== ========== ========== ========
}
tta black (colors1/1) {1 Atomic scalar data value
data value no
CHAR!, INTEGER!
}
tta black (colors1/2) {2 Composite scalar data value
data value yes, via
DATE!, TIME! refinemts
}
tta black (colors1/3) {3 Built-in reference reference
content yes
STRING!, BLOCK! comparison comparison
}
tta black (colors1/4) {4 User-defined reference reference
unsupported yes
OBJECT! comparison (always false)
}
tta black red
{>= 5 special effects like getting executed without [:word].
not well sorted yet.
5 like 3, references, but gets executed
6 even more special, error! pseudo like any-word!, ..
7 don't know behavior yet
8 special, don't know behavior yet
9 words are like atoms, but
there is an assosiated value accessible
which makes words a special kind of reference
pathes are a mystrious thing, mix of series, words and functions.
}
tta black {
=============================================================
}
]
types: [
action! 5 {}
any-block! 3 {any-}
any-function! 5 {any-}
any-string! 3 {any-}
any-type! 6 {any-}
any-word! 6 {any-, can be execute (set-word!)}
binary! 3 {}
bitset! 7 {have to check ops}
block! 3 {}
char! 1 {}
datatype! 1 {base for to}
date! 2 {}
decimal! 1 {}
email! 3 {}
error! 8 {throws itself, needs tests}
event! 8 {needs tests}
file! 3 {}
function! 5 {}
get-word! 9 {}
hash! 3 {}
image! 3 {}
integer! 1 {}
issue! 3 {}
library! 6 {/pro special}
list! 3 {}
lit-path! 6 {transforms to path after assignment. always?}
lit-word! 6 {transforms to word after assignment. always?}
logic! 1 {}
money! 1 {a/2: 3 sets full value!}
native! 5 {but no parts-access}
none! 1 {well, type too..}
number! 1 {any-}
object! 4 {}
op! 5 {exceptional argument-access}
pair! 2 {}
paren! 5 {a execute-block}
path! 5 {}
port! 3 {95% sure}
refinement! 9 {}
routine! 5 {/pro special}
series! 3 {any-, can be execute with paren!}
set-path! 6 {}
set-word! 6 {}
string! 3 {}
struct! 7 {/pro}
symbol! 7 {whats that?}
tag! 3 {}
time! 2 {}
tuple! 2 {}
unset! 6 {}
url! 3 {}
word! 9 {}
]
cnt: 0
view center-face layout [
across
panel legend
cl: list 400x480 [
style tx text
across tx 120x18 tx 12 tx 240
] supply [
count: count + cnt
face/text: face/color: none
offset: count - 1 * 3
if none? pick types offset + 3 [return]
face/color: any [pick colors1 pick types offset + 2
special-color]
face/text: mold pick types offset + index
]
sl: slider cl/size * 0x1 + 16x0 [
c: to-integer ((1 / 3 * length? types) - (480 / 19) *
value)
if cnt <> c [cnt: c show cl]
]
return
]
]
[38/114] from: holger:rebol at: 12-Jun-2001 9:05
On Wed, Jun 06, 2001 at 09:11:00AM -0500, Joel Neely wrote:
> The oddity I described appears to reside in the /DATE "refinement"
> itself, based on this:
<<quoted lines omitted: 5>>
> a function that takes a (complete) DATE! value and returns another
> DATE! value with the TIME! component set to none.
Yes, but, by definition, the date component of a date! value is
another date! value, so /date returns what it is supposed to. REBOL
does not use different datatypes for "date without time" and "date
with time". They are both of type date!.
--
Holger Kruse
[holger--rebol--com]
[39/114] from: sanghabum:aol at: 12-Jun-2001 19:05
Hi Larry,
Colin:
> > 1. From the User Guide:
> >
<<quoted lines omitted: 4>>
> > (block!, list!, hash!, etc.).
<snip>
Larry:
> I would say that the description of series you quote is over-simplified and
> misleading in a couple of respects:
<snip>
> BTW is the quote above from the REBOL/Core users guide? If so, we should
> send feedback a msg to fix it.
I'd agree it was misleading. Certainly it mislead me. The quote was from the
Users' Guide 2.2.0. The latest version is 2.3 and does not define 'Series to
include 'Tuples.
They've put a lot of work into 2.3, and it is a great improvement over 2.2. I
wish I'd noticed it earlier....Maybe there should be a /documentation
refinement to 'Update.
'Poke still needs some clarification. It is described in 2.3 as "similar to
'Change". But Change is clearly limited to 'Series while 'Poke works on
'Tuples and 'Money and other things. But (from the various discussions over
the past weeks) we now know that 'Poke updates a 'Series in place but not a
non-series item. I'll copy this to Feedback as a documentation request.
Sorry for the delay in replying,
--Colin
[40/114] from: joel:neely:fedex at: 12-Jun-2001 23:48
Hi, Ladislav,
Ladislav Mecir wrote:
> Hi Joel,
>
> I see, that the only reason why you think, that set-path
> is a DATE! mutation instrument is the analogy with the
> behaviour of set-path for objects.
>
That's not the only reason. Rather, it is by analogy with the
behavior for paths and set-paths for all other "data-like" uses
(by which phrase I am excluding functions with refinements).
To illustrate ...
... with an object:
>> a: make object! [x: 17 y:42]
>> a/x == 17
>> a/x: 19 == 19
>> b: a
>> b/x == 19
... with a block (by position):
>> a: [2 3 5 7 9 11 15 17 19] == [2 3 5 7 9 11 15 17 19]
>> a/7 == 15
>> a/7: 13 == [2 3 5 7 9 11 13 17 19]
>> a == [2 3 5 7 9 11 13 17 19]
... with a block (by association):
>> a: [fee "a" fie "b" foe "d"] == [fee "a" fie "b" foe "d"]
>> a/foe == "d"
>> a/foe: "c" == [fee "a" fie "b" foe "c"]
>> a == [fee "a" fie "b" foe "c"]
... with a tuple:
>> a: 5.4.6.2.1 == 5.4.6.2.1
>> a/3 == 6
>> a/3: 3 == 3
>> a == 5.4.3.2.1
In all of the above cases, the simplest and most natural model
I can think of is that:
1) a path provides access to a component of a composite data
item, and
2) the corresponding set-path modifies that same component of
the composite value, without modifying (or copying) the
other components. (That's mutation, in my book!)
Although the implementation details of all four examples above
are likely to be different internally, the higher-level
meaning (access to, and modification of, a component) is the
same.
Therefore, I find that the simplest and most natural explanation
of the following:
>> a: 21:18:17 == 21:18:17
>> a/minute == 18
>> a/minute: 28 == 28
>> a == 21:28:17
is that the MINUTE component of a time has been accessed and
modified. How else can we explain the fact that afterwards all
of the other components of A have the same value as previously?
I suppose we *could* try to explain it by imagining that
a/minute: 28
asks the interpreter to exhibit the following behavior:
- Determine that A/MINUTE: is a SET-PATH!
- Get the value of A
- Determine that it is a TIME! value
- Look ahead to see that the "affected" component
is the MINUTE part
- Create a new time value by:
- Copying the HOUR part of A's value to the HOUR part
of the new TIME! value (since we're only "affecting"
the MINUTE part)
- Placing 28 in the MINUTE part of the new TIME! value
(since we're only "affecting" the MINUTE part)
- Copying the SECOND part of A's value to the SECOND
part of the new TIME! value (since we're only
"affecting" the MINUTE part)
- Replace the (entire!) old value of A with the new TIME!
value just created
I have yet to see any reason to imagine such a complicated
meaning, especially since the simpler one (change the MINUTE
part of A's value "in place") adequately predicts the observed
behavior. Let's not forget Occam's razor!
To anyone who is bothered by the following:
>> a: 21:18:17 == 21:18:17
>> b: a == 21:18:17
>> a/minute: 28 == 28
>> a == 21:28:17
>> b == 21:18:17
I would point out that (unlike series or object values) TIME!
values are represented "directly", rather than "indirectly"
(by reference).
Evaluating
b: a
causes B to be set to a copy of whatever A is currently set to.
In this case, it is the entire TIME! value. It is important
to realize that exactly the same meaning applies in this case:
>> a: [21 18 17] == [21 18 17]
>> b: a == [21 18 17]
>> a/2: 28 == [21 28 17]
>> b == [21 28 17]
(even though the effect appears to be different), because A
is not set to "the series itself", but rather is set to "a
reference to the series". Therefore, evaluating
b: a
causes B to be set to a copy of *the*reference* to which A
is currently set.
> That is why I used a different instrument - my own definition
> of mutability/immutability for values, a definition helping me
> to find out whether a value has/ hasn't been mutated/altered
> or not.
>
I'm afraid your instrument is the problem. It is testing for
mutable-by-a-function
instead of simply "mutable". In my
world those are not the same thing.
> Here it is:
> Let's have a Rebol function F and a DATE! value VALUE. I tell,
<<quoted lines omitted: 21>>
> Moreover, I call a DATE! value immutable, if there isn't a
> function F able to mutate it.
There's the problem.
> In this sense all DATE! values are immutable. Just an
> illustration:
>
> f: func [value [date!]] [
> either value/1 = 2000 [
> value/1: 2001
> ] [value/2: 2000]
; Here I assume you meant [value/1: 2000] but that's not
; the problem
> ]
> value: now
>
> the result we get is:
>
> == false
>
Of course we do! REBOL passes arguments using what is normally
termed "call-by-value". That means that F gets (and operates
on) a copy of VALUE, which leaves VALUE unaffected. I believe
that your definition/test conflates two issues:
1) Whether DATE! values can be mutated, and
2) Whether we can pass a "reference" to a DATE! value as an
argument to a function.
If (as I believe to be the case) DATE! values are mutable, but
are not represented via references, then the answer to (1) is
yes
but the answer to (2) is "no". Therefore your test will
always return FALSE for functions that take DATE! arguments.
Back when I was teaching comparative programming languages, one
of the standard "booby-trap" questions was this:
If a programming language (e.g., C) only provides
call-by-value argument passing, how can you write a
function that modifies a data structure that is
external to that function?
The simplest answer, of course, is to write a function whose
(by-value) argument is a pointer to the data structure. (One
could also use a handle, etc...) How can we get that effect
in REBOL? Let me first restate the model from an earlier post
in this thread:
=============================================================
Class of data SAME?-ness EQUAL?-ity Values
Sample types in class based on based on mutable?
======================== ========== ========== ========
Atomic scalar data value data value no
CHAR!, INTEGER!
Composite scalar data value data value yes, via
DATE!, TIME! refinemts
Built-in reference reference content yes
STRING!, BLOCK! comparison comparison
User-defined reference reference unsupported yes
OBJECT! comparison (always false)
=============================================================
Combining the above remarks, the quoted model, and Holger's
remarks of this afternoon, we get
"direct" = "scalar" = "simple" = "small"
in contrast with
"indirect" = "reference" = "more complex" = "variable size"
When we pass a DATE! or TIME! to a function, we're actually
passing a copy of the value, because those data types are in
the direct/scalar/simple/small category.
When we pass a series or object to a function, we're actually
passing a (copy of a) *reference* to that series or object.
I shudder to say it, but essentially we're "getting the pointer
for free".
That's why your test always seems to fail. DATE! and TIME!
values are mutable, but passing one of those types to a function
will cause copying to occur *before* the function can perform
any mutation, and the mutation is made upon the copy. The
only ways around this are:
1) to construct a "pseudo-reference" by embedding the date in
a reference-type value, and then passing that to the
function, or
2) to modify your test to allow an in-line expression instead
of insisting on function evaluation only.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[41/114] from: joel:neely:fedex at: 13-Jun-2001 0:16
Hi, Ladislav,
Ladislav Mecir wrote:
> Hi,
> a: now ; == 6-Jun-2001/22:36:26+2:00
<<quoted lines omitted: 4>>
> provides evidence that the value of 'a has been replaced
> instead of mutated.
Or else it simply provides evidence that DATE! values are
not sharable (i.e., DATE! is not a reference type)!
This seems to be at the root of your desire to call DATE!
and TIME! values immutable.
I believe the following model to be simpler:
1) For reference types, the datum associated with a word
(the value to which it is "set") is a reference to the
data value, not a copy of the data itself. This means
that multiple words can "name" or "share" the same
referenced data.
2) For simple/scalar/direct/small/nonreference data types,
the datum associated with a word is a copy of the data
value itself. This means that values of these types
cannot be "shared" in the same way as reference types.
(However, if these data values are located within more
complex data structures which themselves are shared,
then it becomes possible to traverse alternate paths
which arrive at the same nonreference value. In such
cases, a modification to the value (if it is mutable)
will be visible through all such "computed" references.)
For example, in:
>> b: []
== []
>> insert b now
== []
>> a: reduce ['then "whatever" 'jetzt b]
== [then "whatever" jetzt [13-Jun-2001/0:08:19-5:00]]
>> o: make object! [x: 42 y: copy a]
>> o/y/jetzt/1/month: 7
== 7
>> b
== [13-Jul-2001/0:08:19-5:00]
the simplest explanation is that the MONTH field of a DATE!
value was changed. I know of no motivation for making it any
more complicated than that.
But, "What about SAME?", one might ask.
If SAME? is implemented simply by comparing one "datum" with
another "datum", then:
1) for reference types, SAME? tests whether the two values
(reference!) refer to a common, shared data structure, but
2) for simple/scalar/direct/small data types, SAME? only
tests whether the two values are currently equal.
Simple.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[42/114] from: joel:neely:fedex at: 13-Jun-2001 0:48
Hi, Holger,
Just to clarify, since I apparently wasn't clear initially...
Holger Kruse wrote:
> ... by definition, the date component of a date! value is
> another date! value, so /date returns what it is supposed
> to.
>
I understand what it does, and wasn't suggesting that it was
in error. Just that it looked funny.
> REBOL does not use different datatypes for "date without
> time" and "date with time". They are both of type date!.
>
But isn't this the only case in which a "component" of a
complex (non-atomic) data type is of the same type as its
container
with unbounded descent? In all other cases,
extracting a component gets something that is (in some well-
defined sense) simpler than the whole with which one started.
(Of course, I'm speaking of built-in types... One can always
build pathological self-referential structures such as
>> pathology: [1 2] == [1 2]
>> insert/only next pathology pathology == [2]
<<quoted lines omitted: 3>>
>> pathology/2/2/2/1 == 1
>> pathology == [1 [...] 2]
Kudos to whomever implemented the infinite-recursion-bailout
evidenced by the last line above!)
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[43/114] from: joel:neely:fedex at: 13-Jun-2001 9:19
Hi, Ladislav,
Have read it.
Ladislav Mecir wrote:
> I have got nothing against Occam's razor. But don't forget
> the way how modern microprocessors manipulate bits in the
> main memory, although they normally can read and write only
> bigger chunks of information.
>
I haven't (I just haven't wanted to descend to that level of
detail in this thread). But since you bring it up... ;-)
Don't forget that modern processors can also manipulate bits
in registers, despite the fact that there's no way (for many
CPU architectures) to have a pointer to a register in the
same way that one can have a pointer to a memory address.
By my use of the term, such a register can still be mutable.
By your usage, it could not be.
I truly believe that the concept of whether a value (all by
itself!) is mutable is a *different* issue from whether one
can have a pointer/reference to that value. Your definition
and test cases all hinge on entangling those two issues.
Since we're down at the level of hardware implementation, I
can give examples of all combinations of mutability and (for
lack of a better term) "referrability" (capable of being
accessed via a pointer/handle/reference).
"Referrable" "Non-referrable"
Immutable ROM data, output CPU status data (hardware
registers of ID on some CPUs), overflow
some memory-mapped bits, etc.
controllers
Mutable RAM data, control CPU registers, I/O ports
registers of some on some CPUs
memory-mapped
controllers
> Yes, our points of view differ here. The reason is simple:
> noone of us succeeded to give a simple definition of
> Mutability until now.
>
It seems to me that "capable of having one part changed
without affecting the remaining parts" is a pretty simple
definition. That's the one I use, and it seems to describe
>> a: now == 13-Jun-2001/8:03:15-5:00
>> a/day: 15 == 15
>> a == 15-Jun-2001/8:03:15-5:00
quite adequately. I have yet to see any discussion of why
that wouldn't be the case, that didn't drag in the separate
issue of whether the value of A is sharable (e.g., by some
sort of reference).
> You may dislike it ...
>
Not dislike, just disagree, for the reasons stated above.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[44/114] from: chris:starforge:demon at: 13-Jun-2001 15:38
Joel Neely wrote:
> "Referrable" "Non-referrable"
>
> Immutable ROM data, output CPU status data (hardware
> registers of ID on some CPUs), overflow
> some memory-mapped bits, etc.
> controllers
I'd disagree with the overflow bits etc - on some CPUs (certainly
ARM, I think PPC) it is possible to not only directly view the
status registers but to alter the state of the bits they contain
under program control (not as side-effects of other instructions,
but directly).
Just playing devil's advocate ;)))
Chris
[45/114] from: joel:neely:fedex at: 13-Jun-2001 11:30
Hi, Chris,
Chris wrote:
> Joel Neely wrote:
> > "Referrable" "Non-referrable"
<<quoted lines omitted: 8>>
> under program control (not as side-effects of other instructions,
> but directly).
I mis-parenthesized... I meant the "some CPUs" to qualify all of
the various examples since (as you pointed out) it varies across
different architectures.
> Just playing devil's advocate ;)))
>
By all means, play away!
-jn-
--
___ ___ ___
\/ 2 + \/ 2 = 4 (for sufficiently large approximations of \/ 2 )
joel'dot'neely'at'fedex'dot'com
[46/114] from: lmecir:mbox:vol:cz at: 14-Jun-2001 9:00
Hi Joel,
your posts are thought-provoking as always. :-)
...snip...
> It seems to me that "capable of having one part changed
> without affecting the remaining parts" is a pretty simple
> definition. That's the one I use,
...snip...
I will "play" with your definition. My plan is to get a Special Rebol word:
word-root: "pi"
block: to block! word-root ; == [pi]
special? first block ; == true
; now I would like to make a change
; that wouldn't change the Root attribute of the word,
; but changes its Context attribute:
bind block 'system ; == [pi]
; I succeeded to leave the root of the word unchanged
; did I succeed to change the Context of the word?
special? first block ; == false
How does your definition apply to this case?
Regards
Ladislav
just in case you wanted to play with it too, here is the SPECIAL? function:
special?: func [
{determines, if a Word is a Special Word}
word [any-word!]
] [
error? try [error? get/any :word]
]
[47/114] from: joel:neely:fedex at: 14-Jun-2001 11:56
Hi, Ladislav,
Let me guess... As a child, you always insisted on jumping in at
the deep end of the pool, instead of wading in from the shallow end,
right? ;-)
Your post, as usual, inspired me to think of all sorts of interesting
experiments and follow-on questions. To avoid boring everyone with
most of my thoughts until I have baked them past the halfway point,
I'll defer most of those rambling discussions. However, for the sake
of clarification, let me raise a couple of them now.
1) A question: Given the transcript below:
>> block-o-words: to-block "pie" == [pie]
>> pie: "apple" == "apple"
>> append block-o-words [pie] == [pie pie]
>> do func [n /local pie] [
[ pie: n
[ append block-o-words [pie]
[ ] 17 == [pie pie pie]
>> get second block-o-words == "apple"
>> get third block-o-words == 17
>> print block-o-words
** Script Error: pie is not defined in this context
** Where: halt-view
** Near: pie pie pie
would you say that BLOCK-O-WORDS contains three words whose names
are all spelled the same, or would you say that BLOCK-O-WORDS
contains three occurrences of a word with a different context
attribute on each?
2) You've done some interesting of "particle physics" yourself,
as documented in the essays on your web site. I do feel
compelled to make a distinction between inferences (however inspired
or inspiring) about REBOL details versus clearly-documented features
of REBOL.
You've inferred/postulated that WORD! values have attributes that
could be called "type", "root", "context", and "stored value"
On the other hand, the REBOL documentation clearly states that (for
example) TIME! values have HOUR, MINUTE, and SECOND components.
REBOL provides explicit interfaces for accessing and (at least in
my model ;-) modifying those components. They are, of course:
access modification
------- ------------
/hour /hour:
/minute /minute:
/second /second:
With that said, I'm much more confident about making inferences and
interpretations based on documented features than I am about basing
inferences on top of other inferences.
3) Since you interpret "stored value" as an attribute of a word,
would you consider the following fragment as "changing an
attribute of" the word?
a: 17
a: 42
-jn-
___ ___ ___
\/ 2 + \/ 2 = 4 (for sufficiently large approximations of \/ 2 )
joel'dot'neely'at'fedex'dot'com
[48/114] from: lmecir:mbox:vol:cz at: 15-Jun-2001 1:49
Hi,
> Let me guess... As a child, you always insisted on jumping in at
> the deep end of the pool, instead of wading in from the shallow end,
> right? ;-)
sometimes :-)
> Your post, as usual, inspired me to think of all sorts of interesting
> experiments and follow-on questions. To avoid boring everyone with
<<quoted lines omitted: 19>>
> contains three occurrences of a word with a different context
> attribute on each?
Mainly a terminological difference. I don't think, that e.g. RT could help
us with this. For me (trying to follow the Rebol behaviour if possible) the
words aren't the same. I would rather say, that BLOCK-O-WORDS contains three
words, whose "names" (or ROOT attributes, because they are attributes of
Rebol words) are equal.
> 2) You've done some interesting of "particle physics" yourself,
> as documented in the essays on your web site. I do feel
> compelled to make a distinction between inferences (however inspired
> or inspiring) about REBOL details versus clearly-documented features
> of REBOL.
clearly-documented features wouldn't have been discussed (or at least not
extensively)
> You've inferred/postulated that WORD! values have attributes that
> could be called "type", "root", "context", and "stored value"
except for the fact, that the Special words don't have the "stored value"
attribute
> On the other hand, the REBOL documentation clearly states that (for
> example) TIME! values have HOUR, MINUTE, and SECOND components.
where?
> REBOL provides explicit interfaces for accessing and (at least in
> my model ;-) modifying those components. They are, of course:
<<quoted lines omitted: 6>>
> interpretations based on documented features than I am about basing
> inferences on top of other inferences.
Now I think I know what you are after. The central notion of your approach
is SHARABILITY, while the central notion of my description is MUTABILITY.
The interesting thing is, that there is a simple way how to translate
between them. Where is the difference?
My POV: According to Rebol, values can be the same. If the values are the
same for Rebol, they are the same for me, i.e. they are one value. If I use
this approach, I know, that Rebol values are sharable, because:
a: 12:30
b: a
same? a b ; == true
Thus, all Rebol values are sharable for me ('a and 'b are sharing the same
time value). It is the Observation #1 in my
http://www.sweb.cz/LMecir/evaluation.html . If this is the case, then the
set-path expression:
a/hour: 13
can't mutate the time value, because the value is shared and the mutation
isn't visible everywhere. This approach isn't in contradiction with any fact
you can find in the documentation. Neither it is in contradiction with the
behaviour of the SAME? function as described above.
Your POV: When I see the expression:
a/hour: 13
, I am not able to admit, that it may have been a replacement. (-:What about
the BM dialect bm [a/0: 1]? - that's what Ladislav would have said, oops, it
shouldn't have been here:-) Then I must say, that the observed change has
been a mutation. According to that, the time values aren't sharable,
otherwise we would have seen the mutation when we looked at 'b. This leads
to another conclusion: SAME? lies a bit, when it says we are sharing values.
We are not, we have copies sometimes. There is a problem: what does SAME?
say then?
************************************************************
Here's a little dictionary containing some basic notions:
Ladislav's notion <=> Joel's notion
----------------------------------------------------------------------------
----
Sharability
(all Rebol values are sharable) <=> no translation, trivial notion
Changeable Attribute <=> Sharable Attribute
Mutable Value <=> Value With At Least One Sharable Attribute (Sharable
Value)
Immutable Value <=> Value With No Sharable Attribute (Non-sharable Value)
no definite translation <=> Mutable Value
no definite translation <=> Immutable Value
no definite translation <=> Mutation
no definite translation <=> Replacement
**************************************************************
Now I can translate the main result on sameness contained in
http://www.sweb.cz//LMecir/evaluation.html to your dictionary:
Two equal values having equal types are the same (for the Rebol
interpreter), if they are Non-sharable, or if they share at least one
attribute.
> 3) Since you interpret "stored value" as an attribute of a word,
> would you consider the following fragment as "changing an
> attribute of" the word?
a: 17 ; == 17
a: 42 ; == 42
I would like to explain it more extensively. I see a change. Some Rebol
properties are more understandable, if we are able to classify the changes.
Let's try to classify the above change:
The first point of view is, that I consider the integer value 17 as a
subject of the change. Then I can say, that the integer value 17 got
replaced by another value 42. Observed as a change of the integer value, the
above change is a replacement.
If I observe the same change as a change of the word 'a, I get to a
different conclusion. The word hasn't been replaced, it has been mutated.
Now the full classification: the observed change is a mutation of the word
'a, which changed (namely replaced) its stored value attribute, which was an
integer.
> -jn-
> ___ ___ ___
> \/ 2 + \/ 2 = 4 (for sufficiently large approximations of \/ 2 )
>
> joel'dot'neely'at'fedex'dot'com
Ladislav
(comparative Rebolist)
[49/114] from: joel:neely:fedex at: 15-Jun-2001 2:02
Hi, again, briefly (long day today...)
Ladislav Mecir wrote:
> > 1) A question: Given the transcript below:
> >
<<quoted lines omitted: 22>>
> that BLOCK-O-WORDS contains three words whose "names" ...
> are equal.
So would I. In that case, I'd say that
word-root: "pi"
block: to block! word-root ; == [pi]
bind block 'system ; == [pi]
is mutating BLOCK by replacing the word which is its only
element with a different word.
> > On the other hand, the REBOL documentation clearly states
> > that (for example) TIME! values have HOUR, MINUTE, and
> > SECOND components.
>
> where?
>
REBOL/Core User Guide Version 2.3, page 2-2 and pages A-71
through A-76 (although RCUG uses the term "fields" instead
of the term "components", I assume we agree that the meaning
is the same).
> Now I think I know what you are after. The central notion of
> your approach is SHARABILITY, while the central notion of my
> description is MUTABILITY.
>
The central notion of my approach is that sharability and
mutability are distinct issues. (Although I can't think of
any sharable immutable types in REBOL, the concept is well-
established in other languages, e.g. the Java string type.)
>From my perspective, the central distinction is that your
approach integrates those two issues.
> The interesting thing is, that there is a simple way how to
> translate between them. Where is the difference?
>
I must confess I didn't follow all of the description of how
you perceived the differences in our perspectives. Let me
try to describe it the way I see it, and tell me if this
makes sense to you.
I believe that you and I are building models to answer the
same puzzle: how do we explain what is going on with these
similar-looking cases?
>> b1: [23 34 45] == [23 34 45]
>> b2: b1 == [23 34 45]
<<quoted lines omitted: 7>>
>> b2 == [22 34 45]
>> b3 == [23 34 45]
; Question 1: Why did the value for B2 change?
>> same? b1 b2 == true
>> same? b1 b3 == false
<<quoted lines omitted: 4>>
>> same? t1 t2 == true
>> same? t1 t3 == true
; Question 2: Why does SAME? T1 T3 evaluate to TRUE ?
>> t1/hour: 22 == 22
; Question 3: What just happened?
>> t1 == 22:34:45
>> t2 == 23:34:45
>> t3 == 23:34:45
; Question 4: Why didn't the value of T2 change?
>> same? t1 t2 == false
>> same? t1 t3 == false
>> same? t2 t3 == true
; Question 5: Why are T1 and T2 now not SAME? when
; formerly they were?
>> t4: to-time reduce [2 * 11 + 1 3 * 11 + 1 4 * 11 + 1]
== 23:34:45
>> same? t3 t4 == true
; Question 6: How did REBOL figure out that T3 and T4
; are the SAME? value?
The differences in our models arise from the difference in
what each of us assumes as a basis, and what each of us
consequently must explain in a less intuitive fashion.
MY MODEL:
a) All set-path expressions cause something to be mutated.
The "something" is identified by the set-path up to the
last #"/" and which part of that "something" is identified by
what follows the last #"/". Any such "something" is mutable.
b) A scalar (Holger's "simple") value is stored directly,
represented by the data value itself. A reference value
is stored indirectly, with a reference to the data which is
stored elsewhere. This is true whether we're talking about
a value "in" a variable or "in" a data structure (block,
object, etc.)
c) Since a reference can be duplicated without duplicating
whatever it refers to, reference values can be shared.
Since there are no references for scalar values, they cannot
be shared.
d) Independently-constructed reference values (blocks, strings,
etc.) may be EQUAL? in that they have equivalent content,
but they are not the SAME? values. When a block is constructed,
REBOL doesn't have to search all of memory to see whether there
is already a block in existence with that content; it can just
build it. Therefore, EQUAL? and SAME? are not identical.
Therefore, I have to answer the questions in the puzzle above
in the following way:
1) The value for B2 changed because both B1 and B2 refer to
the same data value (block). Using either reference to
modify the data creates a change visible through both.
2) The SAME? test for reference types compares the references
(an identity test); the SAME? test for scalar types compares
the data values (an equivalence test; there are no references).
Therefore, for scalar types, SAME? and EQUAL? behave
identically.
3) The HOUR component of the data value for T1 was altered.
4) The value of T2 didn't change because it is an independent
scalar value from T1 (whose data value *was* altered).
5) Same answer as for Question 2 -- scalar SAME? compares the
data values, which are no longer equivalent (or EQUAL? for
that matter).
6) Same answer as for Question 2 -- scalar SAME? compares the
data values, regardless of how those data values were
computed.
NOTE: It doesn't bother me that SAME? is implemented in a
different way for scalar types and reference types; after all,
EQUAL? is a simple test for INTEGER! values, a fairly simple
loop for STRING! values, and a much more complex (potentially
recursive) process for BLOCK! values.
YOUR MODEL:
It seems to me that your model starts with the assumption that
all values are sharable and that SAME? is always an identity
test.
This forces you to answer the questions as follows:
1) The value for B2 changed because SAME? B1 B2 was TRUE, so
whatever happens to one happens to the other.
2) There can be only one occurrence of the TIME! value of
23:34:45 and it is shared among all TIME! value references.
Therefore, REBOL must have somehow discovered that this value
was already in use and set T3 to refer to the same TIME! value
as T1 and T2.
3) A new TIME! value was constructed using the value following
the set-path for the HOUR, but using the MINUTE and SECOND
components from the TIME! referred to by T1. Then T1 was set
to refer to that newly-constructed value. In other words,
t1/hour: 22
must be understood as an abbreviation of
t1: make time! reduce [22 t1/minute t1/second]
In fact, all set-path expressions for "simple" types must be
understood as analogous abbreviations to the above (although
the retained/replaced content will vary with type. This is
different from set-paths for non-"simple" types, which may
still be understood as changing only a part of an unreplaced
whole.
4) Because the value of T1 was *replaced* and not *modified*.
5) Because of the answers to (3) and (4); although T1 and T2
were previously sharing a value, they no longer do so
because T1's value was replaced.
6) Some unspecified mechanism must be used to search all data
(or at least all existing TIME! values) in memory to see if
the new value for T4 already exists. Since it does, and is
referred to by T3, T4 can be set to refer to that same value,
which T3 and T4 now share.
The reason I prefer the first model to the second is that it
offers what seems to me to be simpler answers to the six
questions posed in the puzzle. (And please feel free to
correct me if I have incorrectly or unfairly speculated about
any of your answers!)
> What about the BM dialect bm [a/0: 1]?
>
What about it? ;-)
You've managed to construct a clever function (BM) that
implements a dialect that does something different with
set-path expressions that REBOL does. I'm trying to build
a model for what REBOL does, not for how it might be extended
with a dialect to do something else/new.
> According to that, the time values aren't sharable,
> otherwise we would have seen the mutation when we looked at
> 'b. This leads to another conclusion: SAME? lies a bit, when
> it says we are sharing values. We are not, we have copies
> sometimes. There is a problem: what does SAME? say then?
>
Your statement seems to summarize our differences.
I do not believe that SAME? lies. Think of SAME? as meaning
guaranteed equal
.
I believe that SAME? tells us whether two values are so much
alike that they may be freely interchanged for all practical
purposes. I believe that, for instance, any occurrence of 2
is totally equivalent to any other occurrence of 2, even if one
were calculated from 1 + 1 and the other were calcuated from
(29 - 21) / 4 or any other such expressions you can imagine.
And I don't have to believe that there can only exist one
occurrence of 2 in order to believe their equivalence.
On the other hand, two strings that both currently contain
the message "Hi" may not be totally interchangeable for all
purposes, if there is a way I can modify the second letter of
one of them to #"a" without doing so to the other. Since
strings are mutable, this is possible (unless both are actually
references to the same underlying sequence of characters).
I do believe that SAME? is implemented differently for scalar
values than for reference values, but I think that difference
is both reasonable and explainable.
But please play along with me for a moment...
EXPERIMENT:
Whether or not you accept that REBOL has some values that are
not "shareable", I trust that you'll agree with me that it is
conceivable that *some* languages have non-sharable types. It
would be A Good Thing to have a function which tells us whether
two sharable values are in fact sharing the underlying data.
So... Imagine we're designing such a language. What should
our SAME-DATA? function do if given two non-sharable values?
I can only think of three alternatives:
A) Throw an error. This seems slightly hostile; we'd like our
functions to return something reasonable if at all possible.
b) Be strict and return FALSE, since non-sharable values by
definition can't be shared. This is a defensible position
but somewhat hard-nosed. We might really only need a test of
equivalence, in which case we'd have to choose between using
SAME-DATA? and EQUAL? depending on the types of the values we
want to compare.
c) Be generous and test EQUAL?, since non-sharable, immutable
values are indistinguishable (even if they are distinct
copies of equal data).
I believe REBOL does (c), which has as its only tricky exception
the fact that -- with non-sharable MUTABLE values -- two values
will stop being SAME? if one of them is mutated.
SIDE REMARK:
I also believe that our preconceived notions about the English
word "same" are contributing to the confusion. In English, the
words "equal", "equivalent", "same", and "identical" are often
used with highly overlapping (but not exactly identical)
meanings. This simply highlights the grave pitfalls that
surround any attempt to use natural languages as a basis for
user-friendly
languages for "non-programmers".
Natural languages are fuzzy and ambiguous, and are great for
poetry, flirting, and jokes. They are also notoriously bad for
precise specification (such as treaties, contracts, and program
specs).
Programming languages must be precise and unabiguous.
END OF SIDE REMARK
I hope this hasn't been too tedious for you... It certainly
forced me to think hard about what (I think ;-) I understand
and how to verbalize it. Thanks for all your hard work!
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[50/114] from: kenneth:nwinet at: 15-Jun-2001 1:10
Hi Joel,
<snip>
> Programming languages must be precise and unabiguous.
Sorry, but this struck me as funny! I enjoyed reading the insight and
commentary in the snipped parts (as always with your posts.)
Ken.
[51/114] from: joel:neely:fedex at: 15-Jun-2001 7:15
Hi, Ken,
Ken Anthony wrote:
> <snip>
> > Programming languages must be precise and unabiguous.
The batteries ran down on my spell Czech or at too A.M.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[52/114] from: g:santilli:tiscalinet:it at: 15-Jun-2001 19:30
Hello Joel!
On 15-Giu-01, you wrote:
JN> The differences in our models arise from the difference in
JN> what each of us assumes as a basis, and what each of us
JN> consequently must explain in a less intuitive fashion.
MY MODEL:
simple (scalar) value:
+----+
| |
+----+
series (reference) value:
+----+ +----- ... -----+
| |---->| ... |
+----+ +----- ... -----+
(where the boxes represent memory areas).
SAME? checks only the first memory area and returns true if it has
the same content. EQUAL? checks both the first and the second
(where present) memory area to se if they have the same content.
>> a: [1 2 3]
== [1 2 3]
>> b: next a
== [2 3]
>> same? a b
== false
>> same? next a b
== true
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[53/114] from: g:santilli:tiscalinet:it at: 15-Jun-2001 19:18
Hello Ladislav!
I hope you don't mind me jumping in. :-)
On 15-Giu-01, you wrote:
LM> My POV: According to Rebol, values can be the same. If the
LM> values are the same for Rebol, they are the same for me, i.e.
LM> they are one value. If I use this approach, I know, that
LM> Rebol values are sharable, because:
LM> a: 12:30
LM> b: a
LM> same? a b ; == true
Sorry to disappoing you, Lad, but this seems to prove SAME? is not
doing what you think it is doing:
>> a: 12:30
== 12:30
>> b: a
== 12:30
>> same? a b
== true
>> b/minute: 0
== 0
>> same? a b
== false
>> b/minute: 30
== 30
>> same? a b
== true
LM> Thus, all Rebol values are sharable for me ('a and 'b are
LM> sharing the same time value). It is the Observation #1 in my
They are not, at least this cannot be determined using the SAME?
function.
LM> looked at 'b. This leads to another conclusion: SAME? lies a
LM> bit, when it says we are sharing values. We are not, we have
LM> copies sometimes. There is a problem: what does SAME? say
LM> then?
Look above. :-)
LM> Now the full classification: the observed change is a
LM> mutation of the word 'a, which changed (namely replaced) its
LM> stored value attribute, which was an integer.
(I actually think that that was a change in a context! value, not
in a word! value, but well...)
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[54/114] from: joel:neely:fedex at: 15-Jun-2001 15:25
Hi, Gabriele,
We're 99% in agreement!
Gabriele Santilli wrote:
> MY MODEL:
> simple (scalar) value:
<<quoted lines omitted: 8>>
> SAME? checks only the first memory area and returns true if it has
> the same content.
We agree here.
> EQUAL? checks both the first and the second
> (where present) memory area to se if they have the same content.
>
If you meant
EQUAL? compares the first areas and returns TRUE if they have
the same content, otherwise it compares the content in the
second areas.
then we agree. In other words, its an IF/ELSE rather than ALL
set of comparisons. Agreed?
-jn-
___ ___ ___
\/ 2 + \/ 2 = 4 (for sufficiently large approximations of \/ 2 )
joel'dot'neely'at'fedex'dot'com
[55/114] from: carl:cybercraft at: 16-Jun-2001 10:52
On 15-Jun-01, Joel Neely wrote:
> Hi, again, briefly (long day today...)
briefly indeed. (:
[big snip]
> MY MODEL:
> a) All set-path expressions cause something to be mutated.
> The
something" is identified by the set-path up to the
> last #"/" and which part of that "something" is identified by
> what follows the last #"/". Any such "something" is mutable.
<<quoted lines omitted: 137>>
> the fact that -- with non-sharable MUTABLE values -- two values
> will stop being SAME? if one of them is mutated.
Well argued. However, I believe there is a place for a 'shared? word
in REBOL, but not as a replacement for 'same?. 'shared? should
compare words to see if they're sharing the same value, as apposed to
'same? which compares values.
a: 10
b: a
shared? a b
== false
a: "abc"
b: a
shared? a b
= true
a: 10
shared? a 10
== ERROR! ; Because 10 isn't a word.
If nothing else, this would help in debugging.
(Err, or should it be shared? 'a 'b?)
But whether it's right for "simple" values not to be shared, I'm not
sure. Consistancy is lost, and it means we can't have the likes
of...
a: 10
b: a
increase a
a
== 11
b
== 11
When I first realised that strings could be shared in REBOL, I
promptly assumed it would be the same for integers. I guess there's
a good reason why it isn't, (simple things should be simple,
perhaps?:), and I suspect it's a trifle late to ask for it to be
changed now...
--
Carl Read
[carl--cybercraft--co--nz]
[56/114] from: joel:neely:fedex at: 16-Jun-2001 8:33
Carl Read wrote:
> > So... Imagine we're designing such a language. What should
> > our SAME-DATA? function do if given two non-sharable values?
<<quoted lines omitted: 7>>
> 'shared? should compare words to see if they're sharing the
> same value, as apposed to 'same? which compares values.
You mean something like this?
shared?: func ['a [word!] 'b [word!]] [
found? all [
equal? type? get a type? get b
any [
any-function? get a
object? get a
series? get a
]
same? get a get b
]
]
which, I believe, passes all of your tests
>> a: 10 == 10
>> b: a == 10
<<quoted lines omitted: 4>>
>> a: 10 == 10
>> shared? a 10
** Script Error: shared? expected b argument of type: word
** Near: shared? a 10
(and one you forgot ;-)
>> a: "abc" == "abc"
>> b: "abc" == "abc"
>> shared? a b == false
Without this last test in the spec, we'd only be testing
whether the type of A (and B) is sharable, not whether
A and B are actually sharing a value.
> But whether it's right for "simple" values not to be shared,
>
It's certainly *faster* for simple types not to be reference
types, as it cuts out one level of indirection.
> Consistancy is lost...
>
One kind of consistency is traded for another, but the overall
readability is *greatly* improved, in the general case. See
below for why.
> and it means we can't have the likes
> of...
<<quoted lines omitted: 5>>
> b
> == 11
But if you have the likes of *that*, then why wouldn't you have
the likes of
a: 10
b: a
a: 11
b
== 11
which would probably be *very* non-intuitive and inconsistent
with
a: "hello"
b: a
a: "goodbye"
b
"hello"
This exposes us to the danger of confusing mutability and
referenceability all over again, in an even more subtle way!
In addition, "magical" dereferencing of references (especially
multiple layers of them) leads to *highly* confusing/unreadable
code. Consider the horrible example of Algol 68! (And if you
don't even know about Algol 68, take my word for it that the
confusing handling of ref/deref behavior is probably a major
reason why!)
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[57/114] from: lmecir:mbox:vol:cz at: 17-Jun-2001 3:47
Hi,
a sample thought (you need not take it seriously):
> MY MODEL:
>
> a) All set-path expressions cause something to be mutated.
> The "something" is identified by the set-path up to the
> last #"/" and which part of that "something" is identified by
> what follows the last #"/". Any such "something" is mutable.
A possible POV: once upon a time the time values in Rebol behaved like:
a: 12:30 ; == 12:30
a/hour: 13 ; == 13:30
a ; == 12:30
Back then your rule was incorrect. Your rule hasn't changed since then and
therefore it is still incorrect.
[58/114] from: kenneth:nwinet at: 16-Jun-2001 19:44
Forgive me, perhaps I've just lost my way in the thread;
> a: 12:30 ; == 12:30
> a/hour: 13 ; == 13:30
> a ; == 12:30
I get 13:30 for that last line.
I seem to be confused by what I thought to be a very simple concept. Unless
we've entered the twilight zone all computer memory still only have two or
three attributes; value, address and perhaps bit-width which can be ignored
for now.
All variables are either direct or indirect addressed regardless of the
language, but I don't think that is even germain to this issue.
equal? is defined as "Returns TRUE if the values are equal."
Which simply means regardless of where it is stored the bits are the same (I
would think.)
same? is defined as "Returns TRUE if the values are identical."
Here's my confusion. I assume that equal? and same? are not aliases for the
same function. So my understanding would hinge on the meaning of identical.
The only meaningful distinction I can come up with is that identical means
at the same address.
if that's the case (and how could it possibly be otherwise?) then...
a: 1:30
b: 1:30
same? a b ;==True
...confuses the hell out of me! Does anyone have an explanation?
Ken.
[59/114] from: joel:neely:fedex at: 16-Jun-2001 22:21
Hi, again, Ladislav,
Ladislav Mecir wrote:
> a sample thought (you need not take it seriously):
>
But I *always* take you seriously! ;-)
> > MY MODEL:
> >
<<quoted lines omitted: 8>>
> a/hour: 13 ; == 13:30
> a ; == 12:30
I don't know if anyone else did, but I reported that behavior
to RT as questionable. In a subsequent release, it was changed.
I conclude that either someone changed his mind, or that the
original behavior was a bug.
> Back then your rule was incorrect. Your rule hasn't changed
> since then and therefore it is still incorrect.
>
Actually, the prior behavior led me to conclude that TIME!
values were immutable, and I stated so at the time (pardon the
pun ;-). Now that that behavior has changed, I conclude that
TIME! values are mutable.
I did not state the simplified "rule" above until *after*
TIME! values became mutable.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[60/114] from: kenneth:nwinet at: 16-Jun-2001 21:12
...and how about this?
a: [1:30]
b: [1:30]
same? a b ;==false
same? do a do b ;==true
[61/114] from: joel:neely:fedex at: 16-Jun-2001 23:17
Hi, Ken,
I think the thread has become tangled enough that way-losing
has become proactively facilitated! (Can you tell that I'm
a Dilbert fan? ;-)
Ken Anthony wrote:
> Forgive me, perhaps I've just lost my way in the thread;
>
> > a: 12:30 ; == 12:30
> > a/hour: 13 ; == 13:30
> > a ; == 12:30
>
> I get 13:30 for that last line.
>
You should get 13:30. Note that the phrase just before the
part you quoted said "once upon a time". An earlier version
of REBOL exhibited the behavior quoted above, but that was
long ago in a galaxy far, far away.
> I seem to be confused by what I thought to be a very simple
> concept. Unless we've entered the twilight zone all computer
> memory still only have two or three attributes; value,
> address and perhaps bit-width which can be ignored for now.
>
Bear in mind that we're talking about REBOL values, not
computer memory. REBOL values have type, and what/how REBOL
does with a value is influenced by its type.
> All variables are either direct or indirect addressed
> regardless of the language, but I don't think that is even
> germain to this issue.
>
IMHO that *is* the issue.
> equal? is defined as "Returns TRUE if the values are equal."
>
> Which simply means regardless of where it is stored the bits
> are the same (I would think.)
>
EQUAL? tests whether *content* is the same, regardless of the
data type; in the case of a reference type (your "indirect
addressed" case) that may require following the reference to
the actual content.
> same? is defined as "Returns TRUE if the values are
> identical."
>
Well, it's not the first time the on-line help favors brevity
over clarity and completeness.
> Here's my confusion. I assume that equal? and same? are not
> aliases for the same function.
>
You are correct. They are not.
> So my understanding would hinge on the meaning of identical.
> The only meaningful distinction I can come up with is that
> identical means at the same address.
>
Only if there's an "address" involved... see below.
> if that's the case (and how could it possibly be otherwise?)
> then...
<<quoted lines omitted: 3>>
> ...confuses the hell out of me! Does anyone have an
> explanation?
I hate to descend to a low-level language, but consider the
behavior of the following c program:
8<------------------------------------------------------------
#include <stdio.h>
int main (int nargs, char *args[]) {
char *a = "Hello!";
char *b = a;
char c[] = {'H','e','l','l','o','!','\0'};
printf ("a same b: %s\n",
(a == b) ? "yes" : "no"
);
printf ("a same c: %s\n",
(a == c) ? "yes" : "no"
);
printf ("a equal b: %s\n",
(strcmp (a, b) == 0) ? "yes" : "no"
);
printf ("a equal c: %s\n",
(strcmp (a, c) == 0) ? "yes" : "no"
);
exit (0);
}
8<------------------------------------------------------------
When run, it produces the following output:
8<------------------------------------------------------------
$ ./cmp
a same b: yes
a same c: no
a equal b: yes
a equal c: yes
$
8<------------------------------------------------------------
For simple types (such as int) == tests whether the values
are the same. For pointer types == tests whether the pointers
are the same. But this means that if you want to test for
equality of the data POINTED TO by the pointers, you have to
use a different function (strcmp).
That's awkward.
REBOL assumes that we are more interested in data than in
mechanism, so EQUAL? always tests equality of data. For
reference types (e.g., any series) EQUAL? looks *through*
the reference to the data and checks for equality, while
for non-reference types (e.g., integers or times) EQUAL?
looks directly at the data and checks for equality.
For reference types, SAME? looks *at* the reference itself
to see if the references are the same. For non-reference
types (e.g., integers or times) there are no references, so
SAME? looks at the only thing it can -- the data values.
Hope this helps!
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[62/114] from: joel:neely:fedex at: 16-Jun-2001 23:30
Hi, again, Ken,
Using the ideas in my reply to your previous post (I just
sent it a couple of minutes ago)...
Ken Anthony wrote:
> ...and how about this?
>
> a: [1:30]
> b: [1:30]
> same? a b ;==false
>
...this outcome is easy to predict. Notice that A and B
are both blocks, with EQUAL? content, but since they were
constructed separately, they are not the SAME? block.
> same? do a do b ;==true
>
Remember that when DO is given a block, it evaluates all
expressions in the block, and returns the value of the last
expression as its result. Given that fact:
>> do a == 1:30
>> do b == 1:30
>> same? do a do b == true
The result value from DO A is the TIME! value of 1:30, and
likewise for DO B . Since TIME! is not a reference type,
any occurrence of 1:30 is the same as any other occurrence
of 1:30. Therefore, any expression that produces a TIME!
value of 1:30 yields a result that is SAME? to the result of
any other expression yielding 1:30, even something like:
>> 0:30 * 3 == 1:30
>> same? do a 0:30 * 3 == true
>> same? 2:00 - 0:30 0:30 * 3 == true
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[63/114] from: kenneth:nwinet at: 16-Jun-2001 22:30
Thanks Joel,
> > I seem to be confused by what I thought to be a very simple
> > concept. ...memory [has] two or three attributes; value,
> > address and perhaps bit-width which can be ignored for now.
>
> Bear in mind that we're talking about REBOL values, not
> computer memory. REBOL values have type, and what/how REBOL
> does with a value is influenced by its type.
It was always on the fringes (of my feeble mind.)
> > All variables are either direct or indirect addressed
> > regardless of the language, but I don't think that is even
> > germain to this issue.
>
> IMHO that *is* the issue.
My bizarre thought process always dismisses the obvious, you'll get used to
it. ;-))
> > equal? is defined as "Returns TRUE if the values are equal."
> >
<<quoted lines omitted: 4>>
> addressed" case) that may require following the reference to
> the actual content.
I think we are saying the same thing here. The reason I refer to bits is
that regardless of type at some point a test of equality has to test bits of
a value that have been converted to the same format/type (whatever is done
internally.)
> > same? is defined as "Returns TRUE if the values are
> > identical."
>
> Well, it's not the first time the on-line help favors brevity
> over clarity and completeness.
Ain't it the truth! (universally)
> > Here's my confusion. I assume that equal? and same? are not
> > aliases for the same function.
>
> You are correct. They are not.
>
> > The only meaningful distinction I can come up with is that
> > identical means at the same address.
>
> Only if there's an "address" involved... see below.
Forgive my blockheadedness but address is always involved somehow, but I
accept your explanation about same? giving the same result as equal? for
non-referenced types.
> > a: 1:30
> > b: 1:30
> > same? a b ;==True
> >
> > ...confuses the hell out of me! Does anyone have an
> > explanation?
[c code paraphrased (and be kind, I don't do c)...]
> char *a = "Hello!";
> char *b = a;
<<quoted lines omitted: 3>>
> strcmp (a, b) : yes
> strcmp (a, c) : yes
which is exactly as I would expect, but I think your example would
correspond more to a Rebol version as this:
a: 2:30
b: a
c: 1:30 + 1:00
...at which point... same? a c ;=True
...varies with the... a==c: no
Which is what confuses me.
...the rest would be the same (where strcmp would correspond to equal?)
> REBOL assumes that we are more interested in data than in
> mechanism, so EQUAL? always tests equality of data. For
> reference types (e.g., any series) EQUAL? looks *through*
> the reference to the data and checks for equality, while
> for non-reference types (e.g., integers or times) EQUAL?
> looks directly at the data and checks for equality.
I find equal? to be predictable and correct given my limited understanding
of Rebol.
> For reference types, SAME? looks *at* the reference itself
> to see if the references are the same. For non-reference
> types (e.g., integers or times) there are no references, so
> SAME? looks at the only thing it can -- the data values.
>
> Hope this helps!
It does! Assuming of course, someone doesn't change the rules on me later.
Which begs the question is there a referenced? vs. non-referenced? type
function?
Ken.
[64/114] from: kenneth:nwinet at: 16-Jun-2001 22:34
Reading my mind again Joel,
> > a: [1:30]
> > b: [1:30]
<<quoted lines omitted: 18>>
> >> same? do a 0:30 * 3 == true
> >> same? 2:00 - 0:30 0:30 * 3 == true
I just finished doing a bunch of tests like this (I honored to be in such
esteem company! ;-))
ken.
[65/114] from: lmecir:mbox:vol:cz at: 17-Jun-2001 10:02
Hi,
> >
> > a sample thought (you need not take it seriously):
<<quoted lines omitted: 31>>
> TIME! values became mutable.
> -jn-
I try to reformulate my argument: "your rule is correct only in the
circumstances not specified by the rule"
This is a sufficient condition for the rule to be considered incorrect.
Regards
Ladislav
[66/114] from: carl:cybercraft at: 17-Jun-2001 22:12
On 17-Jun-01, Joel Neely wrote:
> Carl Read wrote:
>>
<<quoted lines omitted: 27>>
> ]
> ]
Yep - exactly like that.
> which, I believe, passes all of your tests
>>> a: 10 == 10
<<quoted lines omitted: 14>>
> whether the type of A (and B) is sharable, not whether
> A and B are actually sharing a value.
Agreed - I was just being lazy with my examples. (:
>> But whether it's right for "simple" values not to be shared,
> It's certainly *faster* for simple types not to be reference
<<quoted lines omitted: 22>>
> which would probably be *very* non-intuitive and inconsistent
> with
Ah, but it wouldn't work like that. I used 'increase as a word to
mimic the likes of 'insert for series. This is what would happen...
a: 10 ; a points to 10
b: a ; b points to 10
a: 11 ; a now points to 11, leaving b still pointing to 10.
What this would mean though is we'd have to use...
b: copy a
with "simples" sometimes. How often? I don't know. Perhaps RT did
some tests and found that in the real world it'd have to be way too
often and considered REBOL's present way a happy compromise between
purity and practicality.
> a: "hello"
> b: a
<<quoted lines omitted: 3>>
> This exposes us to the danger of confusing mutability and
> referenceability all over again, in an even more subtle way!
I don't think so, since I think you mistook what I meant - or took it
too far. "Simples" would still behave just like your string example
above, it's just that sometimes more than one variable could point to
the same value.
I think this would be more consistant. Whether it'd be better or
worse for programming though, I haven't a clue. A dialect project
for someone perhaps? (:
> In addition, "magical" dereferencing of references (especially
> multiple layers of them) leads to *highly* confusing/unreadable
> code. Consider the horrible example of Algol 68! (And if you
> don't even know about Algol 68, take my word for it that the
> confusing handling of ref/deref behavior is probably a major
> reason why!)
Okay - will avoid. (:
> -jn-
>
> ------------------------------------------------------------
> "Programming languages: compact, powerful, simple ...
> Pick any two!" joel'dot'neely'at'fedex'dot'com
> ------------------------------------------------------------
--
Carl Read
[carl--cybercraft--co--nz]
[67/114] from: g:santilli:tiscalinet:it at: 16-Jun-2001 20:41
Hello Joel!
On 15-Giu-01, you wrote:
JN> then we agree. In other words, its an IF/ELSE rather than ALL
JN> set of comparisons. Agreed?
Oh, yes, this way is more efficient. :-)
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[68/114] from: brett:codeconscious at: 17-Jun-2001 19:17
You guys lost me a long time ago. Thus I've no idea if this particular
interjection is going to timed appropriately. :)
I'm wondering if and when you come to some agreement and finalisation of
this thread that one/some of you would be good enough to summarise
the resolution so that I do not have to replicate the same amount of brain
energy you've already put in. :) If no resolution, then multiple
hypotheses would be fine. ;)
And for real brownie points it would be good if this summary could be at the
level suitable for inclusion in the language documentation - that is without
recourse to a lot of assumed knowledge.
Many thanks.
Brett.
[69/114] from: joel:neely:fedex at: 17-Jun-2001 8:06
Hi, Ken,
Ken Anthony wrote:
> >
> > EQUAL? tests whether *content* is the same, regardless of
<<quoted lines omitted: 5>>
> equality has to test bits of a value that have been converted
> to the same format/type (whatever is done internally.)
I understand. FWIW the reason I wanted to rephrase it was to
emphasize the issue of *which* bits were being compared in each
case. Unfortunately the word "value" is sometimes ambiguous in
the stuff I've read.
> > Only if there's an "address" involved... see below.
>
> Forgive my blockheadedness but address is always involved
> somehow, but I accept your explanation about same? giving the
> same result as equal? for non-referenced types.
>
For non-reference types there doesn't have to be "an address". The
result of evaluating 1 + 3 is identical to the result of
evaluating 6 - 2 in both Mathematics sense and in REBOL.
>> same? 1 + 3 6 - 2 == true
That's true whether the (temporary) results for those
expressions are held in scratch memory locations (which have
addresses), in a stack (which may or may not have addresses,
depending on CPU) or in registers (which usually don't have
addresses).
> a: 2:30
> b: a
> c: 1:30 + 1:00
>
> ...at which point... same? a c ;=True
> ...varies with the... a==c: no
>
In some other languages (which shall remain nameless ;-) one
thinks of a variable as a label for some "cell" in memory.
The value of a variable is what is stored in that cell. (A
variable is a "container", and the value is its "content".)
For some data types the content of the cell is not the final
data value, but a pointer to it.
If two variables contain "same" pointers, then the pointed-to
data are guaranteed to be equal. If two variables contain
different pointers, then we don't know whether the data are
equal or not without following the pointers and examining the
data at those destinations.
Therefore we have three possible comparison scenarios:
Kind of datatype Comparison to be performed
---------------- --------------------------
1) Simple data Compare the data values
2) Reference data Compare the "pointer" values
3) Reference data Compare the "final data" values
Low-level languages assume that you're interested in bits and
cells and pointers and such, so they test equality of variables
by seeing if what's in the cells are identical, regardless of
the variables' datatype(s). In other words, they group (1)
and (2) together in an equality test (such as the == in c), and
require a separate test for (3) (such as strcmp in c).
You, the programmer, have to keep up with the data types and
figure out which kind of comparison you need to make.
REBOL is a high-level language, and makes the assumption that
the programmer is more frequently interested in data values than
in the details of implementation. Therefore, REBOL groups (1)
and (3) together in the concept of EQUAL? (regardless of data
type), and leaves (2) as a separate SAME? test.
Of course, that begs the question "What do we do if SAME? is
applied to simple data, since it is really there to compare
data structure references?" I discussed a list of possible
answers and reasons in another post, so I won't repeat all of
that here, but the short answer is this: since simple data
values don't have references, SAME? just compares the data
values themselves. That's why we got
>> same? 1 + 3 6 - 2 == true
in the example above.
> ...is there a referenced? vs. non-referenced? type function?
>
Not AFAIK. The following is a quick cut at a function that
tells whether the current value of a word is of a reference
type.
sharable?: func ['w [word!]] [
found? any [
series? get w
any-function? get w
object? get w
]
]
It may be used as follows:
>> a: "123" == "123"
>> sharable? a == true
<<quoted lines omitted: 4>>
>> a: [1 2 3] == [1 2 3]
>> sharable? a == true
No warranties expressed or implied! I believe it to be true
for the "ordinary data" cases, but it may require tweaking
for the more esoteric REBOL-specific types.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[70/114] from: joel:neely:fedex at: 17-Jun-2001 8:07
Ken Anthony wrote:
> Reading my mind again Joel,
>
> >
> > >> 0:30 * 3 == 1:30
> > >> same? do a 0:30 * 3 == true
> > >> same? 2:00 - 0:30 0:30 * 3 == true
>
> I just finished doing a bunch of tests like this...
>
Good minds think alike! ;-)
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[71/114] from: ptretter:charter at: 17-Jun-2001 8:10
Ok, I have read these threads but since I'm new to programming I know not
what is meant by the word "mutable". Can someone define this please.
Paul Tretter
[72/114] from: joel:neely:fedex at: 17-Jun-2001 8:34
Ladislav Mecir wrote:
> I try to reformulate my argument: "your rule is correct only
> in the circumstances not specified by the rule"
>
> This is a sufficient condition for the rule to be considered
> incorrect.
>
I'm sorry. I guess I need more coffee this morning, but I
couldn't follow that one at all. Maybe we should bring this
one to a close on the note that we simply agree to disagree.
Each of us has a model for what is going on with respect to
references and mutability, and in fact we seem to have
differing definitions for those words. I've chosen the one
that I use because
- I think it give me a simpler way to explain a wider
range of REBOL phenomena,
- I think it is consistent with conventional jargon
in Computing Science, and
- it allows me to compare/contrast REBOL behavior with
that of other programming languages easily.
YMMV, of course, and you're certainly entitled to use and
promote a different model. I welcome any and all challenges
to the model I'm using (because that's how we find bugs!).
I think it's fair to call the model "incorrect" only if there
is a piece of REBOL code that produces a result/effect that
is different than the model predicts, using the terminology
of the model in the way that I've been using it.
As far as the case below:
a: [8]
bm [a/1/1: 1]
a ;== 9
all I can say is that BM is a very clever mini-interpreter
that re-interprets its argument block as if it had been
written
a/1: a/1 or 1
which -- in my model -- changes the first element of the
block (referenced by A) by replacing the integer 8 with a
different integer (9), and not by modifying the 8 in-place.
As ingenious as BM is (and I mean that sincerely!) it extends
set-path expressions in a way that is outside standard REBOL
behavior:
>> a: [8]
== [8]
>> a/1/1: 1
** Script Error: Cannot use path on integer! value
** Near: a/1/1: 1
and therefore doesn't prove anything about whether my model of
standard REBOL behavior correctly predicts standard REBOL
behavior.
Again, let me express my sincere appreciation for your deep
understanding of REBOL and for your discussions and time.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[73/114] from: kenneth:nwinet at: 17-Jun-2001 10:42
Joel,
Much appreciation for your discussions in this list.
> Kind of datatype Comparison to be performed
> ---------------- --------------------------
<<quoted lines omitted: 5>>
> tells whether the current value of a word is of a reference
> type.
May I propose or suggest that RT consider adding a 'simple?' function (the
word seems to be common to the thread whereas sharable? seems to add a
nuiance not explicit in your chart above) which could act as a lawman for
these issues.
> sharable?: func ['w [word!]] [
> found? any [
<<quoted lines omitted: 15>>
> for the "ordinary data" cases, but it may require tweaking
> for the more esoteric REBOL-specific types.
But I *want* warranties!
Deputy, round up a posse! I have a warrant here for any genius language
designer that leaves too many undefined issues hanging around the saloon. I
don't give a lick for what that there Godel hombre has to say about it.
While we're at it, let's throw in a few divide by zero's laws just for
kicks. It may be infinity to those there mathmatical fella's, but us
programmer's around these here parts usually just define the result to be
zero.
But Sheriff, my boy told me that 0/0 is undefined soes we might as well make
a law that it's ta be nought... wouldn't it be more correct for sum number
there divided by nought to be a really big number like those mathmedical
fella's says?
Now deputy, if they want to test for zero, they can test for zero, but I'm
telling ya we got ta have a civilized town here. That means no shootin'
irons in the town limits and zero begets zero whether ya multiply or divide.
Well I don't rightly know Sheriff, sounds kinda dangerous like to cipher
thata way.
BTW, Sheriff didya notice they got this cp thing that does the same thang as
copy?
I saw that there deputy, and I plan to make eunix atta those there rustlers
as soon as we get this zero issue all cleared up. Now let's go down to the
corral and see what Ike and his boys are up to.
OK.
Well of course.
[74/114] from: kenneth:nwinet at: 17-Jun-2001 11:22
Hi Paul,
>From microsoft word:
Mutable, changeable, Alterable, shifty, Slippery, variable, Uncertain,
changing, Fickle, inconstant.
> Ok, I have read these threads but since I'm new to programming I know not
> what is meant by the word "mutable". Can someone define this please.
I don't know if there is a more precise definition in computer science but
I've always taken 'mutable or immutable' to simply mean 'variable or
constant'.
There may be some nuiance related to addressing mode but someone else would
have to answer that.
Ken.
[75/114] from: joel:neely:fedex at: 17-Jun-2001 12:10
Hi, Ken,
Ken Anthony wrote:
> But I *want* warranties!
>
> Deputy, round up a posse! I have a warrant here...
> Now let's go down to the corral and see what Ike and his
> boys are up to.
>
> OK.
>
> Well of course.
>
I nearly hurt myself laughing, and aggravated my corral tunnel
syndrome. I don't think I'll be able to code this week...
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[76/114] from: joel:neely:fedex at: 17-Jun-2001 12:36
Hi, Paul,
Paul Tretter wrote:
> Ok, I have read these threads but since I'm new to
> programming I know not what is meant by the word "mutable".
> Can someone define this please.
>
I'll try to offer a definition without stepping on any
land mines...
Mutable: capable of being changed; read/write
Immutable: incapable of being changed; read-only
In REBOL, strings are mutable. Therefore, if I have set
a variable to a string, as in:
>> msg: "Hi, Paul" == "Hi, Paul"
I can *mutate* or modify the value of that string, as in:
>> append msg "!" == "Hi, Paul!"
>> msg == "Hi, Paul!"
APPEND "goes through" the variable to get to the string,
and changes the string itself.
That's different from starting with a string:
>> msg: "Hi, Paul" == "Hi, Paul"
and merely *replacing* it with a different string.
>> msg: "Hi, Paul!" == "Hi, Paul!"
>> msg == "Hi, Paul!"
In REBOL, integers are immutable. If I have set a variable
to an integer, as in:
>> a: 42 == 42
I can't modify the integer itself, but can *only* replace it
with another integer:
>> a: a + 1 == 43
Even if the new integer were calculated from the value of the
old one, I'm still *replacing*, because the above expression
means
set A to the result of evaluating A and adding one
Even though I used the variables MSG and A in the examples
above, mutability/immutability are not about variables, but
about the values themselves. For example, we could have done:
>> blk: ["Hi, Paul" 42] == ["Hi, Paul" 42]
>> append first blk "!" == "Hi, Paul!"
>> blk/2: blk/2 + 1 == ["Hi, Paul!" 43]
>> blk == ["Hi, Paul!" 43]
By way of contrast, strings in Java and Python are immutable;
you cannot modify a string in either of those languages. In
the case of Python, I believe the decision was made with a
view to performance optimization.
In the case of Java, the decision was made for security
purposes. A common security device is for an argument (string
or buffer) to be validated by a routine that only hands it on
for processing if its contents are acceptable. This could be
defeated by code running in a separate thread if that hostile
code waits long enough for the validation to be performed and
then modifies the content of the argument (string or buffer)
to ask for something else that wouldn't have passed validation.
By making strings immutable, Java protects itself from that
type of security attack.
Hope this helps!
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[77/114] from: ptretter:charter at: 17-Jun-2001 17:47
Thanks Joel, this is awesome explaination. I now have a complete and
thourough understanding.
Paul Tretter
[78/114] from: kenneth:nwinet at: 17-Jun-2001 17:46
Joel, I'm being dense again.
When you say the integers are immutable in Rebol (implying they may be
mutable in other languages?); I'm seeing a distinction without a difference.
You referred to mutating verses replacing.
> a: 42
> a: a + 1 ;=43
Could I not see this as an example of mutating the rightmost bit?
...or perhaps...
Are you saying a new symbol 'a' is created in a table so that the place
where 42 is stored is unrelated to the place where 43 is stored?
...or...
The truth is out there (but unlike the x-files I'm about to be enlightened!
;-))
> Mutable: capable of being changed; read/write
> Immutable: incapable of being changed; read-only
ken.
[79/114] from: lmecir:mbox:vol:cz at: 18-Jun-2001 3:17
Hi,
> Ladislav Mecir wrote:
> >
<<quoted lines omitted: 7>>
> couldn't follow that one at all. Maybe we should bring this
> one to a close on the note that we simply agree to disagree.
I am not sure it is the right time, see below.
> Each of us has a model for what is going on with respect to
> references and mutability, and in fact we seem to have
<<quoted lines omitted: 6>>
> - it allows me to compare/contrast REBOL behavior with
> that of other programming languages easily.
You helped me substantially to improve the wording of the
http://www.sweb.cz/LMecir/evaluation.html
Thanks a lot. Could you please check if the choice of notions is better now?
(You might find an interesting property of ERROR! values in there)
> YMMV, of course, and you're certainly entitled to use and
> promote a different model. I welcome any and all challenges
<<quoted lines omitted: 28>>
> understanding of REBOL and for your discussions and time.
> -jn-
BTW, did I say thank you?
Ladislav
[80/114] from: lmecir:mbox:vol:cz at: 17-Jun-2001 18:51
Hi Brett,
see the latest wording of http://www.sweb.cz/LMecir/evaluation.html
[81/114] from: agem:crosswinds at: 18-Jun-2001 3:52
RE: [REBOL] Re: On mutability and sameness
[kenneth--nwinet--com] wrote:
> Joel, I'm being dense again.
> When you say the integers are immutable in Rebol (implying they may be
<<quoted lines omitted: 11>>
> > Mutable: capable of being changed; read/write
> > Immutable: incapable of being changed; read-only
hm. "particle physics"?
Mutable: the original value is "slow" and can be modified.
Immutable: if you touch the value, it immediate "flips out", is automatic copied before.
no chance to be fast enough for a change ;-)
You see, very simple types are very flippy, a bit more complex types are somewhat slower
and heavy series are really mutable slow.
prove:
a: 42
a: a + 1 ; touch a, 42 flips out, add 1, then assign the value to a, changed, hehe
but
a: 23:55
a/1: 56 ;touch 23:55, 23:55 yawns, 23:55 is changed. without explicit assignment
and
a: 1-Apr-2001/23:55
a/time/minute: 56 ; to slow, 23:55 flips out, a unchanged
a/time: 23:56 ;fast enough :)
so we should replace 'Immutable with 'flippy? ;-)
-Volker
[82/114] from: joel:neely:fedex at: 17-Jun-2001 16:32
Hi, Ken,
Ken Anthony wrote:
> Joel, I'm being dense again.
>
> When you say the integers are immutable in Rebol (implying
> they may be mutable in other languages?)
>
Believe it or not, they used to be... ;-)
Questions 16-18 of "The Hacker Purity Test", found at
http://www.armory.com/tests/hacker.html
ask
16. 0x00F Ever change the value of 4?
17. 0x010 ... Unintentionally?
18. 0x011 ... In a language other than Fortran?
but that's a story for a long summer's evening in the
mountains with a campfire and some marshmallows.
> You referred to mutating verses replacing.
>
> > a: 42
> > a: a + 1 ;=43
>
> Could I not see this as an example of mutating the rightmost
> bit?
>
I don't think it's useful to do so. Suppose there had been
more intervening steps:
>> a: 42 == 42
>> b: a + 1 == 43
>> a: b == 43
or
>> a: 42 == 42
>> b: reduce [a + 1] == [43]
>> a: first b == 43
or even
>> a: 42 == 42
>> b: to-char a // 10 + 49 == #"3"
>> c: to-char (to-integer a / 10) + 48 == #"4"
>> d: rejoin [c b] == "43"
>> a: to-integer d == 43
Would that same idea still hold? At what point does "the 42"
get altered? I believe it's simpler to understand that
a: ... some expression ...
sets A to whatever the expression evaluates to, and it's only
coincidental that the expressions we've been talking about
happen to use the former value of A.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[83/114] from: joel:neely:fedex at: 17-Jun-2001 16:39
Hi, Volker,
I didn't *quite* ROFL, but I enjoyed the idea very much! ^_^
[agem--crosswinds--net] wrote:
> hm. "particle physics"?
> Mutable: the original value is "slow" and can be modified.
<<quoted lines omitted: 4>>
> types are somewhat slower
> and heavy series are really mutable slow.
...
> so we should replace 'Immutable with 'flippy? ;-)
>
If this explanation doesn't catch on, would we call it a
flip flop? Oops, hardware again! Maybe I went a bit too far!
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[84/114] from: joel:neely:fedex at: 17-Jun-2001 16:59
Ladislav Mecir wrote:
> You helped me substantially to improve the wording of the
> http://www.sweb.cz/LMecir/evaluation.html
> Thanks a lot. Could you please check if the choice of notions
> is better now?
>
I've just looked at it again, and find the readability better
each time through. I need some digesting time before making
any substantive replies, although I think the terminology is
an improvement.
> (You might find an interesting property of ERROR! values in
> there)
>
That was quite a surprise!
It's a pleasure working with you.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[85/114] from: carl:cybercraft at: 18-Jun-2001 11:25
On 18-Jun-01, Ken Anthony wrote:
> Joel,
> Much appreciation for your discussions in this list.
<<quoted lines omitted: 35>>
>> for the "ordinary data" cases, but it may require tweaking
>> for the more esoteric REBOL-specific types.
As the one who originally suggested 'shared?' as a word, (which I
hadn't notice had mutated into sharable?:), may I second Ken's
suggestion of 'simple?' instead? (Now that I've stopped laughing.:)
Simple things should be simple?, etc., etc... (Even if it's polite
to share.)
--
Carl Read
[carl--cybercraft--co--nz]
[86/114] from: kenneth:nwinet at: 18-Jun-2001 22:17
Hey there,
> Questions 16-18 of "The Hacker Purity Test", found at
>
> http://www.armory.com/tests/hacker.html
>
> 16. 0x00F Ever change the value of 4?
> 17. 0x010 ... Unintentionally?
> 18. 0x011 ... In a language other than Fortran?
A co-worker thought this was new to me when he showed it to me a couple of
years ago. Happens I had to say '5 on purpose in Fortran' = no points.
A classic list.
Ken
[87/114] from: joel:neely:fedex at: 19-Jun-2001 3:43
[Robbo1Mark--aol--com] wrote:
> Joel Neely
>
> > I am not trying to reverse engineer REBOL......
>
> Ladislav Mecir
>
> > I am not trying to make discoveries or
> > statements about REBOL implementation
> > details.......
>
...
> Having followed this thread with interest, I
> believe, barring the disclaimer above, that
> both Joel & Ladislav are WRONG in the sense
> that some REBOL behaviour can only be explained
> and understood fully in terms of the way it
> has been implemented.
>
I don't want to create a model that explains all REBOL
behavior, just the "essential" behavior. The hard part
is at the edges. Absent a formal specification of what
REBOL "should" do, it is sometimes a bit of a puzzle as
to whether a given detail is essential or incidental.
However, most of the time the distinction is obvious.
(I should be clear that, since I view REBOL as a work in
progress, my remark that there's no formal specification
is a statement of fact, and not a complaint.)
> To me this "understanding" means how REBOL is
> implemented as well...
<<quoted lines omitted: 4>>
> true however it does not aid us in our quest
> to understand REBOL...
Let me illustrate why I'm sympathetic to Holger's statement,
clarifying my essential-vs-incidental distinction.
ESSENTIAL:
We can observe REBOL behaving differently for BLOCK! and
TIME! values, as in:
>> a: [1 2 3] == [1 2 3]
>> b: a == [1 2 3]
>> a/1: 2 == [2 2 3]
>> b == [2 2 3]
(changing the value of A changes the value of B)
>> a: 01:02:03 == 1:02:03
>> b: a == 1:02:03
>> a/1: 2 == 2
>> b == 1:02:03
(changing the value of A does not change the value of B)
I view this behavioral distinction as essential; one cannot
use blocks and times correctly without respecting it (I
won't try to imagine using REBOL without using both BLOCK!
and TIME! values and all of their capabilites).
But we can describe this distinction via conceptual models
*without* reference to the specifics of the current REBOL
interpreter. Ladislav has offered one such model; I have
offered another. While our views differ over "meta-details"
of our models, I think we would both agree that both models
do predict the above behavior.
INCIDENTAL:
1) The SORT algorithm in REBOL used to be unstable; more
recent releases have used a stable algorithm. (For any
who aren't familiar with the jargon, "stable" has to do with
how different items with equal keys are handled, rather than
with sanity. ;-) Based on a post by Holger, I could guess
about the change, but there are several stable sort techniques.
Knowing that SORT is stable is relevant to my model (in some
cases, though not all) but knowing *which* stable sorting
technique was used is not. If I'm trying to explain REBOL to
someone who doesn't know what "stable" means, I can give an
example of how to achieve stability without worrying about
whether the example is based on the technique used in REBOL.
2) We know that REBOL values have types. There are many
different ways type could be represented. It is not
essential to my model whether types are coded as a single
byte in a descriptor or in a 64-bit bitmask prefixed to a
pointer, as long as I know that data type *is* an essential
aspect of a value and (for example) understand the meaning
of converting a value from one type to another.
> Forgive me if Iam wrong, but I think Joel is seeking
> a fully comprehensive understanding and Ladislav seeks
> clarity, simplicity, purity and consistency. These are
> NOT mutually exclusive.
>
Ladislav can (and will, I'm sure ;-) correct me if I don't
understand his view properly, but I'd describe our different
perspectives by saying it this way:
Joel is seeking a model of essential REBOL behavior
that uses conventional concepts and terminology when
appropriate and effective, with a goal of explaining
REBOL to programmers who already know other languages.
Ladislav is seeking a model of essential REBOL behavior
that can be communicated entirely within REBOL itself,
without reference to other languages or assumptions,
with a goal of having a seamlessly self-contained model.
These two goals sometimes lead to different explanations;
Joel is a little more willing to make a leap of faith
in the interest of simplifying his model, while Ladislav
is a little more strict about refusing to draw distinctions
that cannot be demonstrated by REBOL code.
> However I think they are wrong to believe they can fully
> and properly achieve this without geting down to the nitty
> gritty of implementation details where necessary.
>
And I suggest that we have different interpretation of "where
necessary".
> To fully understand the behviour of any-block! or any-string!
> series! values you have to have a model of how series! values
<<quoted lines omitted: 4>>
> implementation, I think it is important conceptually that we
> do TRY to conceptually build an implementation model.
I'll admit that sometimes (especially given enough special
cases and exceptions) an operational model may seem more
compact than a more conceptual model, but I believe it is
important to stay as non-operational as possible. I don't
have time to give the whole argument here (and this probably
isn't the right forum for such details), but let me quickly
argue by analogy.
High-school geometry uses lots of diagrams. However, a good
geometry teacher will warn students about the dangers of using
diagrams. If I conjecture some property of a triangle and
draw a diagram to illustrate my conjecture, I have to make some
choices (perhaps unconsciously!) that will affect my perception
of what's relevant and what's not. Should my diagram use an
equilateral triangle, an isosceles triangle, a right triangle,
a scalene triange, an obtuse triangle? Each of those choices
may have incidental properties that could be misleading.
> Rather it is important that we build our model then
> incrementally refine / modify & improve it in view of further
<<quoted lines omitted: 3>>
> then for all intents and purposes it is a valid working model
> of REBOL, regardless of number of bits per value etc.
On this we agree, but I feel compelled to emphasize that we
also have to keep in mind what parts of our model are essential
and what parts are incidental.
> Just like my eyes and hair are brown is controlled by my
> genetics, REBOL is an extension of it's implementation in C.
> One is a direct result of the other.
>
Case in point. I don't know for sure what language(s) the
current REBOL interpreter is written in. I think I shouldn't
have to know.
But let's speculate. Suppose Core 2.5 and View 1.2 were
implemented in C. Now suppose that Carl decides to implement
Core 3.0 and View 2.0 in Ada (or Pascal or raw assembler).
I believe that such a change could happen without our ever
knowing it.
C may be OK for giving examples, but it is certainly not the
only way to think about computing, IMHO.
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[88/114] from: robbo1mark:aol at: 19-Jun-2001 10:43
Joel,
thanks for your clarifications, I think we are in basic agreement, sometimes REBOL examples
can suffice, other times you need to drop down a language to see why REBOL
might behave as it does.
< snip >
C may be okay for giving examples, but it is certainly not the only way to think about
computing, IMHO.
< end snip >
Of course not Joel, everybody knows REAL PROGRAMMERS can
write FORTRAN in "ANY" language. 8-)
Further it is my belief that REBOL or a REBOL like language could be implemented in a
LOT of languages other than ANSI C. For instance FREEBELL in JAVA so why
not Delphi, Ada, C++, C#, Tao/Amiga assembly etc. etc.
This might effect ease of platform portability and full
feature set though!
Your opinions are valued! well by me anyway!
cheers,
Mark Dickson
[89/114] from: jeff:rebol at: 19-Jun-2001 7:45
[Robbo1Mark--aol--com]:
>> .... Having followed this thread with interest, I believe,
barring the disclaimer above, that both Joel & Ladislav are
WRONG in the sense that some REBOL behaviour can only be
explained and understood fully in terms of the way it has
been implemented.<<
That's a very bottom up way to think of things. When we
implement parts of REBOL we first sit down and say "how is
this supposed to work-- what are the rules it obeys." Once we
understand what something is supposed to do, then we write the
lower level code that does that thing we've figured out. It's
a process of describing in a low level, something you
understand at a high level. You're claiming to want to
understand something at a high level by considering how it is
expressed at a low level. That's like trying to understand
what an Elephant IS by looking at one of its cells under a
microscope. How do you even know what you're looking at is an
Elephant?
The way functionality is implemented is arbitrary as long as
it is reasonably space and cpu efficient and the
implementation behaves according to the high level
functionality that's desired. Joel's got this one on the head.
You gain little understanding of something like series by
trying to build series in C. You'll miss the forest for the
trees, so to speak.
Robbo:
>>To fully understand the behviour of any-block! or
any-string! series! values you have to have a model of how
series! values are implemented at the C code level from
which REBOL is built. ... Whilst any C code model we might
build for REBOL values... will most probably NOT exactly
match the RT official implementation, I think it is important
conceptually that we do TRY to conceptually build an
implementation model.<<
Joel:
>> C may be OK for giving examples, but it is certainly not
the only way to think about computing, IMHO.<<
Yes, but I think Mark's interest in having things
"explained" in terms of C code has less to do with
"understanding REBOL" at a high level, and more to do with
having people help "paint his fence", if you've ever read
Tom Sawyer. ;-)
-jeff
[90/114] from: robbo1mark:aol at: 19-Jun-2001 11:34
JEFF,
I essence you are correct, but how easier can you more
properly explain these examples.....
>> a: "123"
== "123"
>> b: a
== "123"
>> c: "123"
== "123"
'a & 'b are the "SAME" string! and refer to the same memory location. 'c has the same
value on the surface
but is a separate instance of a string! value and is stored at a separate memory location.
That is why this....
>> insert b "abc"
== "123"
>> b
== "abc123"
>> a
== "abc123"
>> c
== "123"
The value of 'A & 'B both change but 'C remains unaltered. You can show this in 'C (
or some other language ) by use of pointers and references as Joel
did.
Similarly....
>> a: <abc>
== <abc>
>> parse a [b:]
== false
>> b
== "123"
How do you explain that unless you drop down to C or
something else and show your any-string! or any-block!
models with pointers to memory storage for the actual "data" values.
In the above example both reference the "Same" string!
data but 'a has the datatype! value tag! whilst 'b is
a normal string! datatype!
Sometimes to understand what's in a forest and what makes a forest you've got to look
at trees and leaves
and leaf / tree cells. Afterall thats how you really
UNDERSTAND trees & forests, even if it is from the
bottom up.
Also what is wrong with helping your neighbour to paint
his fence is you neighbour is your friend?
Depends who has more REBOL spirit, Huckleberry Finn
or Aunt Polly?
cheers Jeff 8-)
Mark Dickson
In a message dated Tue, 19 Jun 2001 11:01:20 AM Eastern Daylight Time, Jeff Kreis <[jeff--rebol--net]>
writes:
<<
[Robbo1Mark--aol--com]:
>> .... Having followed this thread with interest, I believe,
barring the disclaimer above, that both Joel & Ladislav are
WRONG in the sense that some REBOL behaviour can only be
explained and understood fully in terms of the way it has
been implemented.<<
That's a very bottom up way to think of things. When we
implement parts of REBOL we first sit down and say "how is
this supposed to work-- what are the rules it obeys." Once we
understand what something is supposed to do, then we write the
lower level code that does that thing we've figured out. It's
a process of describing in a low level, something you
understand at a high level. You're claiming to want to
understand something at a high level by considering how it is
expressed at a low level. That's like trying to understand
what an Elephant IS by looking at one of its cells under a
microscope. How do you even know what you're looking at is an
Elephant?
The way functionality is implemented is arbitrary as long as
it is reasonably space and cpu efficient and the
implementation behaves according to the high level
functionality that's desired. Joel's got this one on the head.
You gain little understanding of something like series by
trying to build series in C. You'll miss the forest for the
trees, so to speak.
Robbo:
>>To fully understand the behviour of any-block! or
any-string! series! values you have to have a model of how
series! values are implemented at the C code level from
which REBOL is built. ... Whilst any C code model we might
build for REBOL values... will most probably NOT exactly
match the RT official implementation, I think it is important
conceptually that we do TRY to conceptually build an
implementation model.<<
Joel:
>> C may be OK for giving examples, but it is certainly not
the only way to think about computing, IMHO.<<
Yes, but I think Mark's interest in having things
"explained" in terms of C code has less to do with
"understanding REBOL" at a high level, and more to do with
having people help "paint his fence", if you've ever read
Tom Sawyer. ;-)
-jeff
[91/114] from: robbo1mark:aol at: 19-Jun-2001 12:36
-- Attached file included as plaintext by Listar --
Return-Path: <[Robbo1Mark--aol--com]>
Received: from web28.aolmail.aol.com (web28.aolmail.aol.com [205.188.222.4]) by air-id07.mx.aol.com
(v79.20) with ESMTP id MAILINID76-0619114752; Tue, 19 Jun 2001 11:47:52 -0400
Date: Tue, 19 Jun 2001 11:47:50 EDT
From: [Robbo1Mark--aol--com]
Subject:Re: [REBOL] Re: On mutability and sameness
To: <[Robbo1Mark--aol--com]>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Mailer: Unknown (No Version)
Message-ID: <[a6--1588ac85--2860ce28--aol--com]>
Earlier I wrote....
Similarly....
>> a: <abc>
== <abc>
>> parse a [b:]
== false
>> b
== "123"
As Homer Simpson would famously say "D'oh!!!!!!"
it should read....
>> b
== "abc"
fingers working faster than the brain here... sorry!
Anyway the point is you can use this to prove that
B can be set as a string! copy of A regardless of whether you set A as a tag! , url!
, issue! , file! or whatever any-string! type value you fancy.
A & B remain as references to the SAME string! data in the same memory location, that
is why changes to either effect both.
Sorry for the typo earlier. 8-)
Still busily painting my fence here 8-)
Fancy helping me paint at the weekend Jeff? but please
don't bring only whitewash!
Only joking! honest!
Mark
In a message dated Tue, 19 Jun 2001 11:34:12 AM Eastern Daylight Time, Robbo1Mark writes:
<< JEFF,
I essence you are correct, but how easier can you more
properly explain these examples.....
>> a: "123"
== "123"
>> b: a
== "123"
>> c: "123"
== "123"
'a & 'b are the "SAME" string! and refer to the same memory location. 'c has the same
value on the surface
but is a separate instance of a string! value and is stored at a separate memory location.
That is why this....
>> insert b "abc"
== "123"
>> b
== "abc123"
>> a
== "abc123"
>> c
== "123"
The value of 'A & 'B both change but 'C remains unaltered. You can show this in 'C (
or some other language ) by use of pointers and references as Joel
did.
Similarly....
>> a: <abc>
== <abc>
>> parse a [b:]
== false
>> b
== "123"
How do you explain that unless you drop down to C or
something else and show your any-string! or any-block!
models with pointers to memory storage for the actual "data" values.
In the above example both reference the "Same" string!
data but 'a has the datatype! value tag! whilst 'b is
a normal string! datatype!
Sometimes to understand what's in a forest and what makes a forest you've got to look
at trees and leaves
and leaf / tree cells. Afterall thats how you really
UNDERSTAND trees & forests, even if it is from the
bottom up.
Also what is wrong with helping your neighbour to paint
his fence is you neighbour is your friend?
Depends who has more REBOL spirit, Huckleberry Finn
or Aunt Polly?
cheers Jeff 8-)
Mark Dickson
In a message dated Tue, 19 Jun 2001 11:01:20 AM Eastern Daylight Time, Jeff Kreis <[jeff--rebol--net]>
writes:
<<
[Robbo1Mark--aol--com]:
>> .... Having followed this thread with interest, I believe,
barring the disclaimer above, that both Joel & Ladislav are
WRONG in the sense that some REBOL behaviour can only be
explained and understood fully in terms of the way it has
been implemented.<<
That's a very bottom up way to think of things. When we
implement parts of REBOL we first sit down and say "how is
this supposed to work-- what are the rules it obeys." Once we
understand what something is supposed to do, then we write the
lower level code that does that thing we've figured out. It's
a process of describing in a low level, something you
understand at a high level. You're claiming to want to
understand something at a high level by considering how it is
expressed at a low level. That's like trying to understand
what an Elephant IS by looking at one of its cells under a
microscope. How do you even know what you're looking at is an
Elephant?
The way functionality is implemented is arbitrary as long as
it is reasonably space and cpu efficient and the
implementation behaves according to the high level
functionality that's desired. Joel's got this one on the head.
You gain little understanding of something like series by
trying to build series in C. You'll miss the forest for the
trees, so to speak.
Robbo:
>>To fully understand the behviour of any-block! or
any-string! series! values you have to have a model of how
series! values are implemented at the C code level from
which REBOL is built. ... Whilst any C code model we might
build for REBOL values... will most probably NOT exactly
match the RT official implementation, I think it is important
conceptually that we do TRY to conceptually build an
implementation model.<<
Joel:
>> C may be OK for giving examples, but it is certainly not
the only way to think about computing, IMHO.<<
Yes, but I think Mark's interest in having things
"explained" in terms of C code has less to do with
"understanding REBOL" at a high level, and more to do with
having people help "paint his fence", if you've ever read
Tom Sawyer. ;-)
-jeff
[92/114] from: robbo1mark:aol at: 19-Jun-2001 12:40
sorry if you receive this twice - AOL playing up today!
-- Attached file included as plaintext by Listar --
Return-Path: <[Robbo1Mark--aol--com]>
Received: from web36.aolmail.aol.com (web36.aolmail.aol.com [205.188.222.12]) by air-id09.mx.aol.com
(v79.20) with ESMTP id MAILINID98-0619123520; Tue, 19 Jun 2001 12:35:20 -0400
Date: Tue, 19 Jun 2001 12:35:19 EDT
From: [Robbo1Mark--aol--com]
Subject:Re: [REBOL] Re: On mutability and sameness
To: <"[rebol-list--rebol--com] ; Oscar-Project"@egroups.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Mailer: Unknown (No Version)
Message-ID: <[dd--1633808b--2860d948--aol--com]>
Everybody,
consider these examples of any-block! values
>> a: load "( 1 + 2 )"
== (1 + 2)
>> :a
== (1 + 2)
>> parse :a [b:]
== false
>> b
== [1 + 2]
>> a: make hash! [ add 3 4 ]
== make hash! [add 3 4]
>> parse :a [b:]
== false
>> b
== [add 3 4]
>> insert b 'negate
== [add 3 4]
>> b
== [negate add 3 4]
>> a
== make hash! [negate add 3 4]
>> a: make list! [ power 3 4 ]
== make list! [power 3 4]
>> parse :a [b:]
== false
>> b
== [power 3 4]
It seems that we can make instances of the same any-block!
data values even though the block!s are of different datatype!
eg Paren! Block! Hash! List! etc.
These too can be modified and changes to either effect both.
So for series! values we seem to have only 2 base implementation
models which are any-block! and any-string!, the rest are simply
a change in the datatype! field.
My model for series values has 4 fields which are
series.datatype
series.length ; Total number of values not length from index to tail
series.index ; the current series position
series.value ; the actual "data" values of the series which can be
; of any-type! for any-block! series and of
; char! for any-string! series.
I hope you find this model and examples helpful and instructive, I cannot
guarentee that this model is entirely accurate or complete, only that it's
seems to work at present.
Hopefully my friendly neighbours will help me "paint my fence" by helping
to show where this model breaks or is incomplete.
Cheers my REBOL friends ( of whom I sincerely hope includes Jeff & Holger
even though we may not always be in complete agreement! )
For the record Monet & Van Gogh are my favourite painters.
Impressionists of course! 8-)
Mark Dickson
[93/114] from: joel:neely:fedex at: 19-Jun-2001 11:29
Hi, Mark,
PMJI, but how about this explanation?
[Robbo1Mark--aol--com] wrote:
> JEFF,
> I essence you are correct, but how easier can you more
<<quoted lines omitted: 12>>
> >> c == "123"
> The value of 'A & 'B both change but 'C remains unaltered.
Excited by the brilliant future of REBOL, my wife and I move to
Ukiah. We open a joint account with our travel expense check of
$1,000. Similarly motivated, my unmarried son moves to Ukiah as
well, and opens an account with his travel expense check, also
$1,000.
At this point my son, my wife, and I would all reply to "What's
your balance?" by saying $1,000. Our balances are equal.
My son moves into an apartment, but my wife and I move into a
house with a yard. Therefore I drive to the store and by a
garden hose and sprinkler for $20, paying by check.
Now if you ask either me or my wife "What's your balance?" we'll
have to answer $980, while my son will answer the same question
by saying $1,000.
The difference is this: initially we had EQUAL? accounts, but
my wife and I have the SAME? account. Therefore, either of us
can write a check that affects our shared balance, but none of
those checks affects our son's balance, because his account is
not the SAME? as ours, even though it was originally EQUAL? to
ours.
> You can show this in 'C ( or some other language ) by use of
> pointers and references as Joel did.
>
You *can* show it using C (although I wish I hadn't ;-), but
it's not *necessary* to do so.
-jn-
___ ___ ___
\/ 2 + \/ 2 = 4 (for sufficiently large approximations of \/ 2 )
joel'dot'neely'at'fedex'dot'com
[94/114] from: jeff:rebol at: 19-Jun-2001 10:44
Hello, Robbo:
> JEFF,
> I essence you are correct, but how easier can you more
<<quoted lines omitted: 9>>
> separate instance of a string! value and is stored at a
> separate memory location.
I think explaining the above in C is vastly more complex than
explaining it in terms REBOL has already established. You may
very well wreak havoc on the understanding people DO have of
the above by trying to explain it using C.
'A and 'B are both different words. They are NOT strings.
Both words refer to (have the value of) the same string. 'C
is also a different word than 'A and 'B. It refers to a
different value (a different string).
These particular notions of WORDS and VALUES are a distinct
aspect of REBOL and they are not an aspect of C. WORDS and
VALUES are within in the vocabulary of REBOL, but they are not
to be found in the vocabulary of C. C's typed variables are
an especially poor analogy to REBOL WORDS, for example please
describe the following in C:
word: 1
word: make object! [word: func [][print "I am a function"]]
word: word/word
word: 'word
I can easily explain the above in terms of WORDS and VALUES,
but I would find it very difficult to explain in terms of C's
typed variables and pointers. That's like explaining calculus
using Lincoln Logs.
REBOL is first class and EVERYTHING is data. This concept is
utterly absent from C. Please provide an example of how one
may understand the nature of REBOL's first class code/data
duality with C code.
> That is why this....
> >> insert b "abc"
<<quoted lines omitted: 7>>
> The value of 'A & 'B both change but 'C remains unaltered. You can show this in 'C
( or some other language ) by use of pointers and references as Joel
> did.
..."or some other language".. hmmm.. what would be a good
language for describing REBOL... hmmm... maybe REBOL? It's
its own metalanguage, afterall! :-)
> Similarly....
> >> a: <abc>
<<quoted lines omitted: 9>>
> data but 'a has the datatype! value tag! whilst 'b is
> a normal string! datatype!
Well, you might start by understanding that in REBOL there are
WORDS and WORDS can refer to VALUES. (Words are VALUES
themselves, by the way.) Once you have those concepts firmly
in hand, move onto understanding how PARSE treats set-words in
a rule.
Would you explain the movement of the knight in chess in terms
of the way you play checkers?
> Also what is wrong with helping your neighbour to paint
> his fence is you neighbour is your friend?
It depends on the informed consent of the fence painter, and
who claims credit for the fence being painted. :-)
-jeff
[95/114] from: robbo1mark:aol at: 19-Jun-2001 7:27
Joel Neely
< snip >
Iam not trying to reverse engineer REBOL......
< snip >
Ladislav Mecir
< snip >
Iam not trying to make discoveries or
statements about REBOL implementation
details.......
< snip >
; disclaimer, I'm not sure if I've quoted
; Joel & Ladislav here precisiely word for
; word, I don't have thier original postings
; & docs to hand, but I think these statements
; portray accurately what they were trying to
; convey. Sincere apologies if I misrepresent
; them in any way!
With the utmost respect to both Joel & Ladislav
whom I admire & respect both greatly, and thank
them for the knowledge and insight I gained from
them with their thoughtful & considered posts
and documents.
Having followed this thread with interest, I
believe, barring the disclaimer above, that
both Joel & Ladislav are WRONG in the sense
that some REBOL behaviour can only be explained
and understood fully in terms of the way it
has been implemented.
Now I know that both Joel & Ladislav and myself
are all striving for basically the same thing.
We want to REALLY UNDERSTAND REBOL.
REALLY UNDERSTANDING REBOL means having an
accurate model & conception of the structure
of REBOL that can properly predict REBOL
behaviour for any given function or datatype.
To me this "understanding" means how REBOL is
implemented as well. Now as we all know REBOL
is not open source and only Carl & the RT gang
can truly know it's inner secrets & full
implementation details & specification.
Holger Kruse also stated that users shouldn't
speculate about the precise implementation
details as this can vary between CPU, platform
etc. This is a valid point in as much as it is
true however it does not aid us in our quest
to understand REBOL and it puts us in a position
of dependancy on RT to clarify further or reveal
parts of REBOL secrets / mystery we don't fully
grasp. Sometimes they are very good and they do
explain things more fully at other they say either
nothing or nothing helpful as it may impinge on
REBOL's proprietary-ness.
Joel & Ladislav both find areas where the existing
REBOL documentation and / or REBOL behaviour is
either misleading, inconsistent, confusing, not
fully or properly documented, or sometimes in their
opinion
wrong!
Though they sometimes disagree / agree to disagree,
and appear to come at things from conflicting
angles or viewpoints, in essence they strive for
the same thing and that is to UNDERSTAND REBOL
and be able to describe / document concisely
and comprehensively ( and consistently ) REBOL values
and behaviour.
Forgive me if Iam wrong, but I think Joel is seeking
a fully comprehensive understanding and Ladislav seeks
clarity, simplicity, purity and consistency. These are
NOT mutually exclusive.
However I think they are wrong to believe they can fully
and properly achieve this without geting down to the nitty
gritty of implementation details where necessary.
To fully understand the behviour of any-block! or any-string!
series! values you have to have a model of how series! values
are implemented at the C code level from which REBOL is built.
The behaviour of series! and their associated functions are
direct result of the way they are implemented in C. The same
applies to whether set-words or set-paths etc. create a new
instance or copy of a value or merely reference existing
value data.
Whilst any C code model we might build for REBOL values, whether
they be "simple" values like integer! or char!, series! values
like block! string! etc. or compound values like date! time!
tuple! etc. will most probably NOT exactly match the RT official
implementation, I think it is important conceptually that we
do TRY to conceptually build an implementation model.
What is important is NOT that we precisely match the official
REBOL implementation from scratch, that would be impossible
as we are essentially working blind and cannot know all the
platform specifics in advance.
Rather it is important that we build our model then incrementally
refine / modify & improve it in view of further tests, errors, new
and better models. What in essence we are doing is subjecting our
Model to a "Turing Test", if it is capable of producing the same
results and behaviour as REBOL then for all intents and purposes
it is a valid working model of REBOL, regardless of number of bits
per value etc.
Charles Moore of Forth fame has been quoted "To fully understand
your tools you have to build / re-build them yourself from scratch."
Now Chuck Moore is famously an extreme perfectionist and harsh
taskmaster but there is a strong element of truth and wisdom here.
On the otherhand there is also the saying "if you want to create
an omelette from scratch, you have to devise a way of re-creating
the Big Bang". Hopefully we don't have to go that far back or
that "low level" 8-)
I liked Joel's recent example of an equivalence test using C code
to display strings as char pointers, char arrays, variable references
etc. This example showed how to produce a boolean true or false
that mimics actual REBOL behaviour.
Unless REBOL Technologies produce the "REALLY UNDERSTANDING REBOL" book
subtitle: REBOL Implementation Explained for Tech. Experts & Hackers
then to gain the knowledge and clarity we seek I think it's inevitable
sometimes we will have look under the hood and build our model upwards
from C code to properly understand and explain topics of debate and / or
dispute, regardless of whether we get the bit numbers slighlty wrong.
Just like my eyes and hair are brown is controlled by my genetics,
REBOL is an extension of it's implementation in C. One is a direct
result of the other.
Credit to Joel, Ladislav and others for the high quality and insight
of posts thus far.
Cheers,
Mark Dickson
In a message dated Sun, 17 Jun 2001 1:44:03 PM Eastern Daylight Time, "Ken Anthony"
<[kenneth--nwinet--com]> writes:
<< Joel,
Much appreciation for your discussions in this list.
> Kind of datatype Comparison to be performed
> ---------------- --------------------------
<<quoted lines omitted: 5>>
> tells whether the current value of a word is of a reference
> type.
May I propose or suggest that RT consider adding a 'simple?' function (the
word seems to be common to the thread whereas sharable? seems to add a
nuiance not explicit in your chart above) which could act as a lawman for
these issues.
> sharable?: func ['w [word!]] [
> found? any [
<<quoted lines omitted: 15>>
> for the "ordinary data" cases, but it may require tweaking
> for the more esoteric REBOL-specific types.
But I *want* warranties!
Deputy, round up a posse! I have a warrant here for any genius language
designer that leaves too many undefined issues hanging around the saloon. I
don't give a lick for what that there Godel hombre has to say about it.
While we're at it, let's throw in a few divide by zero's laws just for
kicks. It may be infinity to those there mathmatical fella's, but us
programmer's around these here parts usually just define the result to be
zero.
But Sheriff, my boy told me that 0/0 is undefined soes we might as well make
a law that it's ta be nought... wouldn't it be more correct for sum number
there divided by nought to be a really big number like those mathmedical
fella's says?
Now deputy, if they want to test for zero, they can test for zero, but I'm
telling ya we got ta have a civilized town here. That means no shootin'
irons in the town limits and zero begets zero whether ya multiply or divide.
Well I don't rightly know Sheriff, sounds kinda dangerous like to cipher
thata way.
BTW, Sheriff didya notice they got this cp thing that does the same thang as
copy?
I saw that there deputy, and I plan to make eunix atta those there rustlers
as soon as we get this zero issue all cleared up. Now let's go down to the
corral and see what Ike and his boys are up to.
OK.
Well of course.
[96/114] from: joel:neely:fedex at: 20-Jun-2001 13:31
Hi, Mark, and all
While discussing this thread with one of my esteemed collegues,
she made an obervation I thought worth sharing...
[Robbo1Mark--aol--com] wrote:
> It is for this reason that you sometimes have to use C or
> Java or something else to "explain" or implement REBOL.
>
So what is it that we have to have to "explain" C?
Couldn't we use that (whatever it is) to explain REBOL,
and dispense with C altogether?
--
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[97/114] from: robbo1mark:aol at: 20-Jun-2001 14:38
JEFF,
You are *as usual* mostly right.
Iam not on a PR campaign, yes I do want an "open" REBOL
and NO Iam in no way as clued up as all you supremely talented guys at REBOL.
I DO want an open REBOL now, as I'm a tinkerer at heart as well as being impatient! that's
not a crime though.
I take on board what you say, honestly! If REBOL was open I could study away at it to
my hearts content and not bother anybody.
But it's not and so I'll just have to keep on trying to master REBOL *AND* attempt to
understand it's implementation, if my brain is big enough for that capacity! 8-)
Yes I DO understand that that is a gargantuan task and I will make lots of mistakes and
bloopers along the way.
Sure there is no way I can truly understand Carl's genius, it took him 20 years, but
by trying to glean whatever I can from whomever I can will help me / us along the way.
I DO have some friend who share this goal too!
If it means we make a right pigs ear of things then at least we will learn from that
and make it better in the next revision, people will be able to see where things are
done badly or wrong and make it better, is that not what open source is all about?
I DO want REBOL to succeed, you must believe that, Iam also a naughty boy sometimes and
suppose am guilty of being provocative and wind people up sometimes, sorry I honestly
don't mean to personally offend anyone, it's just the way Iam I guess.
Thanks for your help and advice!
cheers,
Mark
In a message dated Wed, 20 Jun 2001 1:06:48 PM Eastern Daylight Time, nop <[whip--cs--unm--edu]>
writes:
<<
Hello, Robbo.
[Jeff emailing from his school account --
rebol.net looks down right now]
> REBOL AS IT'S OWN META-LANGUAGE
>
> I've read recently from Jeff & Joel, and other's in the previously,
> that REBOL is it's own meta-language.
>
> This is bunk! or at least only partially true.
No, it's not bunk.
> Consider this model of REBOL addition...
> >> add: func [ x y ] [ + x y ] add 1 2
<<quoted lines omitted: 3>>
> >> set '+ func [ x y ] [ add x y ]
> On the surface it looks okay, but try....
No, on the surface it doesn't look okay at all. You've defined the
function ADD to depend on the function +, and you've defined + to
depend on the function ADD. Something eventually has to
be able to actually add two numbers.
> >> add 4 5
> ** Internal Error: Stack overflow Near: add x y
<<quoted lines omitted: 3>>
> Your into infinite recursion here, so REBOL as a complete
> meta-language is "insufficient".
So, I don't really understand. What are you trying to demonstrate
with the above?
. . .
> If this was the case there would be no need for RT Inc. to write
> any more interpreters, we could simply write and extend REBOL in and
> from REBOL and we'd all live happily ever after.
Written many dialects?
> Unfortunitely there are these "irreducibles" or "primitives" that
> you simply MUST have to get the system up and running.
>
> It is for this reason that you sometimes have to use C or Java or
> something else to "explain" or implement REBOL.
You don't "HAVE TO" use a low level language to "explain" a high
level language.
> You can however devise a way to construct these "primitives" from
> within REBOL / your "meta-language" then you get into the realms and
> possibilities of META-COMPILATION which is a system written in
> itself, however you still have to bootstrap the whole process from
> something else first whether this be Assembler or C or Java or
> whatever.
Are you sure this is necessary? Have you tried, or are you
just speculating here?
> Forth proves this is possible and has had this capability for nearly
> thirty years now, maybe someday REBOL will catch up & we'll be
> dispensed with the need for RT to write our REBOL interpreters for
> us, if we so choose of course. 8-)
That's right.. How uncool of RT to be writing our REBOL
interpreters for us. The nerve of them!
> Oh Dear, why am I always so contrary?
I figure it's part of your PR effort. Play up on that martyr
kind of thing.. :-)
> I don't know about painting that fence Jeff, maybe I should come
> round from the wrong side of it and you can break the fence apart &
> hit me over the head with it!
See, if you ask me, which you haven't, you're going about this all
wrong. You're running out and rather recklessly trying to implement
(or actually, trying to get someone else to implement for you) a
language of great design and forethought (nearly 20 years in design
and many man years of implementation) and yet you consistently seem
to demonstrate rather questionable mastery of REBOL.
If I were you and I was trying to clone REBOL, I'd do the following:
First, become a true REBOL guru, mastering REBOL to a fine art,
including all its different areas: dialecting, introspection,
metaprogramming, networking, GUI, etc... True REBOL gurus can
explain why there is dialecting in REBOL, how to make user defined
ports, the reasoning behing MOLD/only, or LOAD/all, etc.. With all
this understanding of the language, I'd help 1,000 newbies into the
language. Now once my expertise in REBOL was solid and sure, and my
commitment to the beauty of the design was complete, then and only
then would I embark on the journey to clone REBOL.
Here's my recommendations for the cloning phase (which you've
already jumped ahead to):
A. Drop the hokey PR gig.
B. Produce something. Actions speak louder than words.
What to produce? Well, an actual interpreter written in some
compiled language is a lot to expect right away (or for a very long
time). Unrealistic expectations are bad for any development
project. The most rational approach would be to try and implement
REBOL in REBOL first. You can learn a great deal more about the
rules of the language as you put it together, and a working REBOL
implementation of REBOL counts as producing something (you can
actually take credit for having done something other than yack).
Once you've gone through those exercises before actually attempting
something compiled, the likelihood of you groking many of the finer
aspect's of Carl's awesome design will be higher. Also, with that
understanding of the design, the likelihood will be much lower that
you'll end up creating some super mangled REBOL-like language that's
only vaguely related and inappropriately compared.
I only bring this all up because I think it's great that you're
trying to clone REBOL, but like I've said, your approach just shocks
my esthetics and sensibilities. (-8 I sort of think you want to
have it all now, but I suspect you may have to live with RT writing
your REBOL interpreter for you for a while yet...
Just my opinion-- Best of luck!
-jeff
[98/114] from: robbo1mark:aol at: 20-Jun-2001 14:44
Joel,
sorry if I misquoted you, I think now I was actually referring to your comments about
Ladislav wanting a complete self contained meta-system.
Thats' probably where my confusion arose.
I don't know if you saw this earlier
>> increment: func [x] [return abs complement x]
>> increment 1
== 2
>> increment 0
== 1
increment is adding by one, naturally, complement is doing the binary inversion I believe,
absolute makes it positive, tara! increment!
cheers Joel
Mark
In a message dated Wed, 20 Jun 2001 1:15:23 PM Eastern Daylight Time, Joel Neely <[joel--neely--fedex--com]>
writes:
<< Hi, Mark,
Just two remarks...
[Robbo1Mark--aol--com] wrote:
> REBOL AS IT'S OWN META-LANGUAGE
>
> I've read recently from Jeff & Joel, and other's
> in the previously, that REBOL is it's own meta-language.
>
> This is bunk! or at least only partially true.
>
I've never said that "REBOL is its own meta-language".
I accept full responsibility (for good or ill ;-) for any
of my utterances, but prefer not to have ideas attributed
to me unless I've actually said (and believe) them.
> Consider this model of REBOL addition...
>
> >> add: func [ x y ] [ + x y ]
> >> add 1 2
> == 3
>
> Fine so far, however how do you define the '+ in
> the function body?
>
Here's the majority of it ...
bitstring: func [n [integer!] /local bv bt] [
bt: copy ""
bv: 1
until [
append bt either 0 < (n and bv) [#"1"] [#"0"]
any [
error? try [bv: bv + bv]
n < bv
]
]
bt
]
add1: func [a [char!] b [char!] c [char!]] [
select [
"000" [#"0" #"0"]
"001" [#"1" #"0"]
"010" [#"1" #"0"]
"011" [#"0" #"1"]
"100" [#"1" #"0"]
"101" [#"0" #"1"]
"110" [#"0" #"1"]
"111" [#"1" #"1"]
] to-string reduce [a b c]
]
add2: func [aa [string!] bb [string!] /local cc a b s c] [
s: c: #"0"
cc: copy ""
while [(length? aa) < (length? bb)] [append aa #"0"]
while [(length? bb) < (length? aa)] [append bb #"0"]
until [
set [s c] add1 first aa first bb c
append cc s
aa: next aa
tail? bb: next bb
]
if c = #"1" [append cc c]
cc
]
adder: func [a [integer!] b [integer!]] [
head reverse add2 bitstring a bitstring b
]
.. which behaves as
>> adder 2 2 == "100"
>> adder 2 20 == "10110"
>> adder 15 200 == "11010111"
Since REBOL is implemented on binary computers, one must
understand binary in order to have a complete understanding
of REBOL. Therefore translating the output of ADDER back
to decimal is, of course, totally unnecessary.
The final details of handling negatives and overflows are,
as the saying goes,
"left as an exercise to the reader".
Have fun! ;-)
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[99/114] from: robbo1mark:aol at: 20-Jun-2001 14:48
Hello Jeff,
> You can however devise a way to construct these "primitives" from
> within REBOL / your "meta-language" then you get into the realms and
> possibilities of META-COMPILATION which is a system written in
> itself, however you still have to bootstrap the whole process from
> something else first whether this be Assembler or C or Java or
> whatever.
Are you sure this is necessary? Have you tried, or are you
just speculating here?
No not speculating, just what I learned from studying implementations of interpreters
form Guile / Scheme / Forth etc. as well as some compiler theory I also read.
If you guys don't make REBOL from C or some other compileable language, how do you else
do you make it.
Two puppy dogs tails, some snake poison and a healthy dose of abracadabra?
sorry!
Mark
In a message dated Wed, 20 Jun 2001 1:06:48 PM Eastern Daylight Time, nop <[whip--cs--unm--edu]>
writes:
<<
Hello, Robbo.
[Jeff emailing from his school account --
rebol.net looks down right now]
> REBOL AS IT'S OWN META-LANGUAGE
>
> I've read recently from Jeff & Joel, and other's in the previously,
> that REBOL is it's own meta-language.
>
> This is bunk! or at least only partially true.
No, it's not bunk.
> Consider this model of REBOL addition...
> >> add: func [ x y ] [ + x y ] add 1 2
<<quoted lines omitted: 3>>
> >> set '+ func [ x y ] [ add x y ]
> On the surface it looks okay, but try....
No, on the surface it doesn't look okay at all. You've defined the
function ADD to depend on the function +, and you've defined + to
depend on the function ADD. Something eventually has to
be able to actually add two numbers.
> >> add 4 5
> ** Internal Error: Stack overflow Near: add x y
<<quoted lines omitted: 3>>
> Your into infinite recursion here, so REBOL as a complete
> meta-language is "insufficient".
So, I don't really understand. What are you trying to demonstrate
with the above?
. . .
> If this was the case there would be no need for RT Inc. to write
> any more interpreters, we could simply write and extend REBOL in and
> from REBOL and we'd all live happily ever after.
Written many dialects?
> Unfortunitely there are these "irreducibles" or "primitives" that
> you simply MUST have to get the system up and running.
>
> It is for this reason that you sometimes have to use C or Java or
> something else to "explain" or implement REBOL.
You don't "HAVE TO" use a low level language to "explain" a high
level language.
> You can however devise a way to construct these "primitives" from
> within REBOL / your "meta-language" then you get into the realms and
> possibilities of META-COMPILATION which is a system written in
> itself, however you still have to bootstrap the whole process from
> something else first whether this be Assembler or C or Java or
> whatever.
Are you sure this is necessary? Have you tried, or are you
just speculating here?
> Forth proves this is possible and has had this capability for nearly
> thirty years now, maybe someday REBOL will catch up & we'll be
> dispensed with the need for RT to write our REBOL interpreters for
> us, if we so choose of course. 8-)
That's right.. How uncool of RT to be writing our REBOL
interpreters for us. The nerve of them!
> Oh Dear, why am I always so contrary?
I figure it's part of your PR effort. Play up on that martyr
kind of thing.. :-)
> I don't know about painting that fence Jeff, maybe I should come
> round from the wrong side of it and you can break the fence apart &
> hit me over the head with it!
See, if you ask me, which you haven't, you're going about this all
wrong. You're running out and rather recklessly trying to implement
(or actually, trying to get someone else to implement for you) a
language of great design and forethought (nearly 20 years in design
and many man years of implementation) and yet you consistently seem
to demonstrate rather questionable mastery of REBOL.
If I were you and I was trying to clone REBOL, I'd do the following:
First, become a true REBOL guru, mastering REBOL to a fine art,
including all its different areas: dialecting, introspection,
metaprogramming, networking, GUI, etc... True REBOL gurus can
explain why there is dialecting in REBOL, how to make user defined
ports, the reasoning behing MOLD/only, or LOAD/all, etc.. With all
this understanding of the language, I'd help 1,000 newbies into the
language. Now once my expertise in REBOL was solid and sure, and my
commitment to the beauty of the design was complete, then and only
then would I embark on the journey to clone REBOL.
Here's my recommendations for the cloning phase (which you've
already jumped ahead to):
A. Drop the hokey PR gig.
B. Produce something. Actions speak louder than words.
What to produce? Well, an actual interpreter written in some
compiled language is a lot to expect right away (or for a very long
time). Unrealistic expectations are bad for any development
project. The most rational approach would be to try and implement
REBOL in REBOL first. You can learn a great deal more about the
rules of the language as you put it together, and a working REBOL
implementation of REBOL counts as producing something (you can
actually take credit for having done something other than yack).
Once you've gone through those exercises before actually attempting
something compiled, the likelihood of you groking many of the finer
aspect's of Carl's awesome design will be higher. Also, with that
understanding of the design, the likelihood will be much lower that
you'll end up creating some super mangled REBOL-like language that's
only vaguely related and inappropriately compared.
I only bring this all up because I think it's great that you're
trying to clone REBOL, but like I've said, your approach just shocks
my esthetics and sensibilities. (-8 I sort of think you want to
have it all now, but I suspect you may have to live with RT writing
your REBOL interpreter for you for a while yet...
Just my opinion-- Best of luck!
-jeff
[100/114] from: robbo1mark:aol at: 20-Jun-2001 14:59
JOEL,
that is precisely my point, REBOL cannot completely describe or implement REBOL completely,
just as C had to be written in something else first, assembly, which is written in machine
code, which is implemented in hardware, which is based on quantum electronics / physics,
which is written in mathematics, which is written in symbols on ink on paper, which is
made of wood, which is organic materials, made on bio-chemistry according to the laws
of chemistry / physics / mathematics / ad-infinitum!
But in computing terms you CAN start somewhere and that is at the MACHINE level and build
up from there.
Whether this is easy or clarifies things probably not, but is can be done and IS how
things are done.
You cannot yet completely implement ALL of REBOL in REBOL but with a C Compiler ( just
guessing! ) you CAN write a REBOL interpreter, and you can do it in JAVA, see FREEBELL,
so you CAN safely drop down to that level if need be. YOU did so to prove a point about
equality and sameness!
cheers,
Mark
In a message dated Wed, 20 Jun 2001 2:47:46 PM Eastern Daylight Time, Joel Neely <[joel--neely--fedex--com]>
writes:
<< Hi, Mark, and all
While discussing this thread with one of my esteemed collegues,
she made an obervation I thought worth sharing...
[Robbo1Mark--aol--com] wrote:
> It is for this reason that you sometimes have to use C or
> Java or something else to "explain" or implement REBOL.
>
So what is it that we have to have to "explain" C?
Couldn't we use that (whatever it is) to explain REBOL,
and dispense with C altogether?
--
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[101/114] from: joel:neely:fedex at: 20-Jun-2001 15:06
Hello, all!
[Robbo1Mark--aol--com] wrote:
> You cannot yet completely implement ALL of REBOL in REBOL
> but with a C Compiler ...
> ... you CAN safely drop down to that level if need be. YOU
> did so to prove a point about equality and sameness!
>
I knew better at the time, but haste overruled common sense.
I hereby apologize to one and all for using the "c" word.
If I promise never to do it again, will you let me forget
that I did so? ;-)
-jn-
--
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[102/114] from: joel:neely:fedex at: 20-Jun-2001 15:12
Hi, Mark,
[Robbo1Mark--aol--com] wrote:
> which is based on quantum electronics / physics, which is
> written in mathematics...
>
NO! Our mathematical models are only human attempts to model
what happens at the QM level, they are *not* the foundation of
what happens at that level. QM did whatever it did before there
were humans *or* mathematics.
> which is written in mathematics, which is written in symbols
> on ink on paper.
>
Mathematics isn't about a particular set of symbols nor
dependent a particular publication medium.
The history of modern mathematics is about the process of weaning
mathematics from dependence on any application and on a priori
assumptions, and placing it on a formal axiomatic basis.
The whole point of a formal scheme is that one can "bootstrap"
a self-consistent system out of a set of axioms with no
dependence on anything but itself. Full stop.
> But in computing terms you CAN start somewhere and that is at
> the MACHINE level and build up from there.
>
Mathematics *is* the "science" in "computing science". Not c.
If you want to do something constructive, how about trying your
hand at describing some part of REBOL behavior in clear enough
terms that:
1) it provides testable predictions,
2) it can be used to explain (part of) REBOL to a newcomer,
3) it doesn't require use of anything but REBOL, logic,
and mathematics.
I will be perfectly happy to lend a hand in debugging any such
models (as I hope I have been happy to have debugging and advice
regarding the ones I've proposed).
OTOH, I have nothing further to add to any discussions of whether
REBOL should be open source. It isn't. I got over it. Long ago.
I look forward to seeing some usable models!
--
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[103/114] from: holger:rebol at: 20-Jun-2001 13:41
On Wed, Jun 20, 2001 at 02:59:13PM -0400, [Robbo1Mark--aol--com] wrote:
> You cannot yet completely implement ALL of REBOL in REBOL but with a C Compiler ( just
guessing! ) you CAN write a REBOL interpreter, and you can do it in JAVA, see FREEBELL,
so you CAN safely drop down to that level if need be. YOU did so to prove a point about
equality and sameness!
You are confusing some computer science concepts ("meta language", "bootstrapping" etc.).
A Turing Machine can implement any computer language in existance. Similarly, almost
every computer language in existance can implement a Turing Machine. It follows that
almost
every language can implement almost every other language. REBOL is powerful enough
to implement a Turing Machine (very easy, actually, with REBOL's powerful series operations),
so REBOL can be used to implement any language, including itself. Java is not inherently
more powerful than REBOL, as far as expressiveness of the language (and thus the ability
to
implement other languages) is concerned.
In order to be able to actually execute any code you, of course, need a method to get
down
to the assembly layer, but ideally this is only needed once, when you create your runtime
environment, for bootstrapping. It is not necessary afterwards. For instance, gcc is
written
completely in C. No assembly language needed, but in order to compile gcc you DO need
another
C compiler, in assembly language, that first compiles gcc, but only once, and it can
even
run on a different machine, even a different type of CPU, with cross-compilation.
Afterwards gcc can compile itself. That's what is meant by "bootstrapping".
Large portions of REBOL are actually written in REBOL, and REBOL is used extensively
in the
build process to create makefiles, manage components, products, licenses, run tests etc.
It would
theoretically be possible to implement REBOL completely in REBOL. (Of course, since REBOL
is
an interpreted language, at runtime you would still need another REBOL interpreter in
another
language which interprets the REBOL interpreter that is written in REBOL and interprets
your
scripts :-), but that is a different issue).
The point is that only with complete *behavioral* specs (which, admittedly, have not
been
published or even defined yet), without any information about the implementation, it
would
be possible to implement REBOL in whatever language you choose. It could even be REBOL.
The language you choose is irrelevant as long as it is powerful enough to implement a
Turing
Machine (or a GOTO-machine or any other abstraction that is computationally equivalent
to a
Turing Machine).
As for REBOL being its own meta language. That is mostly an issue of how syntax and semantics
are related by the language definition. REBOL being its own meta language basically means
that
you can make formal statements *about* REBOL *in* REBOL.
The concept of a language being its own meta language is very powerful, because you can
apply it recursively to get an infinite hierarchy of meta languages, all using the same
syntax (and thus effectively being a single language, but with different semantic
interpretations at different levels). REBOL allows you to express multiple semantic levels
in the same syntax, using the same language concepts, interpreted dynamically. The key
to this is the way words and blocks provide a unified method of expressing code and data.
--
Holger Kruse
[holger--rebol--com]
[104/114] from: chris:starforge at: 19-Jun-2001 17:41
#19-Jun-01# Message from *Jeff Kreis*:
Hi Jeff,
> functionality that's desired. Joel's got this one on the head.
> You gain little understanding of something like series by
> trying to build series in C. You'll miss the forest for the
> trees, so to speak.
Just to play devil's advocate for a moment...
On several occasions I have found myself in a situation where I needed to
know how Rebol does something. How series were represented is one of the
things I asked about some time ago, I expect there will be others (I have
one about strings, memory allocation and copying in the queue ATM). Not out
of interest as such, but in order to use the most correct algorithm to match
the representation. I freely admit that for general use, these levels of
details certainly aren't important - but when you're pushing the envelope,
you NEED to know, at least in general terms, what you're working with.
What I think REBOL is lacking is a rigid language spec, or at least a
document that tells REBOL hackers about the time and space complexity of
major datatypes and operations. Without this sort of information, it is
very easy to end up using something with linear or exponential cost, when
a constant cost alternative is actually avilable. There is no need to
--
New sig in the works
Explorer 2260, Designer and Coder
http://www.starforge.co.uk
--
A sine curve goes off to infinity or at least the end of the blackboard
-- Prof. Steiner
[105/114] from: doublec:acc at: 21-Jun-2001 10:53
Are you saying that you can't implement a REBOL interpreter in REBOL? I think you'd be
wrong there...
Chris.
[106/114] from: robbo1mark:aol at: 20-Jun-2001 5:34
D'oh!!!!!
stupid stupid stupid Mark!
Of course defining '+ should read
>> set '+ func [x y] [add x y]
That way it works as I Intended.
Sorry again! folks.
Mark
-- Attached file included as plaintext by Listar --
Return-Path: <[Robbo1Mark--aol--com]>
Received: from web51.aolmail.aol.com (web51.aolmail.aol.com [205.188.161.12]) by air-id07.mx.aol.com
(v79.20) with ESMTP id MAILINID75-0620052012; Wed, 20 Jun 2001 05:20:12 -0400
Date: Wed, 20 Jun 2001 05:20:10 EDT
From: [Robbo1Mark--aol--com]
Subject:Re: [REBOL] Re: On mutability and sameness
To: <[rebol-list--rebol--com]>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
X-Mailer: Unknown (No Version)
Message-ID: <[43--16dad16d--2861c4cc--aol--com]>
REBOL AS IT'S OWN META-LANGUAGE
I've read recently from Jeff & Joel, and other's
in the previously, that REBOL is it's own meta-language.
This is bunk! or at least only partially true.
Yes for any particular instance or behaviour you can
generally write a rebol function or object to model
it's behaviour but you cannot do this for the "entirety"
REBOL, sooner or later you run into irreducibility.
Consider this model of REBOL addition...
>> add: func [ x y ] [ + x y ]
>> add 1 2
== 3
Fine so far, however how do you define the '+ in
the function body?
If you say
>> set 'x func [ x y ] [ add x y ]
On the surface it looks okay, but try....
>> add 4 5
** Internal Error: Stack overflow
** Near: add x y
>> + 4 5
** Internal Error: Stack overflow
** Near: add x y
>>
Your into infinite recursion here, so REBOL as a complete
meta-language is "insufficient".
However this is NOT a slight on REBOL just a fact about
the notion of meta-languages, you CAN'T have a complete
& self contained descriptive system.
Here's a quote from Chuck Moore about Forth which equally
applies to REBOL
I like to quote Goedel on this, it goes back to 1930.
he proved that a self contained formal system cannot be
contained. horribly non- sequator but, all right within
a system you can't describe itself. Within forth you can't
describe Forth. Well, our systems are not so esoteric
as Goedel's but I think you can say that within a system
you cannot describe it simply.
Now yes it is "preferable" to use REBOL to describe REBOL
whenever possible as this should lead to "less" confusion
however you simply "cannot" completely model REBOL in REBOL
as a whole entity.
If this was the case there would be no need for RT Inc.
to write any more interpreters, we could simply write and
extend REBOL in and from REBOL and we'd all live happily
ever after.
Unfortunitely there are these "irreducibles" or "primitives"
that you simply MUST have to get the system up and running.
It is for this reason that you sometimes have to use C or
Java or something else to "explain" or implement REBOL.
You can however devise a way to construct these "primitives"
from within REBOL / your "meta-language" then you get into
the realms and possibilities of META-COMPILATION which is
a system written in itself, however you still have to
bootstrap the whole process from something else first whether
this be Assembler or C or Java or whatever.
Forth proves this is possible and has had this capability for
nearly thirty years now, maybe someday REBOL will catch up &
we'll be dispensed with the need for RT to write our REBOL
interpreters for us, if we so choose of course. 8-)
Oh Dear, why am I always so contrary? I don't know about painting
that fence Jeff, maybe I should come round from the wrong side
of it and you can break the fence apart & hit me over the head
with it!
; see I can be "light hearted" sometimes!
Cheers my REBOL friends.
Mark Dickson
In a message dated Tue, 19 Jun 2001 2:16:27 PM Eastern Daylight Time, Jeff Kreis <[jeff--rebol--net]>
writes:
<<
Hello, Robbo:
> JEFF,
> I essence you are correct, but how easier can you more
<<quoted lines omitted: 9>>
> separate instance of a string! value and is stored at a
> separate memory location.
I think explaining the above in C is vastly more complex than
explaining it in terms REBOL has already established. You may
very well wreak havoc on the understanding people DO have of
the above by trying to explain it using C.
'A and 'B are both different words. They are NOT strings.
Both words refer to (have the value of) the same string. 'C
is also a different word than 'A and 'B. It refers to a
different value (a different string).
These particular notions of WORDS and VALUES are a distinct
aspect of REBOL and they are not an aspect of C. WORDS and
VALUES are within in the vocabulary of REBOL, but they are not
to be found in the vocabulary of C. C's typed variables are
an especially poor analogy to REBOL WORDS, for example please
describe the following in C:
word: 1
word: make object! [word: func [][print "I am a function"]]
word: word/word
word: 'word
I can easily explain the above in terms of WORDS and VALUES,
but I would find it very difficult to explain in terms of C's
typed variables and pointers. That's like explaining calculus
using Lincoln Logs.
REBOL is first class and EVERYTHING is data. This concept is
utterly absent from C. Please provide an example of how one
may understand the nature of REBOL's first class code/data
duality with C code.
> That is why this....
> >> insert b "abc"
<<quoted lines omitted: 7>>
> The value of 'A & 'B both change but 'C remains unaltered. You can show this in 'C
( or some other language ) by use of pointers and references as Joel
> did.
.."or some other language".. hmmm.. what would be a good
language for describing REBOL... hmmm... maybe REBOL? It's
its own metalanguage, afterall! :-)
> Similarly....
> >> a: <abc>
<<quoted lines omitted: 9>>
> data but 'a has the datatype! value tag! whilst 'b is
> a normal string! datatype!
Well, you might start by understanding that in REBOL there are
WORDS and WORDS can refer to VALUES. (Words are VALUES
themselves, by the way.) Once you have those concepts firmly
in hand, move onto understanding how PARSE treats set-words in
a rule.
Would you explain the movement of the knight in chess in terms
of the way you play checkers?
> Also what is wrong with helping your neighbour to paint
> his fence is you neighbour is your friend?
It depends on the informed consent of the fence painter, and
who claims credit for the fence being painted. :-)
-jeff
[107/114] from: whip:cs:unm at: 20-Jun-2001 9:03
Hello, Robbo.
[Jeff emailing from his school account --
rebol.net looks down right now]
> REBOL AS IT'S OWN META-LANGUAGE
>
> I've read recently from Jeff & Joel, and other's in the previously,
> that REBOL is it's own meta-language.
>
> This is bunk! or at least only partially true.
No, it's not bunk.
> Consider this model of REBOL addition...
> >> add: func [ x y ] [ + x y ] add 1 2
<<quoted lines omitted: 3>>
> >> set '+ func [ x y ] [ add x y ]
> On the surface it looks okay, but try....
No, on the surface it doesn't look okay at all. You've defined the
function ADD to depend on the function +, and you've defined + to
depend on the function ADD. Something eventually has to
be able to actually add two numbers.
> >> add 4 5
> ** Internal Error: Stack overflow Near: add x y
<<quoted lines omitted: 3>>
> Your into infinite recursion here, so REBOL as a complete
> meta-language is "insufficient".
So, I don't really understand. What are you trying to demonstrate
with the above?
. . .
> If this was the case there would be no need for RT Inc. to write
> any more interpreters, we could simply write and extend REBOL in and
> from REBOL and we'd all live happily ever after.
Written many dialects?
> Unfortunitely there are these "irreducibles" or "primitives" that
> you simply MUST have to get the system up and running.
>
> It is for this reason that you sometimes have to use C or Java or
> something else to "explain" or implement REBOL.
You don't "HAVE TO" use a low level language to "explain" a high
level language.
> You can however devise a way to construct these "primitives" from
> within REBOL / your "meta-language" then you get into the realms and
> possibilities of META-COMPILATION which is a system written in
> itself, however you still have to bootstrap the whole process from
> something else first whether this be Assembler or C or Java or
> whatever.
Are you sure this is necessary? Have you tried, or are you
just speculating here?
> Forth proves this is possible and has had this capability for nearly
> thirty years now, maybe someday REBOL will catch up & we'll be
> dispensed with the need for RT to write our REBOL interpreters for
> us, if we so choose of course. 8-)
That's right.. How uncool of RT to be writing our REBOL
interpreters for us. The nerve of them!
> Oh Dear, why am I always so contrary?
I figure it's part of your PR effort. Play up on that martyr
kind of thing.. :-)
> I don't know about painting that fence Jeff, maybe I should come
> round from the wrong side of it and you can break the fence apart &
> hit me over the head with it!
See, if you ask me, which you haven't, you're going about this all
wrong. You're running out and rather recklessly trying to implement
(or actually, trying to get someone else to implement for you) a
language of great design and forethought (nearly 20 years in design
and many man years of implementation) and yet you consistently seem
to demonstrate rather questionable mastery of REBOL.
If I were you and I was trying to clone REBOL, I'd do the following:
First, become a true REBOL guru, mastering REBOL to a fine art,
including all its different areas: dialecting, introspection,
metaprogramming, networking, GUI, etc... True REBOL gurus can
explain why there is dialecting in REBOL, how to make user defined
ports, the reasoning behing MOLD/only, or LOAD/all, etc.. With all
this understanding of the language, I'd help 1,000 newbies into the
language. Now once my expertise in REBOL was solid and sure, and my
commitment to the beauty of the design was complete, then and only
then would I embark on the journey to clone REBOL.
Here's my recommendations for the cloning phase (which you've
already jumped ahead to):
A. Drop the hokey PR gig.
B. Produce something. Actions speak louder than words.
What to produce? Well, an actual interpreter written in some
compiled language is a lot to expect right away (or for a very long
time). Unrealistic expectations are bad for any development
project. The most rational approach would be to try and implement
REBOL in REBOL first. You can learn a great deal more about the
rules of the language as you put it together, and a working REBOL
implementation of REBOL counts as producing something (you can
actually take credit for having done something other than yack).
Once you've gone through those exercises before actually attempting
something compiled, the likelihood of you groking many of the finer
aspect's of Carl's awesome design will be higher. Also, with that
understanding of the design, the likelihood will be much lower that
you'll end up creating some super mangled REBOL-like language that's
only vaguely related and inappropriately compared.
I only bring this all up because I think it's great that you're
trying to clone REBOL, but like I've said, your approach just shocks
my esthetics and sensibilities. (-8 I sort of think you want to
have it all now, but I suspect you may have to live with RT writing
your REBOL interpreter for you for a while yet...
Just my opinion-- Best of luck!
-jeff
[108/114] from: joel:neely:fedex at: 20-Jun-2001 2:44
Hi, Mark,
Just two remarks...
[Robbo1Mark--aol--com] wrote:
> REBOL AS IT'S OWN META-LANGUAGE
>
> I've read recently from Jeff & Joel, and other's
> in the previously, that REBOL is it's own meta-language.
>
> This is bunk! or at least only partially true.
>
I've never said that "REBOL is its own meta-language".
I accept full responsibility (for good or ill ;-) for any
of my utterances, but prefer not to have ideas attributed
to me unless I've actually said (and believe) them.
> Consider this model of REBOL addition...
>
> >> add: func [ x y ] [ + x y ]
> >> add 1 2
> == 3
>
> Fine so far, however how do you define the '+ in
> the function body?
>
Here's the majority of it ...
bitstring: func [n [integer!] /local bv bt] [
bt: copy ""
bv: 1
until [
append bt either 0 < (n and bv) [#"1"] [#"0"]
any [
error? try [bv: bv + bv]
n < bv
]
]
bt
]
add1: func [a [char!] b [char!] c [char!]] [
select [
"000" [#"0" #"0"]
"001" [#"1" #"0"]
"010" [#"1" #"0"]
"011" [#"0" #"1"]
"100" [#"1" #"0"]
"101" [#"0" #"1"]
"110" [#"0" #"1"]
"111" [#"1" #"1"]
] to-string reduce [a b c]
]
add2: func [aa [string!] bb [string!] /local cc a b s c] [
s: c: #"0"
cc: copy ""
while [(length? aa) < (length? bb)] [append aa #"0"]
while [(length? bb) < (length? aa)] [append bb #"0"]
until [
set [s c] add1 first aa first bb c
append cc s
aa: next aa
tail? bb: next bb
]
if c = #"1" [append cc c]
cc
]
adder: func [a [integer!] b [integer!]] [
head reverse add2 bitstring a bitstring b
]
... which behaves as
>> adder 2 2 == "100"
>> adder 2 20 == "10110"
>> adder 15 200 == "11010111"
Since REBOL is implemented on binary computers, one must
understand binary in order to have a complete understanding
of REBOL. Therefore translating the output of ADDER back
to decimal is, of course, totally unnecessary.
The final details of handling negatives and overflows are,
as the saying goes,
"left as an exercise to the reader".
Have fun! ;-)
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[109/114] from: robbo1mark:aol at: 20-Jun-2001 5:20
REBOL AS IT'S OWN META-LANGUAGE
I've read recently from Jeff & Joel, and other's
in the previously, that REBOL is it's own meta-language.
This is bunk! or at least only partially true.
Yes for any particular instance or behaviour you can
generally write a rebol function or object to model
it's behaviour but you cannot do this for the "entirety"
REBOL, sooner or later you run into irreducibility.
Consider this model of REBOL addition...
>> add: func [ x y ] [ + x y ]
>> add 1 2
== 3
Fine so far, however how do you define the '+ in
the function body?
If you say
>> set 'x func [ x y ] [ add x y ]
On the surface it looks okay, but try....
>> add 4 5
** Internal Error: Stack overflow
** Near: add x y
>> + 4 5
** Internal Error: Stack overflow
** Near: add x y
>>
Your into infinite recursion here, so REBOL as a complete
meta-language is "insufficient".
However this is NOT a slight on REBOL just a fact about
the notion of meta-languages, you CAN'T have a complete
& self contained descriptive system.
Here's a quote from Chuck Moore about Forth which equally
applies to REBOL
I like to quote Goedel on this, it goes back to 1930.
he proved that a self contained formal system cannot be
contained. horribly non- sequator but, all right within
a system you can't describe itself. Within forth you can't
describe Forth. Well, our systems are not so esoteric
as Goedel's but I think you can say that within a system
you cannot describe it simply.
Now yes it is "preferable" to use REBOL to describe REBOL
whenever possible as this should lead to "less" confusion
however you simply "cannot" completely model REBOL in REBOL
as a whole entity.
If this was the case there would be no need for RT Inc.
to write any more interpreters, we could simply write and
extend REBOL in and from REBOL and we'd all live happily
ever after.
Unfortunitely there are these "irreducibles" or "primitives"
that you simply MUST have to get the system up and running.
It is for this reason that you sometimes have to use C or
Java or something else to "explain" or implement REBOL.
You can however devise a way to construct these "primitives"
from within REBOL / your "meta-language" then you get into
the realms and possibilities of META-COMPILATION which is
a system written in itself, however you still have to
bootstrap the whole process from something else first whether
this be Assembler or C or Java or whatever.
Forth proves this is possible and has had this capability for
nearly thirty years now, maybe someday REBOL will catch up &
we'll be dispensed with the need for RT to write our REBOL
interpreters for us, if we so choose of course. 8-)
Oh Dear, why am I always so contrary? I don't know about painting
that fence Jeff, maybe I should come round from the wrong side
of it and you can break the fence apart & hit me over the head
with it!
; see I can be "light hearted" sometimes!
Cheers my REBOL friends.
Mark Dickson
In a message dated Tue, 19 Jun 2001 2:16:27 PM Eastern Daylight Time, Jeff Kreis <[jeff--rebol--net]>
writes:
<<
Hello, Robbo:
> JEFF,
> I essence you are correct, but how easier can you more
<<quoted lines omitted: 9>>
> separate instance of a string! value and is stored at a
> separate memory location.
I think explaining the above in C is vastly more complex than
explaining it in terms REBOL has already established. You may
very well wreak havoc on the understanding people DO have of
the above by trying to explain it using C.
'A and 'B are both different words. They are NOT strings.
Both words refer to (have the value of) the same string. 'C
is also a different word than 'A and 'B. It refers to a
different value (a different string).
These particular notions of WORDS and VALUES are a distinct
aspect of REBOL and they are not an aspect of C. WORDS and
VALUES are within in the vocabulary of REBOL, but they are not
to be found in the vocabulary of C. C's typed variables are
an especially poor analogy to REBOL WORDS, for example please
describe the following in C:
word: 1
word: make object! [word: func [][print "I am a function"]]
word: word/word
word: 'word
I can easily explain the above in terms of WORDS and VALUES,
but I would find it very difficult to explain in terms of C's
typed variables and pointers. That's like explaining calculus
using Lincoln Logs.
REBOL is first class and EVERYTHING is data. This concept is
utterly absent from C. Please provide an example of how one
may understand the nature of REBOL's first class code/data
duality with C code.
> That is why this....
> >> insert b "abc"
<<quoted lines omitted: 7>>
> The value of 'A & 'B both change but 'C remains unaltered. You can show this in 'C
( or some other language ) by use of pointers and references as Joel
> did.
.."or some other language".. hmmm.. what would be a good
language for describing REBOL... hmmm... maybe REBOL? It's
its own metalanguage, afterall! :-)
> Similarly....
> >> a: <abc>
<<quoted lines omitted: 9>>
> data but 'a has the datatype! value tag! whilst 'b is
> a normal string! datatype!
Well, you might start by understanding that in REBOL there are
WORDS and WORDS can refer to VALUES. (Words are VALUES
themselves, by the way.) Once you have those concepts firmly
in hand, move onto understanding how PARSE treats set-words in
a rule.
Would you explain the movement of the knight in chess in terms
of the way you play checkers?
> Also what is wrong with helping your neighbour to paint
> his fence is you neighbour is your friend?
It depends on the informed consent of the fence painter, and
who claims credit for the fence being painted. :-)
-jeff
[110/114] from: carl:cybercraft at: 21-Jun-2001 20:42
On 21-Jun-01, Chris Double wrote:
> Are you saying that you can't implement a REBOL interpreter in
> REBOL? I think you'd be wrong there...
> Chris.
my-rebol-interpreter: do
(:
>>>> [Robbo1Mark--aol--com] 06/21 6:59 >>>
> You cannot yet completely implement ALL of REBOL in REBOL but with a
> C Compiler ( just guessing! ) you CAN write a REBOL interpreter, and
> you can do it in JAVA, see FREEBELL, so you CAN safely drop down to
> that level if need be.
--
Carl Read
[carl--cybercraft--co--nz]
[111/114] from: carl:cybercraft at: 21-Jun-2001 20:56
On 21-Jun-01, Carl Read wrote:
> On 21-Jun-01, Chris Double wrote:
>> Are you saying that you can't implement a REBOL interpreter in
>> REBOL? I think you'd be wrong there...
>> Chris.
> my-rebol-interpreter: do
> (:
Sigh - trickier than I though this interpreter lark...
my-rebol-interpreter: :do
>>>>> [Robbo1Mark--aol--com] 06/21 6:59 >>>
>> You cannot yet completely implement ALL of REBOL in REBOL but with
>> a C Compiler ( just guessing! ) you CAN write a REBOL interpreter,
>> and you can do it in JAVA, see FREEBELL, so you CAN safely drop
>> down to that level if need be.
--
Carl Read
[carl--cybercraft--co--nz]
[112/114] from: robbo1mark:aol at: 21-Jun-2001 5:27
JOEL,
The point is that Ladislave, yourself & others debated at length, trying to use only
REBOL and a natural language ( English ) to demonstrate the differences in property &
behaviour of SAME? & EQUAL? functions.
Using REBOL was insufficient in producing a function for testing whether an any-string!
or any-block! value shared the same memory location, and natural language was to ambiguous
and lead to discussions about concise definitions & meanings for words.
Your use of C, whilst admittedly not making it clear to everyone, showed demonstrably
the why & how of the different behaviour. Anyone who knows C could study your example
and see the logic that produced the REBOL like behaviour. This lead me to a quicker and
more precise understanding than the previous "higher level" attempts at explanation did.
It depends on what your goals are, my goal was understanding the behaviour, perhaps Ladislav
& yourself are looking to "describe" the behaviour more CONCISELY.
The use of C helped my understanding, but whether it aided your attempts at CONCISE explanation,
that is for you and others to decide, all I can say is you helped me
to clarify my understanding and I thank you for that.
With regards to REBOL being open source, it isn't and I accepted that a long time ago
too! It's a shame it isn't because that would help me further my understanding enormously
being able to study the sources, but it's NOT and so I & others have to formulate our
own model of understanding & possible implemetation, which is *FUN*, so that is what
I do, if I can learn & share from and with the help others, great! hopefully we all benefit
from the process.
I love REBOL and will continue to use it and learn from it, it is a wonderful productivity
tool, that doesn't mean I accept proprietary technology as a good thing or think that
the implications & consequences of it are desirable, IMHO they're not, but I won't expound
that view here. All I will say is how advanced would our understanding of modern science
be if the discoveries of Newton, Einstein, Planck, Maxwell etc. were proprietary & secret?
Thank you for helping me further my understanding.
Mark Dickson
In a message dated Wed, 20 Jun 2001 4:18:39 PM Eastern Daylight Time, Joel Neely <[joel--neely--fedex--com]>
writes:
<< Hello, all!
[Robbo1Mark--aol--com] wrote:
> You cannot yet completely implement ALL of REBOL in REBOL
> but with a C Compiler ...
> ... you CAN safely drop down to that level if need be. YOU
> did so to prove a point about equality and sameness!
>
I knew better at the time, but haste overruled common sense.
I hereby apologize to one and all for using the "c" word.
If I promise never to do it again, will you let me forget
that I did so? ;-)
-jn-
--
It's turtles all the way down!
joel'dot'neely'at'fedex'dot'com
[113/114] from: joel:neely:fedex at: 21-Jun-2001 4:00
Hi, Mark,
[Robbo1Mark--aol--com] wrote:
> The point is that Ladislave, yourself & others debated
>
How about "discussed with great energy"? ;-)
> at length, trying to use only REBOL and a natural language
> ( English ) to demonstrate the differences in property &
> behaviour of SAME? & EQUAL? functions.
>
Did my little story about "same" and "equal" bank accounts
capture that distinction for you? If not, I'd really like
to think about how to improve it. If so, then it shows
that we can discuss conceptual distinctions without resorting
to low-level programming languages.
> Using REBOL was insufficient in producing a function for
> testing whether an any-string! or any-block! value shared
> the same memory location,
>
I'm really distressed with myself for being unable to state
this point clearly enough. WRT series value:
I do not CARE whether two series values share "the same memory
location" (and I especially do not care how many bits are in
that "location" nor how it may be laid out). What I care about
most is this:
Given two expressions (including simple words) that
each evaluate to a series, under what conditions can
I perform an evaluation involving one of them that
has the effect of changing the evaluation of the other?
I also care (somewhat less) about this:
Given two expressions (as above...) can one of them
consistently be evaluated using less time and/or
memory than the other?
It is not hard to demonstrate that two expressions may evaluate
to the "same" series, and to start drawing inferences as to
when that occurs.
>> a: [1 2 3] == [1 2 3]
>> b: a == [1 2 3]
<<quoted lines omitted: 5>>
>> c == [1 2 3]
>> d == [1 2 3]
Some conclusion about copying and literal series expressions
are fairly obvious, and I won't take the time for them here.
Factors that make this game more subtle include:
1) the rich variety of REBOL data types,
2) REBOL's ability to create self-referential structures, and
3) the desire to discover "non-destructive" tests that
preserve the values we're examining.
(Old joke: How can you tell if a chair is an antique? It
burns with a bright blue flame!)
> and natural language was to ambiguous and lead to discussions
> about concise definitions & meanings for words.
>
... to which the solution involves precise definitions,
mathematics, and logic, not another programming language.
I must also point out another of my hidden biases. I regard
the goal of "a programming language for non-programmers" in
the same light that I regard the strong-AI goal of programming
human-like intelligence. I believe that both are ultimately
impossible. HOWEVER, I believe that efforts toward both goals
have led to wonderful advances in the state of programming that
likely never would have happened otherwise.
If you'll pardon the sports analogy (I'll probably regret this
as well ;-) it's perfectly OK for a runner to set the goal of
running a 2-minute mile, and to develop nutrition and training
regimens shaped by that goal. On the other hand, if a runner
claims to me that (s)he actually *has* run a 2-minute mile,
I'm going to get very, very picky about examining his/her
stopwatch and yardstick, and I'm going to insist on an actual,
testable demonstration before I accept the claim. (And even
then I'll be suspicious... ;-)
The AI community lost their credibility (despite some really
wonderful achievements) due to overselling and overly-
optimistic/enthusiastic claims. AI fell from being a leading
frontier in computing to being a marginalized niche, and its
proponents are now often viewed as snake-oil salesmen. I don't
want to witness that kind of tragedy again. Especially not
with REBOL.
I have great respect for Carl and the whole RT team, and for
the fruits of their labors.
That's why I often (usually?) take on a gadfly-like role and
challenge the notions that (what I regard as) hand-waving
explanations (or *no* explanations, in some cases ;-) and
claims of simplicity are good enough to certify REBOL as a
final achievement of the "impossible dream" of easy programming
for non-programmers.
Better stories, more precise language, more complete documents
(written *both* by RT and the user community) and, yes, the
elimination of some unnecessary inconsistencies in REBOL itself
will all move us toward better programming for both programmers
and "non-programmers".
Requiring that we describe REBOL in terms of a low-level
programming language is IMHO contrary to that goal.
> Your use of C, whilst admittedly not making it clear to
> everyone, showed demonstrably the why & how of the different
> behaviour. Anyone who knows C could study your example and
> see the logic that produced the REBOL like behaviour...
>
This is the heart of the problem (and the reason for my sincere
regret over that example!).
One or two of the questions in the thread seemed (to me) to
imply that REBOL was drawing a peculiar distinction that was
outside normal programming concepts. Quod non.
I wanted to show that the distinction does exist in other
languages, but that REBOL expressed it differently. I wasn't
trying to argue "how" REBOL must have been implemented. For
the rest, please reconsider my posted remarks on the danger of
drawing triangles in geometry. Arguing by example runs the severe
risk of having irrelevant details of the examples
take over
the discussion and focus attention on the wrong
details.
Depending on The Language That Must Not Be Named as our means
of explaining REBOL:
1) brings in entirely too much irrelevant baggage,
2) can be misleading, and
3) excludes anybody who doesn't already know that Language.
I consider all of these to be undesirable.
> All I will say is how advanced would our understanding of
> modern science be if the discoveries of Newton, Einstein,
> Planck, Maxwell etc. were proprietary & secret?
>
How advanced would our scientific understanding be if:
1) NEPMetc. were *required* to do all of their thinking
in public, subject to constant committee-style debate
over every detail while the work was still in progress?
2) Einstein, Bohr, and Planck were *required* to explain
all of their ideas strictly in terms of Newtonian
mechanics, and told that anything that didn't fit the
Newtonian model was unreasonable and unacceptable?
Now (to follow my own advice) I'm back to model hacking!
-jn-
------------------------------------------------------------
Programming languages: compact, powerful, simple ...
Pick any two!
joel'dot'neely'at'fedex'dot'com
[114/114] from: jeff:rebol at: 22-Jun-2001 8:01
Howdy, Chris:
> Just to play devil's advocate for a moment...
> . . .
<<quoted lines omitted: 5>>
> cost, when a constant cost alternative is actually
> avilable.
Sure, good point-- and we've always been forthright about
the order magnitudes associated with different data
structures and operations (at least all that data has been
posted to this list at one time or another). What's not
been done is create a table of these specs and provide that
for the interested. Or really anyone could publish an order
analysis of REBOL at this point, using ml archive -- search
for O(*) If there's any gaps in the data, just ask! . That
or it can go into the RT TBD pile. :-) (To Be Done)
-jeff
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted