valhalla-dev Digest, Vol 17, Issue 3

Brian Goetz brian.goetz at oracle.com
Mon Dec 14 15:06:34 UTC 2015


What Vitaly is saying is that being able to control the operation of

    new Foo<ASpecificValueType>

and have that evaluate to something that matches the contract of Foo, but not necessarily the same representation of other parameterizations of Foo, gives library designers more power to deliver useful and performant libraries without the user having to worry about it directly.  

This is a valid point, and one we’re willing to explore, though have not committed to anything yet.  

Note that we almost certainly would *not* allow use-site control over this — a client will not be able to say “I want to silently override the definition of ArrayList<long>”, just as they cannot inject default methods into ArrayList.  

Thomas’ concern is also a valid one — does this break parametricity?  Also worth exploring.  

Bottom line is: this is within the realm of possible, but by no means guaranteed.

On Dec 14, 2015, at 9:56 AM, Vitaly Davidovich <vitalyd at gmail.com> wrote:

> On Monday, December 14, 2015, Thomas W <twhitmore.nz at gmail.com> wrote:
> 
>> Hi Vitaly, people
>> 
>> [If you want a BooleanBitList, create a separate class for it.]
>>> But why? I have a generic class ArrayList that satisfies contract of
>> whomever wants to use it
>> 
>> ArrayList is an *implementation*, java.util.List is a contract. Now the
>> List contract can be filled by anybody -- ArrayList<int>,
>> ArrayList<boolean> using a byte-per-cell, BooleanBitList using a
>> bit-per-cell.
>> 
>> The "contract" you referred to (but referencing the incorrect type) gives
>> you full flexibility, to have whatever storage & addressing are provided by
>> the implementation. An "implementation" on the other hand, to be
>> meaningful, has to actually make some things concrete. In a Collection,
>> storage is likely to be that.
>> 
>> 
> Nope, I referenced the right type :).  ArrayList fulfills the higher level
> List contract but it has implementation level contract that people rely on
> and leverage intentionally.
> 
> 
>> I am happy for bytewise addressing & cell width (in bytes) to be
>> abstracted in the service of generic specialization; but you're trying to
>> cross a really clear boundary, when you change the CPU instructions,
>> storage addressing etc etc etc to address memory below the "byte" level.
>> 
> 
> Perhaps we'll have to disagree here, I don't think there's a clear boundary
> here.
> 
> 
>> I'm pretty sure you can see there's a boundary, too -- Good design is
>> about choosing the right boundaries & respecting them, such that a useful,
>> meaningful & efficient abstraction is presented at the higher level.
>> 
> 
> Agreed in principle.
> 
> 
>>> Why define another abstraction just to support better/more efficient
>> storage for a given *type*? There's no capability/semantic
>>> change here, it's still an ArrayList.
>> 
>> Another abstraction?  Classes have existed since Java 1.0, hardly new. We
>> should use them, they work well for things such as types providing
>> different implementations of an interface.
>> 
> 
> Abstraction is meant in general sense here.  You're providing a named type
> here that user will be aware of one way or another; either the type is
> exposed directly or hidden behind some factory that returns it.  Unless of
> course the factory takes a Class and switches on known types, but we'll
> probably agree that's not a good answer.
> 
>> 
>> And to correct your second sentence:  there's no capability/semantic
>> change, it's still a *List*. But there would be _fundamental difference in
>> implementation_, so it should be a different concrete type.
>> 
> 
> What is the fundamental difference?
> 
>> 
>>> The world today requires that but it's unnecessary; storage is an
>> implementation detail that shouldn't necessarily "leak" into the
>>> type system.
>> 
>> The purpose of a concrete Collection implementation is to implement
>> storage. 'List' keeps storage out of the type. ArrayList, LinkedList & the
>> putative BooleanBitList implement it.
>> 
>> It's probably mistaken to claim that implementation is "just a detail"
>> that can (or should be) abstracted out of the type system. The fundamental
>> purpose of concrete classes is to organize _concrete code which does
>> something_, aka implementation, since without implementation a system does
>> nothing.
>> 
> 
> Again, agree in principle.  I'm just not seeing the fundamental difference
> here that warrants this.
> 
>> Yes, a preprocessor can do "anything". Is it a good idea? No.
>> 
> 
> Don't think this is anything close to being a preprocessor.
> 
> Let me ask you this - how do you propose users make use of more optimal
> ArrayList-like implementations? How do you expose your BooleanBitList? How
> do you expose more efficient implementations in the future when you didn't
> envision a particular specialization today? How does user make use of it
> without touching their source code?
> 
>> 
>> 
>> Regards,
>> Thomas
>> 
> 
> 
> -- 
> Sent from my phone



More information about the valhalla-dev mailing list