valhalla-dev Digest, Vol 17, Issue 3

Vitaly Davidovich 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
> 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