View mode: basic / threaded / horizontal-split · Log in · Help
May 09, 2005
container vs collection
Here's a fun naming problem: should the "basic container interface" be 
called Container or Collection? I'm used to Collection from Java but I bet 
they used the name Collection because Container was taken by AWT to mean a 
Component that contains other Components. In D we don't have any such 
conflict so I'm seriously thinking of using Container instead of Collection. 
Thoughts?

I'm also thinking of using Enumeration (ala Java) for the interface for 
opApply and IndexedEnumeration for opApply that takes keys as well as 
values. Currently I'm calling those interfaces Sequences. Thoughts on those 
names would be appreciated, too.

So so summarize here a set of names I'm looking at:
interface Enumeration(Value) {
 int opApply( int delegate(inout Value value) dg);
}
interface IndexedEnumeration(Index,Value) : Enumeration!(Value) {
 alias Enumeration!(Value).opApply opApply;
 int opApply( int delegate(inout Index index, inout Value value) dg);
}
interface Container(Index,Value) : IndexedEnumeration!(Index,Value) {
 bool isEmpty();
 void clear();
 Container dup();
 size_t length();
 Value* lookup(Index index);
 Value opIndex(Index index);
 void opIndexAssign(Value val, Index index); // undefined if not present
 Value extract(Index index);
 void remove(Index index);
 Index[] keys();
 Value[] values();
}
interface OrderedContainer(Index,Value) : Container!(Index,Value) {
 OrderedContainer opSlice(Index a, Index b);
 OrderedContainer opSlice(OrderedContainer a, OrderedContainer b);
 OrderedContainer head();
 OrderedContainer tail();
 void next(int n = 1, int end = 0);
 int opApply(int delegate(inout OrderedContainer itr) dg);
 alias Container!(Index,Value).opApply opApply; // overload
 void remove(OrderedContainer x);
 alias Container!(Index,Value).remove remove; // overload
}
interface ListContainer(Value) : OrderedContainer!(size_t,Value) {
 void add(...);
 ListContainer opCatAssign(Value v);
 ListContainer opCat(Value v);
 ListContainer opCatAssign(OrderedContainer!(size_t,Value) v);
 ListContainer opCat(OrderedContainer!(size_t,Value) v);
 ListContainer opCat_r(Value v);
 void addTail(Value v);
 void addTail(OrderedContainer!(size_t,Value) v);
 void addHead(Value v);
 void addHead(OrderedContainer!(size_t,Value) v);
 Value removeHead();
 Value removeTail();
 void addBefore(OrderedContainer!(size_t,Value) subv, 
OrderedContainer!(size_t,Value) v);
 void addAfter(OrderedContainer!(size_t,Value) subv, 
OrderedContainer!(size_t,Value) v);
 ListContainer reverse();
}
May 09, 2005
Re: container vs collection
The only problem that I see is your dup method.  It returns Container.
What would probably be preferable is to define it for more specific
interfaces, so that casts are less likely.  That is, if I want this to
work w/o casting:
Set s = new HashSet();
Set t = s.dup();

A child class cannot override the return type.  The following code (with
DMD 0.120)
module i;
interface A {
 A dup();
}
interface B:A {
 B dup();
}
class C : B {
 B dup() {
   return null;
 }
}
void main() {
}

produces this:
$ dmd i.d
i.d(11): class i.C interface function B.dup isn't implemented

It sucks.  I've bitched about it before, and still don't understand why
it can't work, just that it doesn't.

John Demme

On Mon, 2005-05-09 at 18:54 -0400, Ben Hinkle wrote:
> Here's a fun naming problem: should the "basic container interface" be 
> called Container or Collection? I'm used to Collection from Java but I bet 
> they used the name Collection because Container was taken by AWT to mean a 
> Component that contains other Components. In D we don't have any such 
> conflict so I'm seriously thinking of using Container instead of Collection. 
> Thoughts?
> 
> I'm also thinking of using Enumeration (ala Java) for the interface for 
> opApply and IndexedEnumeration for opApply that takes keys as well as 
> values. Currently I'm calling those interfaces Sequences. Thoughts on those 
> names would be appreciated, too.
> 
> So so summarize here a set of names I'm looking at:
> interface Enumeration(Value) {
>   int opApply( int delegate(inout Value value) dg);
> }
> interface IndexedEnumeration(Index,Value) : Enumeration!(Value) {
>   alias Enumeration!(Value).opApply opApply;
>   int opApply( int delegate(inout Index index, inout Value value) dg);
> }
> interface Container(Index,Value) : IndexedEnumeration!(Index,Value) {
>   bool isEmpty();
>   void clear();
>   Container dup();
>   size_t length();
>   Value* lookup(Index index);
>   Value opIndex(Index index);
>   void opIndexAssign(Value val, Index index); // undefined if not present
>   Value extract(Index index);
>   void remove(Index index);
>   Index[] keys();
>   Value[] values();
> }
> interface OrderedContainer(Index,Value) : Container!(Index,Value) {
>   OrderedContainer opSlice(Index a, Index b);
>   OrderedContainer opSlice(OrderedContainer a, OrderedContainer b);
>   OrderedContainer head();
>   OrderedContainer tail();
>   void next(int n = 1, int end = 0);
>   int opApply(int delegate(inout OrderedContainer itr) dg);
>   alias Container!(Index,Value).opApply opApply; // overload
>   void remove(OrderedContainer x);
>   alias Container!(Index,Value).remove remove; // overload
> }
> interface ListContainer(Value) : OrderedContainer!(size_t,Value) {
>   void add(...);
>   ListContainer opCatAssign(Value v);
>   ListContainer opCat(Value v);
>   ListContainer opCatAssign(OrderedContainer!(size_t,Value) v);
>   ListContainer opCat(OrderedContainer!(size_t,Value) v);
>   ListContainer opCat_r(Value v);
>   void addTail(Value v);
>   void addTail(OrderedContainer!(size_t,Value) v);
>   void addHead(Value v);
>   void addHead(OrderedContainer!(size_t,Value) v);
>   Value removeHead();
>   Value removeTail();
>   void addBefore(OrderedContainer!(size_t,Value) subv, 
> OrderedContainer!(size_t,Value) v);
>   void addAfter(OrderedContainer!(size_t,Value) subv, 
> OrderedContainer!(size_t,Value) v);
>   ListContainer reverse();
> }
> 
> 
>
May 09, 2005
Re: container vs collection
On Mon, 9 May 2005 18:54:50 -0400, Ben Hinkle wrote:

> Here's a fun naming problem: should the "basic container interface" be 
> called Container or Collection? 

Can such a thing be empty? If so, then I'd use Container. An empty
collection is an oxymoron, because if its empty it is not a collection of
anything. However, if it can never be empty, then Collection is probably a
better term.

-- 
Derek Parnell
Melbourne, Australia
10/05/2005 9:44:15 AM
May 09, 2005
Re: container vs collection
"John Demme" <me@teqdruid.com> wrote in message 
news:1115681750.17438.9.camel@localhost.localdomain...
> The only problem that I see is your dup method.  It returns Container.
> What would probably be preferable is to define it for more specific
> interfaces, so that casts are less likely.  That is, if I want this to
> work w/o casting:
> Set s = new HashSet();
> Set t = s.dup();

Correct. This is the downside of interfaces. When I took the unittests for 
the structs and converted them to classes I had to change two things: the 
"new CList" etc and the dup casting. Everything else just worked. One 
solution to avoid the cast is to use the dup on the implementation:
Set t = new HashSet(s.impl.dup);
since my classes have an "impl" member that is the struct that actually 
implements the container. In fact the definition of HashSet.dup (or the 
equivalent for my containers) is exactly "return new <class>(impl.dup)". 
Most functions in the classes are a light wrapper around the struct 
implementations (together with some casting to get to the impl member).

> A child class cannot override the return type.  The following code (with
> DMD 0.120)
> module i;
> interface A {
>  A dup();
> }
> interface B:A {
>  B dup();
> }
> class C : B {
>  B dup() {
>    return null;
>  }
> }
> void main() {
> }
>
> produces this:
> $ dmd i.d
> i.d(11): class i.C interface function B.dup isn't implemented
>
> It sucks.  I've bitched about it before, and still don't understand why
> it can't work, just that it doesn't.

I don't really know but I'm guessing the reason is due to the following. 
When an object is cast to an interface the "this" pointer is adjusted by an 
offset specific to the class and interface. Two different interfaces have 
two different offsets. So if dup() returns an interface A and then you try 
to return an interface B the offset for A and B are different and so there 
is no way to implicitly consider every B as also an A. For classes a 
subclass does not have any offset so it becomes possible to consider every 
"this" pointer for a class to also be "this" for the super-class.
May 10, 2005
Re: container vs collection
"Derek Parnell" <derek@psych.ward> wrote in message 
news:1k98whbt5s248$.8uyoosdg6m2.dlg@40tude.net...
> On Mon, 9 May 2005 18:54:50 -0400, Ben Hinkle wrote:
>
>> Here's a fun naming problem: should the "basic container interface" be
>> called Container or Collection?
>
> Can such a thing be empty? If so, then I'd use Container. An empty
> collection is an oxymoron, because if its empty it is not a collection of
> anything. However, if it can never be empty, then Collection is probably a
> better term.

They can be empty, so that would be an argument for Container.
May 10, 2005
Re: container vs collection
IMHO, Container is a bit different than Collection

Container - contains.
Collection - holds.

Containtment presumes 1-to-n relationship . Collection does not have such
limitation - the same element can participate in different collections.

Containment frequently have geometrical/physical meaning (at least in GUI).
Element can be placed in container and referenced in many collections.

IMHO, as usual.

And is it possible to rename ArrayList to something different?
It is an oxymoron, isn't it?

Andrew.



"Ben Hinkle" <ben.hinkle@gmail.com> wrote in message 
news:d5opnt$21m$1@digitaldaemon.com...
> Here's a fun naming problem: should the "basic container interface" be 
> called Container or Collection? I'm used to Collection from Java but I bet 
> they used the name Collection because Container was taken by AWT to mean a 
> Component that contains other Components. In D we don't have any such 
> conflict so I'm seriously thinking of using Container instead of 
> Collection. Thoughts?
>
> I'm also thinking of using Enumeration (ala Java) for the interface for 
> opApply and IndexedEnumeration for opApply that takes keys as well as 
> values. Currently I'm calling those interfaces Sequences. Thoughts on 
> those names would be appreciated, too.
>
> So so summarize here a set of names I'm looking at:
> interface Enumeration(Value) {
>  int opApply( int delegate(inout Value value) dg);
> }
> interface IndexedEnumeration(Index,Value) : Enumeration!(Value) {
>  alias Enumeration!(Value).opApply opApply;
>  int opApply( int delegate(inout Index index, inout Value value) dg);
> }
> interface Container(Index,Value) : IndexedEnumeration!(Index,Value) {
>  bool isEmpty();
>  void clear();
>  Container dup();
>  size_t length();
>  Value* lookup(Index index);
>  Value opIndex(Index index);
>  void opIndexAssign(Value val, Index index); // undefined if not present
>  Value extract(Index index);
>  void remove(Index index);
>  Index[] keys();
>  Value[] values();
> }
> interface OrderedContainer(Index,Value) : Container!(Index,Value) {
>  OrderedContainer opSlice(Index a, Index b);
>  OrderedContainer opSlice(OrderedContainer a, OrderedContainer b);
>  OrderedContainer head();
>  OrderedContainer tail();
>  void next(int n = 1, int end = 0);
>  int opApply(int delegate(inout OrderedContainer itr) dg);
>  alias Container!(Index,Value).opApply opApply; // overload
>  void remove(OrderedContainer x);
>  alias Container!(Index,Value).remove remove; // overload
> }
> interface ListContainer(Value) : OrderedContainer!(size_t,Value) {
>  void add(...);
>  ListContainer opCatAssign(Value v);
>  ListContainer opCat(Value v);
>  ListContainer opCatAssign(OrderedContainer!(size_t,Value) v);
>  ListContainer opCat(OrderedContainer!(size_t,Value) v);
>  ListContainer opCat_r(Value v);
>  void addTail(Value v);
>  void addTail(OrderedContainer!(size_t,Value) v);
>  void addHead(Value v);
>  void addHead(OrderedContainer!(size_t,Value) v);
>  Value removeHead();
>  Value removeTail();
>  void addBefore(OrderedContainer!(size_t,Value) subv, 
> OrderedContainer!(size_t,Value) v);
>  void addAfter(OrderedContainer!(size_t,Value) subv, 
> OrderedContainer!(size_t,Value) v);
>  ListContainer reverse();
> }
>
>
>
May 10, 2005
Re: container vs collection
On Mon, 9 May 2005 22:47:28 -0700, Andrew Fedoniouk wrote:


[snip]
> 
> And is it possible to rename ArrayList to something different?
> It is an oxymoron, isn't it?

No, it's a tautology - sort of ... ;-)

