July 20, 2004
"Daniel Horn" <hellcatv@hotmail.com> wrote in message news:cdhkqj$s1a$1@digitaldaemon.com...
> definitely do both struct and class of everything

I disagree. It might seem like a convenience to have many versions of nearly the same thing but it actually winds up making the library impossible to use. Long discussions about this kind of thing were had about the dll-loader module. I picked structs for my containers since dynamic arrays and assoc arrays have struct-like semantics and so it seems natural to have other containers follow the same style as them. For instance slicing a dynamic array returns another dynamic array. In the same way slicing a List returns a List and slicing a Map returns a Map.

> you never know when one might come in handy...
>
> on the other hand it definitely muddles pass-by-ref and pass-by-val
>
> you get cases where you pass a vector<> into a function and it gets
> copied sometimes:
> i.e. the inner function does a push_back on a value...
> that may or may not increase memory allocation
> then that inner function sets the value--that may or may not set the
> caller's copy of the struct
> but one thing is certain: the caller's vector struct will be precisely
> the size it was when it was passed it, because it's a local struct var...
> how do we deal with difficult to identify bugs like this (they only
> occur on power of two borders)
>
>
> Bent Rasmussen wrote:
> >>I've been thinking about the struct/class issue, and I'm pleased that
> >
> > you're
> >
> >>also thinking about it. I look forward to hearing more of your thoughts.
> >
> >
> > I'd guess that you need both struct based and class based variants of collections like list, e.g. I've made Sequence and SequenceRef, the
first is
> > a struct template while the second is a class template. Both mix-in
their
> > implementation and both are quite useful. I guess for types like arrayed lists there's even four variants: struct/class dynamic/static; not to
speak
> > of higher-dimensional structures.
> >
> > It'll be interesting to see how much "D-think" there'll be in the first version of DTL...
> >
> >


July 20, 2004
I can't believe it to be a bad idea to support both inheritance and composition.


July 21, 2004
It's the old design question of complexity vs features. Some use-cases are not worth the added complexity. Keep in mind complexity makes a library harder to learn, use and maintain and many times the use-case is so seldomly used that it just adds baggage. Do I want a concept of "dynamic array" that I can subclass? personally, no, I don't. I've never subclassed vector<>, Vector or ArrayList (to use the C++/Java classes).

"Bent Rasmussen" <exo@bent-rasmussen.info> wrote in message news:cdjuu4$1s66$1@digitaldaemon.com...
> I can't believe it to be a bad idea to support both inheritance and composition.
>
>


July 21, 2004
Ben Hinkle schrieb:
> It's the old design question of complexity vs features. Some use-cases are
> not worth the added complexity. Keep in mind complexity makes a library
> harder to learn, use and maintain and many times the use-case is so seldomly
> used that it just adds baggage. Do I want a concept of "dynamic array" that
> I can subclass? personally, no, I don't. I've never subclassed vector<>,
> Vector or ArrayList (to use the C++/Java classes).

On the one hand, i agree that for D, a less complex library is quite appropriate.

On the other hand, i recall a nice use of subclassing an array (or any other container) in Sather, where language supports all of that so nicely that it adds no complexity to the library... However, D is not the same, and potential productivity gains would probably be minimal.

-eye
July 21, 2004
Ilya Minkov wrote:

> Ben Hinkle schrieb:
> 
>> It's the old design question of complexity vs features. Some use-cases are
>> not worth the added complexity. Keep in mind complexity makes a library
>> harder to learn, use and maintain and many times the use-case is so seldomly
>> used that it just adds baggage. Do I want a concept of "dynamic array" that
>> I can subclass? personally, no, I don't. I've never subclassed vector<>,
>> Vector or ArrayList (to use the C++/Java classes).
> 
> 
> On the one hand, i agree that for D, a less complex library is quite appropriate.
> 
> On the other hand, i recall a nice use of subclassing an array (or any other container) in Sather, where language supports all of that so nicely that it adds no complexity to the library... However, D is not the same, and potential productivity gains would probably be minimal.

There is an advantage to having a standard interface to interact with,
allowing the implementation of that interface to change.

For example, I may know I need to interact with a list of items, so I
declare my variable as a list<>.  I don't know what implementation of
the list will yield the better results yet, but at least I know I am
working on a subset of methods that are available in all
implementations.  I might start with a vector<> and then realize that
the backing array is inneficient for large amounts of data so I switch
to a linked_list<>.

It's not subclassing that empowers the user, but interfaces.

list<Coord> m_coordinates = vector<Coord>;
list<Coord> m_coordinates = linked_list<Coord>;

The List interface in Java has the standard "Collection" interface
as well as list specific functions.  The actual implementations of the
List have additional functions that pertain to that type of list (like
a getHead() or getTail() for LinkedList).

