valhalla-dev Digest, Vol 17, Issue 3

Vitaly Davidovich vitalyd at gmail.com
Sat Dec 19 00:53:59 UTC 2015


Hi Thomas,


> Thanks for both your thoughts. I guess you can tell my design preferences
> are clearly on the side of KISS.. but we'll put that aside for now, and
> consider the question.


I'm going to preface by saying that I see this design decision (i.e.
specialize vs dedicated type) akin to interface vs abstract class; both can
be used to model abstractions, but each can be more appropriate/"better" in
some circumstances.

My observation would be that "ArrayList<boolean>" has fairly minimal/
> uncommon utility..  We're not really discussing language changes for a list
> of booleans as the requirement. So I would question whether this whole
> discussion, is actually a stalking horse for something else.
> - ArrayList<Optional<X>> perhaps?  to me, that seems like the only really
> worthwhile candidate.
> - are there any others of genuine value?


ArrayList<boolean> is just an easy example with similar "prior art" in a
different language (i.e. C++ std::vector<bool>); the other one mentioned
before, and you're alluding to here, is Optional<T> where T is a ref type
--> should be same size as T.  There will be some domain-specific places
where this can be leveraged, but I agree this won't be widespread, so to
speak.

Having said that, if Optional<T> is ported to being a value type (or some
successor is introduced, I don't really care), there are quite a few places
where using it in APIs would provide more null safety and self-documenting
code (aside: I'd rather not get into the whole debate about using @NotNull
annotations vs library solutions here).  However, having Optional<T> where
T=ref take up more space than just T would be a shame.  It's not
*critical*, of course, but unless the amount of work to make this a reality
is tremendous, it's a very good optimization and makes using this type more
palatable.

As a thought experiment, let's suppose we give "somebody" this feature of
> allowing type-specific overrides, and let them run with it for a while.
> - let's say they find the benefits of making ArrayList<boolean> more
> compact, as nearly zero value;
> - but hey, large objects could be stored off-heap!  that's more valuable
> than making dumb old boolean a tiny bit smaller.
> --- so they add special support for some perceived large type, to store it
> off-heap. it works great.
> - but hey, we can store more if we go to disk.
> --- so they add file storage as well. there's a few dependencies &
> interactions, but come on, it works great.
> - that works great. but hey, we're putting Comparables in the list.
> shouldn't it be able to sort these automatically?
> --- so they add that.. it works great.

All of these features work great! What's the problem?  Problem is, the
> design of the class is now rubbish. It doesn't do one thing well any more,
> it does five. Ask what the "contract" is and now it's a meaningless jumble
> of special-cases.


In my opinion, this has nothing to do with specialization vs dedicated
types -- you can design a monster with either approach.  In general, no
language prevents "terrible" design, however one wants to define that
(nevermind it's subjective, but let's no get hung up on that).

The biggest advantage to doing this via specialization is that if you do
come up with a better way to represent a generic type with a given type
arg, the user of such instantiations doesn't need to change their code.  As
a bonus, you don't need to provide a name for this thing (we all like
naming bikesheds right? :)).  Your alternative approach doesn't stop
someone from creating a named specialized type, providing some means for
getting access to it (or even hiding it behind some interface/abstraction),
and letting someone use it.  So the only difference that I can see is that
by explicitly making user change code to take advantage of the new type
they don't unknowingly use a terribly-implemented specialization?


On Fri, Dec 18, 2015 at 7:26 PM, Thomas W <twhitmore.nz at gmail.com> wrote:

> Hi Brian, Vitaly,
>
> Thanks for both your thoughts. I guess you can tell my design preferences
> are clearly on the side of KISS.. but we'll put that aside for now, and
> consider the question.
>
> My observation would be that "ArrayList<boolean>" has fairly minimal/
> uncommon utility..  We're not really discussing language changes for a list
> of booleans as the requirement. So I would question whether this whole
> discussion, is actually a stalking horse for something else.
> - ArrayList<Optional<X>> perhaps?  to me, that seems like the only really
> worthwhile candidate.
> - are there any others of genuine value?
>
> Vitaly, when we discuss the "contract of ArrayList" today -- or with
> simple byte-addressed value type genericization, where the array
> multiplier  -- we get a single clear statement of what it does, which I
> would consider reasonable to describe as a "contract".
>
> As a thought experiment, let's suppose we give "somebody" this feature of
> allowing type-specific overrides, and let them run with it for a while.
> - let's say they find the benefits of making ArrayList<boolean> more
> compact, as nearly zero value;
> - but hey, large objects could be stored off-heap!  that's more valuable
> than making dumb old boolean a tiny bit smaller.
> --- so they add special support for some perceived large type, to store it
> off-heap. it works great.
> - but hey, we can store more if we go to disk.
> --- so they add file storage as well. there's a few dependencies &
> interactions, but come on, it works great.
> - that works great. but hey, we're putting Comparables in the list.
> shouldn't it be able to sort these automatically?
> --- so they add that.. it works great.
>
> All of these features work great! What's the problem?  Problem is, the
> design of the class is now rubbish. It doesn't do one thing well any more,
> it does five. Ask what the "contract" is and now it's a meaningless jumble
> of special-cases.
>
> OO Principle is to prefer composition to inheritance.  "Inheritance" in
> the principle means the embodying of functionality in a single class; for
> us, this would be via type-specific templating rather than inheritance.
>
> I for one, find a great deal of value in having simple & well-defined
> classes which do their job.
> - If I want a different implementation, I instantiate a different class.
> - I presume that a very large proportion of the requirement for
> List<boolean> are actually aware that they're using a 'boolean' -- and can
> instantiate a BooleanBitList specifically, if they actually need/ want to
> optimize storage of it.
>
> While it's easy to say that SomeCollection<Optional<X>> has a great case
> to support efficiently, I think that -- if we consider type-specific
> templating as a general architectural direction -- the place that road
> leads to, if pursued more than a very little bit, are questionable.
>
> Which obviously raises uncertainty -- if the architectural approach (when
> used other than minimally) leads in a direction we don't want to go, as to
> whether it's the right direction.
>
> I think this is an exploratory phase so these are all great questions to
> consider.  But I'd like to conclude by asking, what types are the real
> drivers for this?
>
>
> Regards,
> Thomas
>


More information about the valhalla-dev mailing list