Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

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