I have specified in Java libraries I wrote that I am returning a
collection, but did not identify what kind it was.  I needed the luxury of choosing whether I returned a list or a set--but I wasn't sure of the
details at that time.

So interfaces provide alot of help when you need to deal with a wider variety of things.

In D we have templates, so I don't know how much that changes the picture.  I can still see times where it would be very convenient to have an interface for the collections as opposed to working directly against an implementation.  Just to handle temporary unknowns.
July 21, 2004
"Berin Loritsch" <bloritsch@d-haven.org> wrote in message news:cdm2qk$2qgl$1@digitaldaemon.com...
> Ilya Minkov wrote:
>
> > Ben Hinkle schrieb:
> >
> >> It's the old design question of complexity vs features. Some use-cases
> >> are
> >> not worth the added complexity. Keep in mind complexity makes a library
> >> harder to learn, use and maintain and many times the use-case is so
> >> seldomly
> >> used that it just adds baggage. Do I want a concept of "dynamic array"
> >> that
> >> I can subclass? personally, no, I don't. I've never subclassed
vector<>,
> >> Vector or ArrayList (to use the C++/Java classes).
> >
> >
> > On the one hand, i agree that for D, a less complex library is quite appropriate.
> >
> > On the other hand, i recall a nice use of subclassing an array (or any other container) in Sather, where language supports all of that so nicely that it adds no complexity to the library... However, D is not the same, and potential productivity gains would probably be minimal.
>
> There is an advantage to having a standard interface to interact with, allowing the implementation of that interface to change.
>
> For example, I may know I need to interact with a list of items, so I declare my variable as a list<>.  I don't know what implementation of the list will yield the better results yet, but at least I know I am working on a subset of methods that are available in all implementations.  I might start with a vector<> and then realize that the backing array is inneficient for large amounts of data so I switch to a linked_list<>.
>
> It's not subclassing that empowers the user, but interfaces.
>
> list<Coord> m_coordinates = vector<Coord>;
> list<Coord> m_coordinates = linked_list<Coord>;
>
> The List interface in Java has the standard "Collection" interface
> as well as list specific functions.  The actual implementations of the
> List have additional functions that pertain to that type of list (like
> a getHead() or getTail() for LinkedList).
>
> I have specified in Java libraries I wrote that I am returning a collection, but did not identify what kind it was.  I needed the luxury of choosing whether I returned a list or a set--but I wasn't sure of the details at that time.
>
> So interfaces provide alot of help when you need to deal with a wider variety of things.
>
> In D we have templates, so I don't know how much that changes the picture.  I can still see times where it would be very convenient to have an interface for the collections as opposed to working directly against an implementation.  Just to handle temporary unknowns.

True. The runtime dispatching of Java's library is nice - though it does
mean the performance might not be as good as compile-time binding. The use
case you are talking about (protecting oneself from choosing a collection
type too early in the development process) can be avoided by making up an
alias. For example define
 alias vector MyCollectionAlias;
Then instead of using vector<Coord> everywhere you can use
MyCollectionAlias<Coord>. If the time comes when you want to use a linked
list instead of a vector you only have to change the alias definition and
recompile. Writing libraries might be more scary, though, unless one can
modify and recompile the library. Anyhow, there are trade-offs in either
direction.

-Ben


July 21, 2004
Ben Hinkle wrote:

> True. The runtime dispatching of Java's library is nice - though it does
> mean the performance might not be as good as compile-time binding. The use
> case you are talking about (protecting oneself from choosing a collection
> type too early in the development process) can be avoided by making up an
> alias.

I would argue that the performance hit is negligible--but without
anything to authoritatively prove that its just your word against mine.
My personal observation is that most projects I have seen that make
design decisions based solely on performance/micro-benchmark claims ends
up causing more issues than they solve.  (I'm not saying that its
happening in your work at all).

The example I gave is just one of the times it comes in handy.

> For example define
>  alias vector MyCollectionAlias;
> Then instead of using vector<Coord> everywhere you can use
> MyCollectionAlias<Coord>. If the time comes when you want to use a linked
> list instead of a vector you only have to change the alias definition and
> recompile. Writing libraries might be more scary, though, unless one can
> modify and recompile the library. Anyhow, there are trade-offs in either
> direction.

The alias thing is pretty cool.  Now that Java has "generics" of some
fashion, I think it can really use an alias command.

Personally, from a design perspective, I usually opt for the least
amount of lock-in possible to start with.  It's kind of the Agile
Programming motto of "you ain't gonna need it until you need it".
As a result, by the time I am done with the library (I've written many
Java libraries), it works well and is flexible enough for just about
everyone's need.

I think of the required contract, and do everything I can to leave the
implementation for as late in the game as possible.  Which is why I am a fan of interfaces.

Getting to the compile vs. runtime argument, I must say that as a
primarily Java developer I am shielded from that due to the runtime.
Modern JVMs will recompile the code natively and based on the actual implementation, you will have your compile time binding.

