C
Chris M. Thomasson
[...]Flash Gordon said:Only if your access pattern is list like.
Yes! Sorry for basically repeating you're statement.
[...]Flash Gordon said:Only if your access pattern is list like.
What is the exact equivalent using your syntax?
Nick said:But you shouldn't have exposed your choice of data structure to the
application
level code anyway. It all should have been hidden away behind an
abstraction
anyway. The application wants to add things, remove things and find
things
it shouldn't care if it's an array, a linked list or a relational
database.
Changeing the container type is not expensive becasue it involves
rewriting
one thin library.
You may not know how big the system is going to get.
Or you may
be concentrating on getting other things right first. If things
are being addded and removed semi-randomly than a balanced tree
may be the right thing but an array ot list might be ok for a first
hack.
I've seen an application scale from a handful of thingies (an
important
measure of the system's load) to thousands of thingies. Admittedly
this
was known from the start.
I think Jacob wants the flexibility in his library. Note even with C++
which has a set of generic containers I would still say hide the
choice
of container from the application code.
flexible arrays can be nice. I'd hide the malloc() in a library.
I can't say I've a need for that, not in the was you are doing it. I doo Software specialization and subclassing (This was the original theme I
wanted to discuss with "Adapting software to multiple usage patterns")
have stuff with indirection through function pointers, but that is not
working in the same [way] as your interface.
I've done similar-ish things but not with containers. It doesn't feel
right.
The C++ invented a whole major language construct (templates) to avoid
using inheritance (which is what your function pointers look like) to
implement containers.
But you shouldn't have exposed your choice of data structure to the
application
level code anyway. It all should have been hidden away behind an
abstraction
anyway. The application wants to add things, remove things and find
things
it shouldn't care if it's an array, a linked list or a relational
database.
Changeing the container type is not expensive becasue it involves
rewriting
one thin library.
You may not know how big the system is going to get. Or you may
be concentrating on getting other things right first. If things
are being addded and removed semi-randomly than a balanced tree
may be the right thing but an array ot list might be ok for a first
hack.
Which a well-designed program confines to a small part of the code.
You should only be caught by this once (at worst) because after that
you
will have Refactored Mercilessly.
really? I thought C++ demonstrated that you don't need inheritance for
a decent set of containers.
...which is poorly modelled by inheritance
Perhaps.
which is not how C++ did it...
perhaps you could do a template thingy without inheritance. It's a
common
interface you need rather than inheritance (just because C++ does
interfaces
via inheritance doesn't mean you have to do it that way)
... you need some kind of way to specify the "one of these is also one
of those" type relations, so that code can take a container whether it's
a list or an array, and that starts getting suspiciously similar to the
territory of inheritance and such.
Actually I was thinking of a library where the application code calls
explicit functions, and a fair way down the call graph in the library it
goes through function pointers to database specific functions so we can
select the database type at run time. However, that is deeply embedded
in the library and no where near the level of application code.
jacob said:Seebs a écrit :
If you use
container->lpVtbl->GetElement(container,index);
you can use it with lists, arraylists (flexible arrays) and all
*sequential* containers.
I would make the distinction at the top level between sequential
containers (lists, arrays, arraylists, and maybe others) and
non sequential ones like hash tables for instance, where the idea of
"the item 42" doesn't make any sense.
I would call this just grouping, not inheritance since there
are shared characteristics but not a class hierarchy.
Trees and graphs would be another type of containers, of course
completely different (and with a complete different access methods)
than sequential containers.
jacob said:Seebs a écrit :
If you use
container->lpVtbl->GetElement(container,index);
you can use it with lists, arraylists (flexible arrays) and all
*sequential* containers.
I would make the distinction at the top level between sequential
containers (lists, arrays, arraylists, and maybe others) and
non sequential ones like hash tables for instance, where the idea of
"the item 42" doesn't make any sense.
I would call this just grouping, not inheritance since there
are shared characteristics but not a class hierarchy.
Trees and graphs would be another type of containers, of course
completely different (and with a complete different access methods)
than sequential containers.
If you use
container->lpVtbl->GetElement(container,index);
you can use it with lists, arraylists (flexible arrays) and all
*sequential* containers.
Ive wanted to iterate over all the elements of a hash in a language
which has hashes natively, whilst at other points using it as a hash. If
you can iterate over it, then there is a concept of "the item 42" (even
if the order is not obvious, as long as it is consistent on any instance
of a hash whilst it exists between modifications). The same can apply to
trees (where there is a more obvious ordering).
The container concept can be thought of as the base class with the lists
implementation being derived from it, even if that is not how you have
implemented it.
It's not unusual to want to want to do a tree traversal where you are
iterating over all the elements of the tree.
jacob said:Flash Gordon a écrit :
I thought about that by using a generic creation function for each
container
that would receive a set of flags specifying the size of the container
(huge, big, normal, small tiny) and the creation function would choose
according to the flags which vtable to set into the new list.
The interface of all those function would still be exactly the same, the
algorithms would be quite different of course.
For big lists we would use a heap manager, for normal lists malloc at
each element and for tiny lists we would allocate all the elements at once
That is what I proposed with the theme of this thread:
"Adapting software to multiple usage patterns"
Seebs said:In ruby/perl, it's definitely possible for order to vary with modifications,
but I'm not even sure it's impossible for order to vary without
externally-visible modifications.
Imagine a hypothetical implementation where the hash may, under some
non-obvious circumstances, choose to restructure itself internally. (Say,
some kind of "please clean things up if you can" message coming from a
garbage collector causing it to rebuild itself in some way.)
Yes.
Basically, any container-like thing can reasonably have an iterator,
but the behavior might vary widely.
Richard Heathfield said:jacob navia wrote: said:For instance this proposal about a container library
is an evolution that doesn't add any new complexity to the language.
That depends on whether you consider the library to be a part of the
language. Some do, others don't. [... snip rest...]
Richard Heathfield said:I guess I'm a lot less fussy about what I am prepared to accept as a
formal system.
Seebs said:Of course it does.
The library is part of "the language".
Seebs said:Which I wouldn't. If I were implementing this, I'd make it something
like:
static inline ctr_getelement(container *x, int index) {
x->vtable->getelement(x, index);
}
and write
ctr_getelement(x, index);
... Because C does not use camel case.
Tim Rentsch said:Now there's a laugh. C has nothing even vaguely resembling
a formal semantics.
Phil said:C doesn't /use/ any case. It copes with camel case precisely
as well as it copes with lower case.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.