There is also a chance that the compiler can be taught about Immutable
types to help in analysis. A typical case I've seen in record based
function languages is an optimization called equational reasoning,
which essentially boils down to statically determining the the fields
of an object as constant values, and then substituting those values
where appropriate, essentially treating the object as nothing more
than a compile time macro holding a few values.

Consider:

ImmutablePerson p = new ImmutablePerson("Ray", "Cromwell");

salute(p.firstName, p.lastName) => salute("Ray", "Cromwell");

or better,

ImmutableArray ar = ImmutableArray.cons(1,2,3,4,5);

add(ar.get(2), ar.get(3)) => add(3, 4) => 7

It's true that the compiler in theory could do constant analysis/copy
propagation, but it tends to get difficult when the intermediate
values are passed to other methods and you don't know who is modifying
them The immutability of these types let's the compiler assume that
regardless of which methods receive these objects, they cannot
possibly be modified.


On Mon, Mar 22, 2010 at 4:05 PM, Bruce Johnson <br...@google.com> wrote:
> I think Rodrigo's point already subsumed what I'm about to say, but there
> are three cases here:
> 1) A read-only reference to a collection that may or may not be mutable by
> someone else. This is the purpose of the root type Array, which has not
> mutators but doesn't make a guarantee about whether the referenced
> collection is mutable or immutable.
> 2) A reference to a read-only collection whose contents are guaranteed to in
> fact be immutable.
> 3) A normal, mutable array that is read/write.
> @Ray: The idea of an immutableView() method doesn't seem to quite handle
> these use cases, because either the returned object is a separate object
> with a runtime wrapper (the equivalent of unmodifiableList()) or it's a
> read-only interface to a collection that isn't really guaranteed to be
> immutable, merely read-only. Also note that MutableArray extends the
> read-only Array class, and so every MutableArray can be implicitly returned
> as a read-only alias anywhere you want, which is even easier than
> immutableView().
> I would guess it would be fairly typical to use mostly MutableArray and
> Array, but ImmutableArray has a real role, too. Imagine a MyPanel that takes
> a list of Widgets in its constructor. You could declare the constructor like
> this:
>    public MyPanel(ImmutableArray<Widget> widgets) { ... }
> That's useful because you can code the class with full knowledge that the
> set of widgets won't be changing out from under you from the calling code --
> you can just directly assign that param to a field without making a copy.
> Had the constructor been:
>    public MyPanel(List<Widget> widgets) { ... }
> you could never be sure and would probably feel compelled to make a
> defensive copy.
> I'm going to guess this is how it would play out:
> 1) Constructors will often take ImmutableArray because it's nice to assign
> ctor params directly to fields and know for a fact there's no reason to make
> defensive copies.
> 2) Fields will be declared as MutableArray, and in getters the return type
> will be Array, thus allowing getters to safely return references directly,
> happy in the knowledge that there is neither a need to make a defensive
> outgoing copy nor a risk that the caller can mutate your private field's
> contents.
> 3) Library methods will take the least-specific type that can suffice for
> the respective algorithm. For example, binarySearch(), find(), forEach(),
> etc. would take a param of type Array, thus allowing either mutable or
> immutable arrays to use the method. Then again, sort() would explicitly take
> a MutableArray.
> And of course, there is no desire to design all this in a vacuum -- and we
> shouldn't argue against it in a vacuum either. This is a starting point
> strawman, so I'd propose we use this design as a stake in the ground and
> then see how it would play it if we retrofitted it into real code, both app
> code and library code. Then we'll really get a feel for how useful vs.
> confusing it is, and most importantly, we can get metrics on the speed and
> size.
>
>
> On Mon, Mar 22, 2010 at 6:34 PM, Rodrigo Chandia <rchan...@google.com>
> wrote:
>>
>> Immutability is a stronger assertion than read-only access. If I receive a
>> read-only object I better make sure to handle the case of the data being
>> changed by others; be it by tacit agreement, using other channels, locking
>> or simply ignoring the issue. Immutability guarantees the data is stable and
>> unchanging. The agreement is explicit. I will be able to read it to my
>> heart's content without worry.
>> Granted, being this a simple implementation it has some inconveniences:
>> 1. The Immutability is achieved by "freezing" the original Mutable
>> container while it may be useful to keep working with the original container
>> instead.
>> 2. The receiver of a MutableArray may find later that someone called
>> freeze on the object causing an error.
>> This is largely a matter of it being a lightweight implementation. There
>> is no contract forcing the mutable view to be tied to the original mutable
>> container. A more sophisticated implementation could copy the container,
>> implement copy-on-write semantics, or any number of alternative
>> implementations. Still the meaning of an immutable collection implies the
>> contents will not change, while a read-only view makes no such promise.
>> 2010/3/22 Ray Ryan <rj...@google.com>
>>>
>>> My argument is that one is necessary and sufficient. Two is kind of
>>> pointless if you have achieved one, and maybe even counterproductive.
>>>
>>> On Mon, Mar 22, 2010 at 2:32 PM, Joel Webber <j...@google.com> wrote:
>>>>
>>>> I think we're talking about two different things here. Rodrigo's (valid)
>>>> point is that implementing immutability sanely early on is a good idea. And
>>>> this implementation is pretty much analogous to the one you describe from
>>>> Cocoa.
>>>> The question at hand is whether it makes sense to get an immutable
>>>> collection from a mutable one, with no copies. There are two ways to do
>>>> this:
>>>> 1. Create an immutable "view" of a mutable list, but with no guarantees
>>>> that the list won't be mutated by the original owner later.
>>>> 2. "Freeze" a mutable list into an immutable view of said list, making
>>>> the former "runtime immutable".
>>>> (1) solves the problem of a class giving access to one of its internal
>>>> collections without having to guard against external mutation. (2) can be
>>>> used to replicate the "builder" pattern.
>>>> I don't have a strong opinion about (2) myself, but (1) is pretty damned
>>>> important, because it's the source of innumerable stupid defensive copies 
>>>> in
>>>> JRE code. The provider of such an interface would just have to be very 
>>>> clear
>>>> about whether the "immutable" list might be modified later (because it's a
>>>> view on a mutable one).
>>>>
>>>> On Mon, Mar 22, 2010 at 5:23 PM, Ray Ryan <rj...@google.com> wrote:
>>>>>
>>>>> I think you're missing my point. An object is immutable if there exists
>>>>> no api to mutate it. That should be enough.
>>>>> Let me put it another way. It's lame that the JRE achieves immutability
>>>>> by turning mutate methods into runtime errors. It will be equally lame of 
>>>>> us
>>>>> to do the same, especially since we can't enforce it at production time. 
>>>>> It
>>>>> would be much better to provide an api such that there is not even 
>>>>> possible
>>>>> to compile the mutate call (without cheating with casts, but then you know
>>>>> you're being bad).
>>>>> The Cocoa approach to this is to have interfaces like NSArray be
>>>>> immutable, and then have NSMutableArray extend NSArray. If we're going to
>>>>> roll our own collection classes, it seems to me we could do the same: e.g.
>>>>> LiteImmutableList and List extends LiteImmutableList.
>>>>> rjrjr
>>>>>
>>>>> On Mon, Mar 22, 2010 at 2:12 PM, Rodrigo Chandia <rchan...@google.com>
>>>>> wrote:
>>>>>>
>>>>>> I like the *concept* of immutability being introduced early in the
>>>>>> development. The initial implementation may be limiting for some use 
>>>>>> cases,
>>>>>> but I believe it is a useful concept to expand on. If specific needs 
>>>>>> require
>>>>>> simultaneous mutable and immutable access we can provide implementations 
>>>>>> to
>>>>>> address that problem (copy on write semantics, for example).
>>>>>> 2010/3/22 Ray Ryan <rj...@google.com>
>>>>>>>
>>>>>>> I guess I'm overstating my opposition. It's not really dangerous, but
>>>>>>> it just doesn't seem useful. Just by existing I think it'll promote
>>>>>>> confusion and perhaps bad habits. Why bother?
>>>>>>> I think the 90% use case is for something like the following (writing
>>>>>>> in JRE terms here):
>>>>>>> private final List<String> magicValues;
>>>>>>> {
>>>>>>>    List<String> buildValues = new ArrayList<String>();
>>>>>>>    buildValues.add("able");
>>>>>>>    buildValues.add("baker");
>>>>>>>    buildValues.add("charlie");
>>>>>>>    magicValues = Collections.unmodifiableList(buildValues);
>>>>>>> }
>>>>>>> Ta da: it's a read only structure and no copy was made. In our world,
>>>>>>> we could do better:
>>>>>>> private final ImmutableLiteList<String> magicValues;
>>>>>>> {
>>>>>>>    LiteList<String> buildValues = new LiteList<String>();
>>>>>>>    buildValues.add("able");
>>>>>>>    buildValues.add("baker");
>>>>>>>    buildValues.add("charlie");
>>>>>>>    magicValues = buildValues.immutableView(); // more equivalent of
>>>>>>> cast()
>>>>>>> }
>>>>>>> The user never thinks in terms of freezing, just cutting off access.
>>>>>>> No extra dev mode mechanism to maintain, and basically the same idiom
>>>>>>> already in use in Java.
>>>>>
>>>>> --
>>>>> http://groups.google.com/group/Google-Web-Toolkit-Contributors
>>>>>
>>>>> To unsubscribe from this group, send email to
>>>>> google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to 
>>>>> this
>>>>> email with the words "REMOVE ME" as the subject.
>>>>
>>>> --
>>>> http://groups.google.com/group/Google-Web-Toolkit-Contributors
>>>>
>>>> To unsubscribe from this group, send email to
>>>> google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to 
>>>> this
>>>> email with the words "REMOVE ME" as the subject.
>>>
>>
>
> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors
>
> To unsubscribe from this group, send email to
> google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this
> email with the words "REMOVE ME" as the subject.
>

-- 
http://groups.google.com/group/Google-Web-Toolkit-Contributors

To unsubscribe from this group, send email to 
google-web-toolkit-contributors+unsubscribegooglegroups.com or reply to this 
email with the words "REMOVE ME" as the subject.

Reply via email to