I just expressed my own personal opinions, take them as you will.

I agree that subclassing the the collection implementation (I think that
is what sparked this little side-tangent) doesn't buy much.
July 21, 2004
Ben Hinkle wrote:
> 
> True. The runtime dispatching of Java's library is nice - though it does
> mean the performance might not be as good as compile-time binding. The use
> case you are talking about (protecting oneself from choosing a collection
> type too early in the development process) can be avoided by making up an
> alias. For example define
>  alias vector MyCollectionAlias;
> Then instead of using vector<Coord> everywhere you can use
> MyCollectionAlias<Coord>. If the time comes when you want to use a linked
> list instead of a vector you only have to change the alias definition and
> recompile. Writing libraries might be more scary, though, unless one can
> modify and recompile the library. Anyhow, there are trade-offs in either
> direction.

I'm playing devil's advocate here for a moment.  Please bear with me,
while I have extensive programming experience, I am new to D.

Since I write a lot of code that is designed to be used as a library,
and backwards compatibility is very important to me, what would be the
impact of using an interface?

The reason I say that is because the following two methods are
functionally equivalent, but not syntactically equivalent:

vector<Coord>      getPolygon()
linked_list<Coord> getPolygon()

If I found that the linked_list worked better for me after I already
released the library I would have to choose between breaking backwards
compatibility or living with the deficiencies the other collection had.
Array backed lists and linked lists are best suited to different types
of interaction, so you can't just say there should be only one type of
list.

Now, if I were able to use an interface, I would be free to make the
change without breaking binary compatibility with any software already
installed on the system.  I would also be able to enjoy the boost in
performance that would arguably be orders of magnitude better than
runtime dispatching vs. compiletime dispatching.

I think this is about as best an argument as I can muster supporting
interfaces for the collections.

Within an application, one can always use the implementations directly
(in many cases that's what happens), so they still have the advantage
of compiletime binding where they need it.  With a library the goals
are interoperability so the interfaces make more sense to manage
potential change.

Does that make sense, or am I just blowing wind here?  If I'm blowing
wind, I'll stop now.
July 21, 2004
In article <cdmmvk$1mf$1@digitaldaemon.com>, Berin Loritsch says...
>
>I'm playing devil's advocate here for a moment.  Please bear with me, while I have extensive programming experience, I am new to D.
>
>Since I write a lot of code that is designed to be used as a library, and backwards compatibility is very important to me, what would be the impact of using an interface?

Potentially, a bit more flexibility.

>The reason I say that is because the following two methods are functionally equivalent, but not syntactically equivalent:
>
>vector<Coord>      getPolygon()
>linked_list<Coord> getPolygon()
>
>If I found that the linked_list worked better for me after I already released the library I would have to choose between breaking backwards compatibility or living with the deficiencies the other collection had. Array backed lists and linked lists are best suited to different types of interaction, so you can't just say there should be only one type of list.
>
>Now, if I were able to use an interface, I would be free to make the change without breaking binary compatibility with any software already installed on the system.  I would also be able to enjoy the boost in performance that would arguably be orders of magnitude better than runtime dispatching vs. compiletime dispatching.
>
>I think this is about as best an argument as I can muster supporting interfaces for the collections.
>
>Within an application, one can always use the implementations directly (in many cases that's what happens), so they still have the advantage of compiletime binding where they need it.  With a library the goals are interoperability so the interfaces make more sense to manage potential change.
>
>Does that make sense, or am I just blowing wind here?  If I'm blowing wind, I'll stop now.

Makes perfect sense, and I agree with you.  The C++ containers are actually a bit annoying in this regard as there is little support for polymorphism.  Adding an interface layer allows for at least a bit of wiggle room, while the user is still free to use the container directly if there are specialized methods he would like to call.  Iterators answer some of the polymorphic need in C++ but really not enough in most cases.  I really wouldn't mind seeing a set of interfaces for each general container type as it would give the most flexibility.


Sean


July 22, 2004
I'm a big fan of simplicity, so more power to you Ben.


"Ben Hinkle" <bhinkle@mathworks.com> wrote in message news:cdlvdj$2ot0$1@digitaldaemon.com...
> It's the old design question of complexity vs features. Some use-cases are not worth the added complexity. Keep in mind complexity makes a library harder to learn, use and maintain and many times the use-case is so
seldomly
> used that it just adds baggage. Do I want a concept of "dynamic array"
that
> I can subclass? personally, no, I don't. I've never subclassed vector<>, Vector or ArrayList (to use the C++/Java classes).
>
> "Bent Rasmussen" <exo@bent-rasmussen.info> wrote in message news:cdjuu4$1s66$1@digitaldaemon.com...
> > I can't believe it to be a bad idea to support both inheritance and composition.
> >
> >
>
>