valhalla-dev Digest, Vol 17, Issue 3
vitalyd at gmail.com
Mon Dec 14 14:56:49 UTC 2015
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
> 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
> 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
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?
Sent from my phone
More information about the valhalla-dev