-- 
Derek
Melbourne, Australia
10/05/2005 4:21:44 PM
May 10, 2005
Re: container vs collection
"Andrew Fedoniouk" <news@terrainformatica.com> wrote in message 
news:d5phpo$esl$1@digitaldaemon.com...
> IMHO, Container is a bit different than Collection
>
> Container - contains.
> Collection - holds.
>
> Containtment presumes 1-to-n relationship . Collection does not have such
> limitation - the same element can participate in different collections.
>
> Containment frequently have geometrical/physical meaning (at least in 
> GUI).
> Element can be placed in container and referenced in many collections.

ok - it sounds like a vote for Collection

> IMHO, as usual.
>
> And is it possible to rename ArrayList to something different?
> It is an oxymoron, isn't it?

The idea is that it is a list backed by an array. Calling it "Array" 
wouldn't distinguish it from builtin arrays and calling it "List" would 
conflict with calling linked-list "List". Calling it "Vector" is an option 
to mimic C++/Java but to me (my silly math background) a Vector is a point 
in space to be used in a math context. Sure an instance of an array can be 
considered a point in some huge space of all possible memory contents but so 
can any other data structure. Plus the name ArrayList fits well with 
ArrayHeap (a heap backed by an array) and the aliases ArrayQueue and 
ArrayStack.
May 11, 2005
Re: container vs collection
"John Demme" <me@teqdruid.com> wrote in message 
news:1115681750.17438.9.camel@localhost.localdomain...
> The only problem that I see is your dup method.  It returns Container.
> What would probably be preferable is to define it for more specific
> interfaces, so that casts are less likely.

I've been getting annoyed with the casting, too, actually. So I've been 
experimenting with smushing the interfaces into one and defining aliases for 
those "sub-interfaces" that implement more and more of the super-interface. 
So basically most of the Container interface is optional, which isn't very 
OO but removed lots of casts as long as you declare your variables as one of 
the interfaces.

interface Enumeration(Value) {
 int opApply( int delegate(inout Value value) dg);
}
interface IndexedEnumeration(Index,Value) : Enumeration!(Value) {
 alias Enumeration!(Value).opApply opApply;
 int opApply( int delegate(inout Index index, inout Value value) dg);
}
interface Container(Index,Value) : IndexedEnumeration!(Index,Value) {
 bool isEmpty();
 void clear();
 Container dup();
 size_t length();
 Value* lookup(Index index);
 Value opIndex(Index index);
 void opIndexAssign(Value val, Index index); // undefined if not present
 Value extract(Index index);
 void remove(Index index);
 Index[] keys();
 Value[] values();
 void remove(Container x);
 void add(...);

 // OrderedContainer members
 Container opSlice(Index a, Index b); //optional
 Container opSlice(Container a, Container b); //optional
 Container head(); //optional
 Container tail(); //optional
 Index key(); //optional
 Value value(); //optional
 void next(int n = 1, int end = 0); //optional
 int opApply(int delegate(inout Container itr) dg); //optional

 // List members
 Container opCatAssign(Value v); //optional
 Container opCat(Value v); //optional
 Container opCatAssign(Container v); //optional
 Container opCat(Container v); //optional
 Container opCat_r(Value v); //optional
 void addTail(Value v); //optional
 void addTail(Container v); //optional
 void addHead(Value v); //optional
 void addHead(Container v); //optional
 Value removeHead(); //optional
 Value removeTail(); //optional
 void addBefore(Container subv, Container v); //optional
 void addAfter(Container subv, Container v); //optional
 Container reverse(); //optional
}
alias Container OrderedContainer;
template IList(Value) {
 alias Container!(size_t,Value) IList;
}
template IStack(Value) {
 alias Container!(size_t,Value) IStack;
}
template IQueue(Value) {
 alias Container!(size_t,Value) IQueue;
}
template AssocContainer(Key,Value) {
 alias Container!(Key,Value) AssocContainer;
}
May 11, 2005
Re: container vs collection
"John Demme" <me@teqdruid.com> wrote in message 
news:1115681750.17438.9.camel@localhost.localdomain...
> The only problem that I see is your dup method.  It returns Container.
> What would probably be preferable is to define it for more specific
> interfaces, so that casts are less likely.

It just occurred to me that covariance would work with abstract classes 
instead of interfaces. Making Container and friends abstract classes would 
lose some of the flexibility of interfaces but I can't really imagine a 
container that would implement "interface Container" that would also be able 
to subclass "abstract class Container". I'll try that out before going ahead 
with the "smushed interface" API. The smushed API should be a last resort.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home