[REBOL] Re: On mutability and sameness
From: carl:cybercraft at: 16-Jun-2001 10:52
On 15-Jun-01, Joel Neely wrote:
> Hi, again, briefly (long day today...)
briefly indeed. (:
> MY MODEL:
> a) All set-path expressions cause something to be mutated.
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
> 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
> 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
> 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
> 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...
> 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.
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.
shared? a b
shared? a b
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
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