[Prev][Next][Index][Thread]

Re: A Proposal!!



In article <39289CC4.B6BD7A8A@cup.hp.com>, eric_gouriou@hp.com wrote:

> Bruce Hoult wrote:
> [...]
> > -------------------------------------------
> > The result of add! on a stretchy vector is == to the stretchy-vector
> > argument, which is modified by this operation. add!
> > -------------------------------------------
> > 
> > Is it really necessary to specify this in the language spec?
> 
>  I'd say yes. I consider this to be the defining characteristic of
> a <stretchy-vector>.

Well it seems to me to mandate wasteful and inefficient implementation by
forcing an extra level of indirection that 1) may not be wanted, and 2)
will already be provided by client code that has to deal with other types
of collection.

There are basically two ways to implement a stretchy vector (using a
mythical C-with-templates :-)) :

----------------------------------------------------
template<class T>
struct stretchy_vector {
   int maxSize;
   int curSize;
   T *items;
}

void add_item(stretchy_vector<T> *v, T newItem)
{
   if (++v->curSize = v->maxSize)
   {
      v->maxSize += increment;
      v->items = realloc(v->items, v->maxSize * sizeof(T));
   }
   v->items[curSize] = newItem;
}
----------------------------------------------------
template<class T>
struct stretchy_vector {
   int maxSize;
   int curSize;
   T items[0];
}

stretchy_vector<T>* add_item(stretchy_vector<T> *v, T newItem)
{
   if (++v->curSize = v->maxSize)
   {
      v->maxSize += increment;
      v = realloc(v, sizeof(stretchy_vector<T>) + v->maxSize * sizeof(T));
   }
   v->items[curSize] = newItem;
   return v;
}
----------------------------------------------------


In C the first version (which enforces == after add!) is better because it
allows the stretchy_vector to be allocated as a global or on the stack or
as part of another object.  But in Dylan none of those apply (at least
with current compilers) and:

- the first version is going to give you two objects on the heap instead of one.

- generic code that works with other types of collections has to work with
the second version, so the wrapping in the first version is unnecessary

- if the user wants object identity, he can always wrap the second version
himself.  He can't unwrap the first one, no matter what he wants.


The only benefit of the Dylan standard specifying the implementation to be
the first one is to people who both want object identity and *know* for
sure that they have a stretchy-vector and not some other type of
collection.  That's an assymetry, a dangerous one (because it leads people
to write code for stretchy-vector that won't work for other collections),
and one that isn't necessary because users who want the benefits of your
way can get them for themselves (or there could be a
wrapped-stretchy-vector class as well as stretchy-vector).

-- Bruce



References: