[squeak-dev] Re: immutibility

Bert Freudenberg bert at freudenbergs.de
Wed Mar 31 15:13:53 UTC 2010


On 31.03.2010, at 17:01, Igor Stasenko wrote:
> 
> On 31 March 2010 17:14, Bert Freudenberg <bert at freudenbergs.de> wrote:
>> On 31.03.2010, at 16:10, Igor Stasenko wrote:
>>> 
>>> On 31 March 2010 16:07, Bert Freudenberg <bert at freudenbergs.de> wrote:
>>>> On 31.03.2010, at 15:03, Igor Stasenko wrote:
>>>>> 
>>>>> On 30 March 2010 14:09, Bert Freudenberg <bert at freudenbergs.de> wrote:
>>>>>> On 30.03.2010, at 11:45, Bryce Kampjes wrote:
>>>>>>> 
>>>>>>> On Thu, 2010-03-18 at 16:40 +0100, Bert Freudenberg wrote:
>>>>>>>> On 18.03.2010, at 16:30, Ralph Johnson wrote:
>>>>>>>>> 
>>>>>>>>> On 3/18/10, Bert Freudenberg <bert at freudenbergs.de> wrote:
>>>>>>>>> 
>>>>>>>>>> With true immutables you can start developing in a mixed object/functional style, which would allow interesting optimizations, e.g. for concurrency, memoization etc.
>>>>>>>>> 
>>>>>>>>> I've developed in a mixed object/functional style for years, and I
>>>>>>>>> think a lot of other people do, too.   You don't need language support
>>>>>>>>> for this, though I expect it would be helpful.  It makes concurrency
>>>>>>>>> and distributed programming easier, and is important when you are
>>>>>>>>> dealing with databases.  Eric Evans calls this "Value Object" in his
>>>>>>>>> book "Domain Driven Design".
>>>>>>>>> 
>>>>>>>>> -Ralph Johnson
>>>>>>>> 
>>>>>>>> Right, the style is possible without VM support in your own subsystem. But being able to *guarantee* immutability would allow to generalize this beyond your own special-purpose code. And possibly it would enable further VM-level optimizations.
>>>>>>> 
>>>>>>> Even perfectly VM enforced immutability isn't enough to allow
>>>>>>> optimisation if you still allow become:. It's always possible to swap
>>>>>>> out the immutable object with a different one via become:.
>>>>>> 
>>>>>> It's fine to swap immutable objects, unless the object holding the reference is itself unmutable. No instance variable of an immutable object can be stored into, not even by become:.  Obviously, become: would have to honor the immutability flag:. For references inside immutable objects, become: becomes a forward-become (or a no-op if both were immutable):
>>>>>> 
>>>>>> a := Array with: A new.
>>>>>> b := Array with: B new beImmutable.
>>>>>> c := (Array with: C new) beImmutable.
>>>>>> a first become: b first. "a points to the immutable B instance, b to the A instance".
>>>>>> a first become: c first. "both a and c now point to the immutable C instance"
>>>>>> 
>>>>> 
>>>>> one of the problem with #become:/becomeForward: that it should swap
>>>>> all of existing references atomically.
>>>>> Now imagine that while walking the heap, it replaced a 50% of
>>>>> references to given object, and then discoreved that it
>>>>> needs to swap a reference held by immutable object.
>>>>> Now, what you suppose to do? Revert all changes and fail primitive?
>>>>> Ignore this object (do not alter it references) and continue?
>>>>> Or, before doing the real swapping, scan the heap and check all object
>>>>> to make sure that none of them are immutable and so, #become will work
>>>>> ok?
>>>> 
>>>> Just ignore all writes into immutable objects (that is, in the become code, do not insert a forwarding block), otherwise proceed as usual.
>>>> 
>>> But such semantics is no longer can be treated as #become (or #becomeForward),
>>> because you leaving a references to old object instead of uniformly
>>> replacing them with swapped one.
>> 
>> I don't see a problem with that. Can you give an example where it would be problematic?
>> 
> 
> It defeats a purpose of #become.
> If you think about objects as a nodes in directed graph, then
> become is a way to replace a single node with another one,
> such that all nodes pointing to node A, now start pointing to node B.
> If you make any exceptions, you'll end up with having part of nodes in
> graph pointing to B, while
> another part still pointing to node A.
> Many things in system relying on such semantics, and i don't even want
> to guess, how many places will break
> if you change that, because in all cases where one using #become, he
> expects that all references is replaced, but now he should keep in
> mind that some references keep unchanged and moreover, you don't have
> a reliable control over this process.
> So, instead of simple and predictable behavior, #become will be
> something unreliable and brittle, which cannot be fully trusted.

self call: Shenanigans ;)

Show me a single place that would break in a real-world use-case.

In fact, #become: is rarely used in Squeak because of its inherent slowness caused by our direct-pointer object model. And those rare places I can think of would work just fine.

- Bert -




More information about the Squeak-dev mailing list