[REBOL] generalities of addresses and values... Re:(3)
From: joel:neely:fedex at: 10-Oct-2000 21:47
Hello, Rishi!
[rishi--picostar--com] wrote:
> ok. I think I get it now. Everything is basically done as a
> reference. Even setting words. This is much simpler than what
> I was thinking :-)
>
Well... maybe not!
> ei:
>
> a: 5
> b: a
>
> in this example, b is a reference to a (right?).
>
Not as I understand it. In the second line, the expression
a
is evaluated, yielding the value of 5. A copy of that value is
bound to b (in the current context) by
b:
Note: When I said "a copy" above, I wasn't pretending to know how
the REBOL interpreter works. I was trying to emphasize that all
copies of 5 are interchangeable.
> The thing that
> was confusing me was that the copy function doesn't always create
> a new copy. In deep series, it creates a reference to copied value
> ....strange...
>
I think you're talking about the difference between
b: copy a
and
b: copy/deep a
(If I'm mistaken here, please let me know!) The issue is that
series values are dealt with "by reference" so that one can do
>> a: ["This" "is" "a" "test"]
== ["This" "is" "a" "test"]
>> b: a
== ["This" "is" "a" "test"]
>> change next b "was"
== ["a" "test"]
>> a
== ["This" "was" "a" "test"]
The word a contains a reference to the literal, four-string
series in the first line. The second line binds to b a copy
of the value of a , which means that b now has a copy of
that reference. Since both of these references are to the same
data structure, changing the state of that structure (through
either reference) is visible via either/both.
Now consider one-level copying. With
>> a: ["This" "is" "a" "test"]
== ["This" "is" "a" "test"]
>> b: copy a
== ["This" "is" "a" "test"]
>> change next b "was"
== ["a" "test"]
>> a
== ["This" "is" "a" "test"]
>> b
== ["This" "was" "a" "test"]
it is (I hope) clear that THE BLOCK ITSELF was copied, not merely
a reference to it. But... what does the block contain? Well, it
contains four references! Blocks and strings are both series
values, which are handled via reference. So changing the value
to which b refers (as in the above example) doesn't affect
the value to which a refers, BUT going one level deeper and
changing a string (series value) to which both the (block) value
of a and the (block) value of b refer will again be visible
via either of the second-level references. Continuing after the
interaction above, we can do
>> change/part skip b/1 2 "at" 2
== ""
>> a
== ["That" "is" "a" "test"]
>> b
== ["That" "was" "a" "test"]
The way to ensure against such hidden connections is to do a deep
copy, which recursively copies nested series values.
>> a: ["This" "is" "a" "test"]
== ["This" "is" "a" "test"]
>> b: copy/deep a
== ["This" "is" "a" "test"]
>> change next b "was"
== ["a" "test"]
>> a
== ["This" "is" "a" "test"]
>> b
== ["This" "was" "a" "test"]
>> change/part skip b/1 2 "at" 2
== ""
>> a
== ["This" "is" "a" "test"]
>> b
== ["That" "was" "a" "test"]
After which we can see that
>> same? a b
== false
>> same? a/4 b/4
== false
>> same? a/4/1 b/4/1
== true
>> same? a/4/1 b/4/4
== true
because two strings that spell the same word are not necessarily
the SAME string. You can distinguish them by modifying one of them,
and seeing whether the other is modified. However, any two copies
of the letter #"t" are the same, because there's not any way to
reach inside
it and modify one of its parts.
> By the way, is there any way to prove that b is a reference to a
> (in the above example) ? I know you can do it if you set the value
> of as a series datatype (by using insert or other series function).
> But how do you prove that b references a for number datatypes?
>
It doesn't. If you wanted to prove that it did, you'd need to be
able to modify a part of a numeric value in-place and show the
change propagating. However, REBOL also does some other tricky
things in that regard. Consider:
>> a: 1-Jan-2000
== 1-Jan-2000
>> b: a
== 1-Jan-2000
>> same? a b
== true
>> b/2: 10
== 10
>> b
== 1-Oct-2000
>> same? a b
== false
>> a
== 1-Jan-2000
Even though you can modify a component of a date value, doing do
does not propagate. Therefore, one would conclude that the two
date values are considered the same because they are being tested
by value, rather than by reference. This is consistent with the
results below:
>> same? "test" "test"
== false
>> same? 1-Oct-2000 2000/10/01
== true
At this point, one would need to do similar tests for all REBOL
datatypes to completely answer your question. The description
of copy (with respect to the /deep refinement) leaves
the impression that anything under the series! pseudotype
would be a "reference", however.
>> series? ["This" "is" "a" "test"]
== true
>> series? "test"
== true
>> series? 1-Oct-2000
== false
The best advice I can give you is to forget the concept of "address"
that you may have from assembler, C, or any other low-level language.
There just isn't any way to get at the "storage location" associated
with a "variable" in REBOL -- in fact, I quoted those phrases just to
emphasize that I'm speaking a foreign language here! Those concepts
don't even exist in REBOL!
-jn-