Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Container library (continued)

5 views
Skip to first unread message

jacob navia

unread,
Mar 16, 2010, 7:07:38 PM3/16/10
to
Data allocation strategies for containers can vary wildly, depending on
the specific container and on the application. Environment
considerations play also a major role: if there is enough RAM many
things can be handled QUITE differently than when there isn't.

It is impossible to find a strategy that can be always good in all
situations, so naturally, we need an object with (roughly) 3 function
pointers:

(1) MALLOC
(2) FREE
(3) REALLOC

This table of functions will be used by a container for
allocating/releasing memory. It will default to the standard C
functions, but can be changed so that a GC is used, for instance. In
that case we would have

MALLOC --> GC_malloc
FREE --> no operation
REALLOC --> GC_realloc.

Now, should this object be a global part of the library, i.e. a single
allocation object for the whole library, or should each container class
(hash tables, lists, dictionaries) have one, or should each individual
container have one?

If we have a single global object, changing the behavior of our
containers is very easy, we have a single object to change and we are
done. Obviously, this is VERY global and forces the user to have always
the same allocation strategy for all containers.

If we have a per class of container design, we have more flexibility, we
could use the GC for hash tables but not for lists, etc. The price to
pay is increased difficulty to change the behavior of all objects... To
change from the default object to the GC, for instance, we would have to
go through all container classes. True, the library could provide a
function to do that, but if we add a container we would have to modify
that function again and again.

If we have an allocation object per individual container we have the
maximum flexibility but changing the allocation strategy becomes QUITE
complicated.


Personally, I think that is easier to understand the first option:
having a single object that allocates/frees memory. It is rare that we
would want to use a GC, say, and at the same time malloc/free at the
same time.

Obviously I am not sure, hence this message. What do you think?

jacob

Seebs

unread,
Mar 16, 2010, 7:22:09 PM3/16/10
to
On 2010-03-16, jacob navia <ja...@spamsink.net> wrote:
> Now, should this object be a global part of the library, i.e. a single
> allocation object for the whole library, or should each container class
> (hash tables, lists, dictionaries) have one, or should each individual
> container have one?

Hmm.

> Personally, I think that is easier to understand the first option:
> having a single object that allocates/frees memory. It is rare that we
> would want to use a GC, say, and at the same time malloc/free at the
> same time.
>
> Obviously I am not sure, hence this message. What do you think?

I would say probably per-container. It sounds like the individual
containers are going to end up performing roughly the role that a
less-library-able container implementation would assign to an individual
struct type. I am not sure, though.

See, what I would normally do is expect that there'd be an object type,
and those objects would have their own alloc/free routines. But the
container itself needs allocation too. Depending, it might make sense
to have a single global "container objects allocator", but then each
container can be given the alloc/free routines for the specific things
it contains.

So, if I'm doing a container of foos and a container of bars, both of
them use container_alloc() for allocating internal data structures,
but one uses foo_alloc() to allocate space for contained things, and
the other uses bar_alloc(). And in all cases, the default is to just
use malloc.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Andrew Poelstra

unread,
Mar 16, 2010, 9:32:29 PM3/16/10
to
On 2010-03-16, jacob navia <ja...@spamsink.net> wrote:
> Data allocation strategies for containers can vary wildly, depending on
> the specific container and on the application. Environment
> considerations play also a major role: if there is enough RAM many
> things can be handled QUITE differently than when there isn't.
>
> It is impossible to find a strategy that can be always good in all
> situations, so naturally, we need an object with (roughly) 3 function
> pointers:
>
> (1) MALLOC
> (2) FREE
> (3) REALLOC
>
> This table of functions will be used by a container for
> allocating/releasing memory. It will default to the standard C
> functions, but can be changed so that a GC is used, for instance. In
> that case we would have
>
> MALLOC --> GC_malloc
> FREE --> no operation
> REALLOC --> GC_realloc.
>
> Now, should this object be a global part of the library, i.e. a single
> allocation object for the whole library, or should each container class
> (hash tables, lists, dictionaries) have one, or should each individual
> container have one?
>

I like the third option.

I started out defending the second, but when I thought about common use
cases, it makes more sense to select an allocator when allocating an
object; otherwise, if I needed to find out what allocator was in use, I'd
have to trace the code backwards to wherever that was set.

The reason I don't like the first option is that is restricts extensibility.
If I used your libraries, but decided I didn't like your hash table (IME
hash tables have the most to gain by /not/ being generalized) I would be in
the position of handing one allocator to my hash table, and one allocator
to all N of your classes.

To me that feels yucky, to have some classes sharing allocators and some
classes needing their own.

--
Andrew Poelstra

ng2010

unread,
Mar 17, 2010, 12:22:38 AM3/17/10
to
So sad to be dying and seeing youth tackling problems already solved in
my own youth.


jacob navia

unread,
Mar 17, 2010, 4:45:35 AM3/17/10
to
Andrew Poelstra a écrit :

>
> The reason I don't like the first option is that is restricts extensibility.
> If I used your libraries, but decided I didn't like your hash table (IME
> hash tables have the most to gain by /not/ being generalized) I would be in
> the position of handing one allocator to my hash table, and one allocator
> to all N of your classes.
>

Mmm this is a good point. I did not think about that.

Obviously, the solution is (if we retain a single global object) that each class contains a pointer
to a specific allocator for the class. If that pointer is NULL (default situation), we use the
global object. If it is not NULL, it is assumed that it points to a similar table of functions
(malloc/free/realloc) that the user has set up for this class.

Within this schema, it is still easy to change the global behavior of all objects, but subclasssing
with a custom allocator is still easy and is NOT affected by any changes in the global behavior.

Thanks for your contribution.
jacob

jacob navia

unread,
Mar 17, 2010, 4:46:46 AM3/17/10
to
ng2010 a écrit :
> So sad to be dying and seeing youth tackling problems already solved in
> my own youth.
>
>
You misunderstand. I am not trying to invent a new way of doing those things. I am trying to invent
a generalized standard way of doing that in C. This has never been done before for C.

Nick Keighley

unread,
Mar 17, 2010, 4:58:15 AM3/17/10
to
On 17 Mar, 04:22, "ng2010" <ng2...@att.invalid> wrote:
> So sad to be dying and seeing youth tackling problems already solved in
> my own youth.

and the solution was? I'm not convinced there *is* a single right
answer for all situations.

Nick Keighley

unread,
Mar 17, 2010, 5:01:42 AM3/17/10
to

both? That is a global allocation object that is the default allocator
that can be over-ridden on a per container basis.

If I have a number of small conatiners and a single gigantic container
maybe only gigantic container needs a special memory allocator. I
could imagine containers needing special memory (eg. for DMA).

Also the STL does it this way...


Dr Malcolm McLean

unread,
Mar 17, 2010, 5:11:29 AM3/17/10
to
> Now, should this object be a global part of the library, i.e. a single
> allocation object for the whole library, or should each container class
> (hash tables, lists, dictionaries) have one, or should each individual
> container have one?
>
Most of the time user won't really care abput the memory allocation
strategy wants. So the default should be to use some sensible scheme
(probably stdlib malloc) and to kep this away from the user.
However you can provide a function to set the defaults for all
containers. It should apply only to containers created after the call.
Then you can also provide special contructors that take memory
management function pointers as arguments. Most of the time these
won't be used, but they provide fine control to those who need it.

Andrew Poelstra

unread,
Mar 17, 2010, 10:50:09 AM3/17/10
to

I like this (and Nick suggested it as well downthread). Malcolm
suggested having separate constructors for people who want their
own memory management. The regular constructor would just use
malloc().

--
Andrew Poelstra
http://www.wpsoftware.net/andrew

Seebs

unread,
Mar 17, 2010, 11:36:27 AM3/17/10
to
On 2010-03-17, jacob navia <ja...@nospam.org> wrote:
> You misunderstand. I am not trying to invent a new way of doing
>those things. I am trying to invent a generalized standard way
>of doing that in C. This has never been done before for C.

It's been done repeatedly, except for the "standard" part.

I honestly don't think that generalizing to "container" is going to be
useful in C. In a language that doesn't have meaningful inheritance,
it's very unusual for this kind of approach to get widespread adoption.
I think you'd do better to make a list library and a hash library,
for instance.

jacob navia

unread,
Mar 17, 2010, 12:33:26 PM3/17/10
to
Seebs a écrit :

> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:
>> You misunderstand. I am not trying to invent a new way of doing
>> those things. I am trying to invent a generalized standard way
>> of doing that in C. This has never been done before for C.
>
> It's been done repeatedly, except for the "standard" part.
>
> I honestly don't think that generalizing to "container" is going to be
> useful in C. In a language that doesn't have meaningful inheritance,
> it's very unusual for this kind of approach to get widespread adoption.


I do not know of any other attempt in C.

Inheritance is not necessary at all. The code works without it.

Seebs

unread,
Mar 17, 2010, 12:50:06 PM3/17/10
to
On 2010-03-17, jacob navia <ja...@spamsink.net> wrote:
> Seebs a �crit :

>> I honestly don't think that generalizing to "container" is going to be
>> useful in C. In a language that doesn't have meaningful inheritance,
>> it's very unusual for this kind of approach to get widespread adoption.

> I do not know of any other attempt in C.

I don't know of another generalization to container in C. I know of
many lists and vectors and the like.

> Inheritance is not necessary at all. The code works without it.

But without inheritance, "container" is not a useful level of abstraction.

The thing that makes "container" useful is that it provides for commonality
between "list" and "hash". But that's only useful when list and hash are
the types you actually work with, but because of inheritance, you can treat
them both as containers.

Without inheritance, either you have to call things "container" regardless
of which they are, and thus have access to an API that only makes sense for
a list when you're using a hash, and an API that only makes sense for a hash
when you're using a list, or you lose the ability to write a function which
just takes a "container".

I have often used list libraries. I'd use hash libraries if I needed a hash.
In neither case would I use a "container" library in C -- it's the wrong
level of abstraction for C, so far as I can tell. I've never in any language
wanted "a container". In OO languages, it's useful that the specific things
I request are also generically "containers". In C, it's not useful, because
I can't do anything with it.

Andrew Poelstra

unread,
Mar 17, 2010, 1:43:02 PM3/17/10
to
On 2010-03-17, Seebs <usenet...@seebs.net> wrote:
> On 2010-03-17, jacob navia <ja...@spamsink.net> wrote:
>
>> I do not know of any other attempt in C.
>
> I don't know of another generalization to container in C. I know of
> many lists and vectors and the like.
>
>> Inheritance is not necessary at all. The code works without it.
>
> But without inheritance, "container" is not a useful level of abstraction.
>
> The thing that makes "container" useful is that it provides for commonality
> between "list" and "hash". But that's only useful when list and hash are
> the types you actually work with, but because of inheritance, you can treat
> them both as containers.
>
> Without inheritance, either you have to call things "container" regardless
> of which they are, and thus have access to an API that only makes sense for
> a list when you're using a hash, and an API that only makes sense for a hash
> when you're using a list, or you lose the ability to write a function which
> just takes a "container".
>
> I have often used list libraries. I'd use hash libraries if I needed a hash.
> In neither case would I use a "container" library in C -- it's the wrong
> level of abstraction for C, so far as I can tell. I've never in any language
> wanted "a container". In OO languages, it's useful that the specific things
> I request are also generically "containers". In C, it's not useful, because
> I can't do anything with it.
>

You can do OO in C. I think most people don't because they have
it drilled into their heads that "C is not an object-oriented"
language. Which to be fair, it isn't, but that doesn't mean that
there are reasonably-elegant[1] ways to do OO.

What Jacob has described doing (for a couple of projects) is
making the first element of his structs a vptr table, and interally
casting all his containers to this vtpr table, then calling the
appropriate "method" from there.

So that's inheritance. But from the user's perspective, it requires
casting each list/vector/hash/whatever to a Container * before
passing it to a function.

eg.
int data = 5;
List mylist = new_list();
append((Container *) mylist, &data);

Which is kinda ugly, but the cast can be hidden by a macro around
the function, and then you're golden:

#define append(a, b) (append((Container *)a, b)

append(mylist, &data);


I think this is a nice interface, has appropriate data-hiding, and
provides genericity. If he published the vptr structure, it would
also be extensible by other libraries.


[1] And "Reasonably elegent" often means "more elegant than C++"

Seebs

unread,
Mar 17, 2010, 1:47:50 PM3/17/10
to
On 2010-03-17, Andrew Poelstra <apoe...@localhost.localdomain> wrote:
> You can do OO in C. I think most people don't because they have
> it drilled into their heads that "C is not an object-oriented"
> language. Which to be fair, it isn't, but that doesn't mean that
> there are reasonably-elegant[1] ways to do OO.

Oh, certainly. I just don't think that it's a good enough fit to reward
the kind of hierarchy the "container" library implies.

> I think this is a nice interface, has appropriate data-hiding, and
> provides genericity. If he published the vptr structure, it would
> also be extensible by other libraries.

True. But I think there's a limit -- every library needs to know what could
be in the vptr structure, and you can't easily add or remove things. I
suppose some kind of type indicator could help.

But at this point, you end up with things that have a fair bit of overhead,
and most of the time when I see lists used in C, they're used directly
so they don't have to pay the overhead of function calls at all, let alone
indirection through function pointers...

> [1] And "Reasonably elegent" often means "more elegant than C++"

-s

ImpalerCore

unread,
Mar 17, 2010, 1:58:22 PM3/17/10
to

One option is to just use malloc, wait for user complaints and see
what areas in performance they are complaining about and address
them. If the interface is easy enough to use and there are enough
examples to lead them in how to use your library, there will be
interest in improving the performance issues, which can be argued and
fleshed out as a community.

I simply use malloc for my stuff since I have a very small frame of
reference (just myself) for my container code and it works for me.
I'd release it that way if I decided to jump in the pool, as I
personally would like to get a broader user experience (if anyone
would be willing to use it) to make an more informed decision between
the trade-offs of complexity and efficiency before making that kind of
choice (and hopefully you'd have a following of willing test subjects
to try out your changes in "real world" applications).

Again, you likely have a more robust background in this stuff than I.
I've never used a garbage collector in C or even C++, and haven't been
pushed to the point where efficiency was that critical to require
writing special allocators. All I've done is create a wrapper that
allows me to inject faults after specified number of malloc, calloc,
or realloc function calls to test my internal container allocation
error handling.

I don't intend this to discourage the allocator discussion at all, but
just to point out that if I'm not using the library, I have no vantage
point to make any informed suggestion. While I think that the
semantics of memory allocation is important, I just feel it's not
important to a library that no one is committed to using *yet*.

Best regards,
John D.

ImpalerCore

unread,
Mar 17, 2010, 2:24:00 PM3/17/10
to
On Mar 17, 1:47 pm, Seebs <usenet-nos...@seebs.net> wrote:

> On 2010-03-17, Andrew Poelstra <apoels...@localhost.localdomain> wrote:
>
> > You can do OO in C. I think most people don't because they have
> > it drilled into their heads that "C is not an object-oriented"
> > language. Which to be fair, it isn't, but that doesn't mean that
> > there are reasonably-elegant[1] ways to do OO.
>
> Oh, certainly.  I just don't think that it's a good enough fit to reward
> the kind of hierarchy the "container" library implies.
>
> > I think this is a nice interface, has appropriate data-hiding, and
> > provides genericity. If he published the vptr structure, it would
> > also be extensible by other libraries.
>
> True.  But I think there's a limit -- every library needs to know what could
> be in the vptr structure, and you can't easily add or remove things.  I
> suppose some kind of type indicator could help.
>
> But at this point, you end up with things that have a fair bit of overhead,
> and most of the time when I see lists used in C, they're used directly
> so they don't have to pay the overhead of function calls at all, let alone
> indirection through function pointers...

Imo, there's probably a few people willing to allow the overhead if

1. It's easy to use correctly.
2. Rolling their own version is significantly more difficult and
expensive.
3. It's free.
4. The performance overhead is not detrimental to the application.

For example, I would gladly use a correct but slowish hash-table to
build a working demo of an application just to verify the proof of
concept. At the very least, it would allow developers to prototype a
design faster and fine tune with more type-specific/efficient data
structures if need be.

Best regards,
John D.

> > [1] And "Reasonably elegent" often means "more elegant than C++"
>
> -s
> --

> Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nos...@seebs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny pictureshttp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Ian Collins

unread,
Mar 17, 2010, 2:48:40 PM3/17/10
to
On 03/18/10 05:50 AM, Seebs wrote:
> On 2010-03-17, jacob navia<ja...@spamsink.net> wrote:
>> Seebs a écrit :

>>> I honestly don't think that generalizing to "container" is going to be
>>> useful in C. In a language that doesn't have meaningful inheritance,
>>> it's very unusual for this kind of approach to get widespread adoption.
>
>> I do not know of any other attempt in C.
>
> I don't know of another generalization to container in C. I know of
> many lists and vectors and the like.
>
>> Inheritance is not necessary at all. The code works without it.
>
> But without inheritance, "container" is not a useful level of abstraction.

I don't think it's inheritance that makes "container" a useful level of
abstraction. The most important language feature for containers is
support for generics. For example, the containers part of the C++
standard library makes very little use of inheritance but relies heavily
on templates (hence the old name of standard template library).

> The thing that makes "container" useful is that it provides for commonality
> between "list" and "hash". But that's only useful when list and hash are
> the types you actually work with, but because of inheritance, you can treat
> them both as containers.

Or because of generics support.

> Without inheritance, either you have to call things "container" regardless
> of which they are, and thus have access to an API that only makes sense for
> a list when you're using a hash, and an API that only makes sense for a hash
> when you're using a list, or you lose the ability to write a function which
> just takes a "container".

Again, generics enables you to use the common subset of container
interfaces.

So the interface can be done in C, just not very cleanly.

--
Ian Collins

Ian Collins

unread,
Mar 17, 2010, 2:51:31 PM3/17/10
to
On 03/17/10 12:07 PM, jacob navia wrote:
> Data allocation strategies for containers can vary wildly, depending on
> the specific container and on the application. Environment
> considerations play also a major role: if there is enough RAM many
> things can be handled QUITE differently than when there isn't.
>
> It is impossible to find a strategy that can be always good in all
> situations, so naturally, we need an object with (roughly) 3 function
> pointers:
>
> (1) MALLOC
> (2) FREE
> (3) REALLOC
>
> This table of functions will be used by a container for
> allocating/releasing memory. It will default to the standard C
> functions, but can be changed so that a GC is used, for instance. In
> that case we would have
>
> MALLOC --> GC_malloc
> FREE --> no operation
> REALLOC --> GC_realloc.
>
> Now, should this object be a global part of the library, i.e. a single
> allocation object for the whole library, or should each container class
> (hash tables, lists, dictionaries) have one, or should each individual
> container have one?

If possible, provide both. That's the was C++ does it and it works
well. It's uncommon to provide a specific allocator to a container
instance, but when this is required, it is very useful.

--
Ian Collins

Nick Keighley

unread,
Mar 18, 2010, 4:26:26 AM3/18/10
to
On 17 Mar, 15:36, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:

> > You misunderstand. I am not trying to invent a new way of doing
> >those things. I am trying to invent a generalized standard way
> >of doing that in C. This has never been done before for C.
>
> It's been done repeatedly, except for the "standard" part.
>
> I honestly don't think that generalizing to "container" is going to be
> useful in C.  In a language that doesn't have meaningful inheritance,
> it's very unusual for this kind of approach to get widespread adoption.
> I think you'd do better to make a list library and a hash library,
> for instance.

C++ doesn't use inheritance in its container classes. Having seen
inheritance based conatiner classes I tend to think its the wrong
mechanism.

ImpalerCore

unread,
Mar 18, 2010, 10:16:09 AM3/18/10
to
On Mar 18, 4:26 am, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:

That's absolutely right imo. If you follow C++'s methodology, the
linked list, hash table, auto-resizing array have their own specific
interfaces (I don't remember seeing any public/private inheritance in
them last time I looked). I don't think that there is much that they
can commonly inherit. The best abstraction for containers is
iterators and algorithms built on using those iterators. And while it
will require calling a container specific function to get a container
specific iterator, the iterators hopefully can share the same
interface regardless of what container it was created from.

In C++, you can define a container specific iterator, but use a common
interface between those iterators.

vector::iterator --> would have to become 'struct array_iterator'
list::iterator --> would have to become 'struct list_iterator'

In C, these iterators would need to have a reference to the container
they use, and a table of function pointers to traverse the container,
access the element, and comparisons (to check whether you're at the
beginning or end of a container), maybe more. The function pointers
can share the same name so that access can be abstracted to an array
or list container.

---Random code segment---

my_list_t* list;
/* Fill up the list with stuff */

my_list_iterator_t l = my_list_iterator_create( list,
my_list_front( list ) );
or maybe
my_list_iterator_t l = list->begin();

/* list->end() is a function pointer that creates a iterator pointing
to the end of the list. */
while ( !my_list_iterator_equal( l, list->end() ) )
{
my_list_iterator_assign( l, object );
l = l->next();
}

Without operator overloading, it gets quite clunky to use iterators in
C compared to C++ containers, perhaps with a bad enough taste that
people will decide to just use C++. This is where C++ really has C
beat in the container arena imo.

At the moment I have no idea how to approach it, as it just seems too
messy to be worth the effort; plus integrating the generic part into a
list or array C interface has to come first. I believe that generic
container specific interfaces do have value in C, but I'm not
convinced about generalizing the interface to them via iterators since
I'm too spoiled from my C++ experience with them. If I saw a C
interface that made sense, sure, but I don't have one that I like.

Just some more thoughts to toss in the salad bowl.

Andrew Poelstra

unread,
Mar 18, 2010, 11:03:01 AM3/18/10
to
On 2010-03-18, ImpalerCore <jadi...@gmail.com> wrote:
>
> Without operator overloading, it gets quite clunky to use iterators in
> C compared to C++ containers, perhaps with a bad enough taste that
> people will decide to just use C++. This is where C++ really has C
> beat in the container arena imo.
>
> At the moment I have no idea how to approach it, as it just seems too
> messy to be worth the effort; plus integrating the generic part into a
> list or array C interface has to come first. I believe that generic
> container specific interfaces do have value in C, but I'm not
> convinced about generalizing the interface to them via iterators since
> I'm too spoiled from my C++ experience with them. If I saw a C
> interface that made sense, sure, but I don't have one that I like.
>
> Just some more thoughts to toss in the salad bowl.
>

I think you could use next / prev pointers as iterators. It
wouldn't be super clean, but it could certainly be consistent.

for(it = (Iter *) get_first(MyList); it; it = it->next) {
T *data = it->data;
data->foo = grommit();
data->bar = 5;
}

Actually, that looks a fair bit /cleaner/ than a lot of C++
iterator code. And now that I think about it, that cast could
probably be made unnecessary by simply having get_first
return an Iter* to begin with.

it->data would have to be a void pointer, which loses some
type safety, but such is life in C, I suppose.

jacob navia

unread,
Mar 18, 2010, 11:26:02 AM3/18/10
to
Andrew Poelstra a écrit :

> On 2010-03-18, ImpalerCore <jadi...@gmail.com> wrote:
>> Without operator overloading, it gets quite clunky to use iterators in
>> C compared to C++ containers, perhaps with a bad enough taste that
>> people will decide to just use C++. This is where C++ really has C
>> beat in the container arena imo.
>>
>> At the moment I have no idea how to approach it, as it just seems too
>> messy to be worth the effort; plus integrating the generic part into a
>> list or array C interface has to come first. I believe that generic
>> container specific interfaces do have value in C, but I'm not
>> convinced about generalizing the interface to them via iterators since
>> I'm too spoiled from my C++ experience with them. If I saw a C
>> interface that made sense, sure, but I don't have one that I like.
>>
>> Just some more thoughts to toss in the salad bowl.
>>
>
> I think you could use next / prev pointers as iterators. It
> wouldn't be super clean, but it could certainly be consistent.
>
> for(it = (Iter *) get_first(MyList); it; it = it->next) {
> T *data = it->data;
> data->foo = grommit();
> data->bar = 5;
> }

Well, that is exactly what I have in mind. The only difference is that you
iterate with a list element (in single linked list) or with a "dlist_element"
in a double linked list. A list_element struture differs from a dlist_element
only in that the second has a "previous" pointer of course.

In any case, all containers support an "Apply" method that will
iterate through all elements. You give it a function and it will call
this function for each element of the container. Obviously this is
quite heavy for simple iterations since it forces you to write a function
for the iteration.

A simpler solution is:
for (i=0; i<container->length; i++) {
void *data = container->lpVtbl->GetElement(container,i);
// work with your data here.
// If you need to update the data you do
container->lpVtbl->SetElement(container,i,data);

Andrew Poelstra

unread,
Mar 18, 2010, 11:36:42 AM3/18/10
to
On 2010-03-18, jacob navia <ja...@nospam.org> wrote:
> Andrew Poelstra a écrit :
>>
>> I think you could use next / prev pointers as iterators. It
>> wouldn't be super clean, but it could certainly be consistent.
>>
>> for(it = (Iter *) get_first(MyList); it; it = it->next) {
>> T *data = it->data;
>> data->foo = grommit();
>> data->bar = 5;
>> }
>
> Well, that is exactly what I have in mind. The only difference is that you
> iterate with a list element (in single linked list) or with a "dlist_element"
> in a double linked list. A list_element struture differs from a dlist_element
> only in that the second has a "previous" pointer of course.
>
> In any case, all containers support an "Apply" method that will
> iterate through all elements. You give it a function and it will call
> this function for each element of the container. Obviously this is
> quite heavy for simple iterations since it forces you to write a function
> for the iteration.
>
> A simpler solution is:
> for (i=0; i<container->length; i++) {
> void *data = container->lpVtbl->GetElement(container,i);
> // work with your data here.
> // If you need to update the data you do
> container->lpVtbl->SetElement(container,i,data);
> }
>

I like this, but I definitely think you should write some
macros around that lpVtbl stuff. :)

And personally, I don't think it's necessary to have separate
iterators for single/double linked lists. If there's some
extra performance cost I don't see, then fine, but if it's
just for the space savings, I think anyone who cares would
be writing their own domain-specific containers anyway.

>>
>> Actually, that looks a fair bit /cleaner/ than a lot of C++
>> iterator code. And now that I think about it, that cast could
>> probably be made unnecessary by simply having get_first
>> return an Iter* to begin with.
>>
>> it->data would have to be a void pointer, which loses some
>> type safety, but such is life in C, I suppose.
>>

Seebs

unread,
Mar 18, 2010, 11:56:09 AM3/18/10
to
On 2010-03-18, Andrew Poelstra <apoe...@localhost.localdomain> wrote:
> On 2010-03-18, jacob navia <ja...@nospam.org> wrote:
>> A simpler solution is:
>> for (i=0; i<container->length; i++) {
>> void *data = container->lpVtbl->GetElement(container,i);

> I like this, but I definitely think you should write some


> macros around that lpVtbl stuff. :)

And if you want it accepted as a standard, pick names consistent with
the C standard nomenclature -- no capital letters.

I still can't figure out what "lpVtbl" is. I mean, "vtable", sure, but
what's the "lp"? Why is the V capitalized?

I'd probably do:
#define get_element(x, y) ((container *) x)->funcs->getele(x, y)

or something comparable. In particular, if "container" has to be there
twice, that should be hidden.

jacob navia

unread,
Mar 18, 2010, 12:04:25 PM3/18/10
to
Seebs a écrit :

> On 2010-03-18, Andrew Poelstra <apoe...@localhost.localdomain> wrote:
>> On 2010-03-18, jacob navia <ja...@nospam.org> wrote:
>>> A simpler solution is:
>>> for (i=0; i<container->length; i++) {
>>> void *data = container->lpVtbl->GetElement(container,i);
>
>> I like this, but I definitely think you should write some
>> macros around that lpVtbl stuff. :)
>
> And if you want it accepted as a standard, pick names consistent with
> the C standard nomenclature -- no capital letters.
>
Well, maybe, _Bool is standard C now

> I still can't figure out what "lpVtbl" is. I mean, "vtable", sure, but
> what's the "lp"? Why is the V capitalized?
>

This is a COM usage. COM used that name and I got used to it.
Vtbl means virtual table, lp means "long pointer", and that comes from
windows 16 bit days where you had long pointers (beyond 64 K) and
short pointers (16 bit pointers). Obviously I need to change that name
before publication. Sorry for this.


> I'd probably do:
> #define get_element(x, y) ((container *) x)->funcs->getele(x, y)
>
> or something comparable. In particular, if "container" has to be there
> twice, that should be hidden.
>

PROBLEM:

This library doesn't use very much the user's name space since all
names are within the container structure. If we do that macro (what is
OK) it can only be optional because name clashes are bound to happen.

Seebs

unread,
Mar 18, 2010, 12:33:32 PM3/18/10
to
On 2010-03-18, jacob navia <ja...@nospam.org> wrote:
> Seebs a écrit :

>>> I like this, but I definitely think you should write some
>>> macros around that lpVtbl stuff. :)

>> And if you want it accepted as a standard, pick names consistent with
>> the C standard nomenclature -- no capital letters.

> Well, maybe, _Bool is standard C now

_Bool exists for a very specific reason, and is hidden from the user.

>> I still can't figure out what "lpVtbl" is. I mean, "vtable", sure, but
>> what's the "lp"? Why is the V capitalized?

> This is a COM usage.

Ahh.

> COM used that name and I got used to it.
> Vtbl means virtual table, lp means "long pointer", and that comes from
> windows 16 bit days where you had long pointers (beyond 64 K) and
> short pointers (16 bit pointers). Obviously I need to change that name
> before publication. Sorry for this.

Ahh, yes.

Definitely do NOT do systems-hungarian names in anything you want other
people to use. In fact, you shouldn't do them in ANYTHING. EVER.
UNDER ANY CIRCUMSTANCES. That usage is 100% guaranteed to screw you up
without ever helping you.

> This library doesn't use very much the user's name space since all
> names are within the container structure. If we do that macro (what is
> OK) it can only be optional because name clashes are bound to happen.

It might make more sense to do it as an inline function, thinking about
it more.

But!

That's okay. Because it'll only exist *if the user includes the header*.
So that's fine, same as it's okay for "bool" to be defined if you include
<stdbool.h>.

The container library doesn't need to be part of the fundamental type
system, so it doesn't need its types to be in scope unconditionally, so
it doesn't need to do something crazy like the _Bool trick.

But thinking about it more... Hmm. The problem is really the lack of
a good unambiguous shorthand for "container". Let's imagine that it's
"cont" for now.

static inline cont_ele *
cont_next(void *c, int i) {
return ((container *)c->funcs->cont_next(c, i));
}

Something like that, even though it doesn't look that much
different, will be a lot easier to sell people on. If I see "lp"
prefixes, my first assumption is that it's more godawful Windows
shit based on a 640k barrier, and I lose interest rapidly. :)

Ben Bacarisse

unread,
Mar 18, 2010, 1:02:51 PM3/18/10
to
jacob navia <ja...@nospam.org> writes:

It's possible you've missed Andrew's point. I think he is suggesting
that you start to get some payoff if you can iterate any container
with the same code. I.e. that Mylist could be changed to be a tree and
the code would still work.

If that is not the point he was making, I'll make it! I doubt it can
be done with plain pointers, but I would want to be able to iterate
over any container so that I could write generic algorithms. This
would be the kind of benefit that might make a relatively heavyweight
framework like yours pay off.

> In any case, all containers support an "Apply" method that will
> iterate through all elements. You give it a function and it will call
> this function for each element of the container. Obviously this is
> quite heavy for simple iterations since it forces you to write a function
> for the iteration.
>
> A simpler solution is:
> for (i=0; i<container->length; i++) {
> void *data = container->lpVtbl->GetElement(container,i);

BCPL had/has a syntax for this:

GetElement#(container, i);

The # caused an indirect call to be made through a vector of function
pointers associated with 'container'.

> // work with your data here.
> // If you need to update the data you do
> container->lpVtbl->SetElement(container,i,data);
> }

That's universal but likely to impractical for contains that don't
have random access.

<snip>
--
Ben.

Ben Bacarisse

unread,
Mar 18, 2010, 1:36:35 PM3/18/10
to
Seebs <usenet...@seebs.net> writes:

> On 2010-03-18, Andrew Poelstra <apoe...@localhost.localdomain> wrote:
>> On 2010-03-18, jacob navia <ja...@nospam.org> wrote:
>>> A simpler solution is:
>>> for (i=0; i<container->length; i++) {
>>> void *data = container->lpVtbl->GetElement(container,i);
>
>> I like this, but I definitely think you should write some
>> macros around that lpVtbl stuff. :)
>
> And if you want it accepted as a standard, pick names consistent with
> the C standard nomenclature -- no capital letters.
>
> I still can't figure out what "lpVtbl" is. I mean, "vtable", sure, but
> what's the "lp"? Why is the V capitalized?
>
> I'd probably do:
> #define get_element(x, y) ((container *) x)->funcs->getele(x, y)

What's the thinking behind the cast? It looks like it would just hide
errors from me.

> or something comparable. In particular, if "container" has to be there
> twice, that should be hidden.

Using gcc I'd use:

#define MCALL(f, obj, ...) ((obj)->funcs->f((obj), ##__VA_ARGS__))

If needed, I'd then define get_element in terms of MCALL.

This macro uses gcc's special meaning of the ## token to remove the
comma that would otherwise be there in a call like:

MCALL(GetSize, tree);

Without it, you'd need MCALL and MCALL0:

#define MCALL0(f, obj) ((obj)->funcs->f((obj)))
#define MCALL(f, obj, ...) ((obj)->funcs->f((obj), __VA_ARGS__))

I don't think there is any way to avoid needing two macros in the
situation in standard C, but this is one case where I /want/ to be
wrong. I wonder if there are any plans to provide a standard
solution.

--
Ben.

ImpalerCore

unread,
Mar 18, 2010, 1:38:53 PM3/18/10
to
On Mar 18, 11:03 am, Andrew Poelstra <apoels...@localhost.localdomain>
wrote:

> On 2010-03-18, ImpalerCore <jadil...@gmail.com> wrote:
>
>
>
>
>
> > Without operator overloading, it gets quite clunky to use iterators in
> > C compared to C++ containers, perhaps with a bad enough taste that
> > people will decide to just use C++.  This is where C++ really has C
> > beat in the container arena imo.
>
> > At the moment I have no idea how to approach it, as it just seems too
> > messy to be worth the effort; plus integrating the generic part into a
> > list or array C interface has to come first.  I believe that generic
> > container specific interfaces do have value in C, but I'm not
> > convinced about generalizing the interface to them via iterators since
> > I'm too spoiled from my C++ experience with them.  If I saw a C
> > interface that made sense, sure, but I don't have one that I like.
>
> > Just some more thoughts to toss in the salad bowl.
>
> I think you could use next / prev pointers as iterators. It
> wouldn't be super clean, but it could certainly be consistent.
>
> for(it = (Iter *) get_first(MyList); it; it = it->next) {
>   T *data = it->data;
>   data->foo = grommit();
>   data->bar = 5;
>
> }
>
> Actually, that looks a fair bit /cleaner/ than a lot of C++
> iterator code. And now that I think about it, that cast could
> probably be made unnecessary by simply having get_first
> return an Iter* to begin with.

That just looks like the regular iterative method to access a linked
list data structure. Let's throw in MyArray instead and keep the same
nomenclature. Do you expect this to work?

for(it = (Iter *) get_first(MyArray); it; it = it->next) {


T *data = it->data;
data->foo = grommit();
data->bar = 5;
}

A list iterator would have to keep track of the head of the list and
its current list node pointer. An array iterator would need to keep
track of the array buffer and the current index. Moving to the next
position are different operations. In the list, you follow the next
pointer, for arrays, you increment the index by 1. This currently
requires me to use two different loops styles to iterate through
either a list or an array, rather than one loop that uses iterators
that will work independently whether a list or an array is the data
structure.

It may be possible to create an infrastructure to abstract iteration
of a container, but it only provides a tangible benefit when you have
an algorithms library on top of it. C++ iterators have several things
going for it. Operator overloading to sweeten the syntax, and member
functions so that you can avoid having to pass the iterator back to
its own function pointers, which imo is very annoying and doesn't make
the syntax to accessing a container via a generic iterator look easy
to do in C, at least not the ways I've explored trying to implement
it.

Or maybe I'm missing your point.

> it->data would have to be a void pointer, which loses some
> type safety, but such is life in C, I suppose.

I don't see a way around keeping the data as a void*. If you're
willing to ignore the problem of generic iterators, you can use macros
to wrap the type into the interface, i.e.

int n = 42;
my_array_t* array = my_array_new( 100, int );
my_array_push_back( array, &n, int );
int* p = my_array_front( array, int );
if ( p && *p == 42 ) {
printf( "Yay\n" );
}

This kind of array can work as long as the size of the type is fixed.
All that needs to be done is to translate the type 'int' into the
amount of memory via sizeof and use that to access and change values
of that type. It does require passing the type around to the
interface though, which is clunky, but not terribly clunky imo.

Best regards,
John D.

> --
> Andrew Poelstrahttp://www.wpsoftware.net/andrew

Andrew Poelstra

unread,
Mar 18, 2010, 1:52:24 PM3/18/10
to
On 2010-03-18, ImpalerCore <jadi...@gmail.com> wrote:
>
> A list iterator would have to keep track of the head of the list and
> its current list node pointer. An array iterator would need to keep
> track of the array buffer and the current index. Moving to the next
> position are different operations. In the list, you follow the next
> pointer, for arrays, you increment the index by 1. This currently
> requires me to use two different loops styles to iterate through
> either a list or an array, rather than one loop that uses iterators
> that will work independently whether a list or an array is the data
> structure.
>

You're right. Using next pointers the way I described is not
as generic as I thought it could be. But still there is hope:

Iter *it;
for(it = get_first(MyArray); it->valid; iter_next(it)) {


T *data = it->data;
data->foo = grommit();
}

This is essentially how C++ does it, without the operator
overloading syntax. iter_next() would be a macro that added
a cast to a generic iterator and called the "real" next
function, which would go through its vtable and interate
itself properly.

OR, you could use a single iterator type with a type field
and associated container, and put all the logic right into
iter_next(). It would be a little faster, probably, but
would restrict extensibility.

Andrew Poelstra

unread,
Mar 18, 2010, 1:54:57 PM3/18/10
to
On 2010-03-18, Andrew Poelstra <apoe...@localhost.localdomain> wrote:
> On 2010-03-18, ImpalerCore <jadi...@gmail.com> wrote:
>>
>> A list iterator would have to keep track of the head of the list and
>> its current list node pointer. An array iterator would need to keep
>> track of the array buffer and the current index. Moving to the next
>> position are different operations. In the list, you follow the next
>> pointer, for arrays, you increment the index by 1. This currently
>> requires me to use two different loops styles to iterate through
>> either a list or an array, rather than one loop that uses iterators
>> that will work independently whether a list or an array is the data
>> structure.
>>
>
> You're right. Using next pointers the way I described is not
> as generic as I thought it could be. But still there is hope:
>
> Iter *it;
> for(it = get_first(MyArray); it->valid; iter_next(it)) {
> T *data = it->data;
> data->foo = grommit();
> }
>
> This is essentially how C++ does it, without the operator
> overloading syntax. iter_next() would be a macro that added
> a cast to a generic iterator and called the "real" next
> function, which would go through its vtable and interate
> itself properly.
>

Silly me, there's no need for the cast. get_first() would
setup the vtable properly and a single Iter type could be
used.

> OR, you could use a single iterator type with a type field
> and associated container, and put all the logic right into
> iter_next(). It would be a little faster, probably, but
> would restrict extensibility.
>

This is also silly, as per above.

Seebs

unread,
Mar 18, 2010, 2:24:38 PM3/18/10
to
On 2010-03-18, Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
> What's the thinking behind the cast? It looks like it would just hide
> errors from me.

The objects passed in would not be "container *", they'd be something
which...

Ohhh. Wait. Nevermind, I'm just being dumb. Even if x may not be
a container...

x->container is always a container.

So x->container->funcs.

> Without it, you'd need MCALL and MCALL0:

> #define MCALL0(f, obj) ((obj)->funcs->f((obj)))
> #define MCALL(f, obj, ...) ((obj)->funcs->f((obj), __VA_ARGS__))

> I don't think there is any way to avoid needing two macros in the
> situation in standard C, but this is one case where I /want/ to be
> wrong. I wonder if there are any plans to provide a standard
> solution.

Hmm. I don't know of one. I vaguely recall the question being discussed,
and some conclusion being reached that it was viable to ignore that case.
In this case, though, it doesn't seem to be. On the other hand... I
don't know that we ever need to have one that doesn't take at least one
argument. Because we pretty much always want an aux() type thing.

Nick

unread,
Mar 18, 2010, 3:57:38 PM3/18/10
to
Seebs <usenet...@seebs.net> writes:

> But thinking about it more... Hmm. The problem is really the lack of
> a good unambiguous shorthand for "container".

Invent a new technical term - like "box" or "sack". Why ever not?
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk

Ben Bacarisse

unread,
Mar 18, 2010, 5:51:52 PM3/18/10
to
Seebs <usenet...@seebs.net> writes:

> On 2010-03-18, Ben Bacarisse <ben.u...@bsb.me.uk> wrote:

<snip>


>> Without it, you'd need MCALL and MCALL0:

The "it" is gcc's use of ## to suppress a preceding , before __VA_ARGS__

>> #define MCALL0(f, obj) ((obj)->funcs->f((obj)))
>> #define MCALL(f, obj, ...) ((obj)->funcs->f((obj), __VA_ARGS__))
>
>> I don't think there is any way to avoid needing two macros in the
>> situation in standard C, but this is one case where I /want/ to be
>> wrong. I wonder if there are any plans to provide a standard
>> solution.
>
> Hmm. I don't know of one. I vaguely recall the question being discussed,
> and some conclusion being reached that it was viable to ignore that
> case.

Seems a shame to me. I did find this:

http://www.open-std.org/Jtc1/sc22/wg14/www/docs/n976.htm

which discusses the issue. I talks about "this DR" but I could not
find an actual Defect Report so I don't think it ever became formal.

> In this case, though, it doesn't seem to be. On the other hand... I
> don't know that we ever need to have one that doesn't take at least one
> argument. Because we pretty much always want an aux() type thing.

I don't follow. Can you say a bit more...

--
Ben.

Seebs

unread,
Mar 18, 2010, 10:03:07 PM3/18/10
to

Basically, any API like this for callbacks should almost always have
an extra parameter to every function, even functions which "take no
arguments", for passing sideband/auxiliary data.

So instead of
list_count(container);
it should be
list_count(container, aux);
where "aux" is a void * interpreted however a given kind of container
wants to interpret it.

Ben Bacarisse

unread,
Mar 18, 2010, 10:23:05 PM3/18/10
to
Seebs <usenet...@seebs.net> writes:

> On 2010-03-18, Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
>>> In this case, though, it doesn't seem to be. On the other hand... I
>>> don't know that we ever need to have one that doesn't take at least one
>>> argument. Because we pretty much always want an aux() type thing.
>
>> I don't follow. Can you say a bit more...
>
> Basically, any API like this for callbacks should almost always have
> an extra parameter to every function, even functions which "take no
> arguments", for passing sideband/auxiliary data.
>
> So instead of
> list_count(container);
> it should be
> list_count(container, aux);
> where "aux" is a void * interpreted however a given kind of container
> wants to interpret it.

Sure. I think that is widely know. I had no idea you were talking
about callbacks. I thought you were talking about there being no need
for a fix for the __VA_ARGS__ problem in the macro I proposed. At
least I though you comment had something to do with the macro.

You can't be talking about the container operations themselves (which are
what my suggested macro calls) -- your example call has no auxiliary
data argument (quote correctly so in my opinion since it does not need
one).

[Can I suggest you to keep a little more context when you reply? No
one reading your reply could know what was being discussed when you
claimed that "we pretty much always want an aux() type thing".]

--
Ben.

Seebs

unread,
Mar 18, 2010, 11:05:39 PM3/18/10
to
On 2010-03-19, Ben Bacarisse <ben.u...@bsb.me.uk> wrote:

> Seebs <usenet...@seebs.net> writes:
>> Basically, any API like this for callbacks should almost always have
>> an extra parameter to every function, even functions which "take no
>> arguments", for passing sideband/auxiliary data.
>>
>> So instead of
>> list_count(container);
>> it should be
>> list_count(container, aux);
>> where "aux" is a void * interpreted however a given kind of container
>> wants to interpret it.

> Sure. I think that is widely know. I had no idea you were talking
> about callbacks. I thought you were talking about there being no need
> for a fix for the __VA_ARGS__ problem in the macro I proposed. At
> least I though you comment had something to do with the macro.

I think it does. The fact that there must always be at least one more
argument means that we can use the , __VA_ARGS__ thing and expect it to
work, because there will always be at least one argument.

> You can't be talking about the container operations themselves (which are
> what my suggested macro calls) -- your example call has no auxiliary
> data argument (quote correctly so in my opinion since it does not need
> one).

Sure it does. (container, aux).

> [Can I suggest you to keep a little more context when you reply? No
> one reading your reply could know what was being discussed when you
> claimed that "we pretty much always want an aux() type thing".]

Not a bad idea. :)

Ben Bacarisse

unread,
Mar 19, 2010, 7:08:21 AM3/19/10
to
Seebs <usenet...@seebs.net> writes:

> On 2010-03-19, Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
>> Seebs <usenet...@seebs.net> writes:
>>> Basically, any API like this for callbacks should almost always have
>>> an extra parameter to every function, even functions which "take no
>>> arguments", for passing sideband/auxiliary data.
>>>
>>> So instead of
>>> list_count(container);
>>> it should be
>>> list_count(container, aux);
>>> where "aux" is a void * interpreted however a given kind of container
>>> wants to interpret it.
>
>> Sure. I think that is widely know. I had no idea you were talking
>> about callbacks. I thought you were talking about there being no need
>> for a fix for the __VA_ARGS__ problem in the macro I proposed. At
>> least I though you comment had something to do with the macro.
>
> I think it does. The fact that there must always be at least one more
> argument means that we can use the , __VA_ARGS__ thing and expect it to
> work, because there will always be at least one argument.

But the macro was not for a callback. Zero "extra" arguments are
perfectly normal in the context it would be used.

>> You can't be talking about the container operations themselves (which are
>> what my suggested macro calls) -- your example call has no auxiliary
>> data argument (quote correctly so in my opinion since it does not need
>> one).
>
> Sure it does. (container, aux).

Not this example, the one you originally gave that I proposed with the
macro in question. There's been too much snippage. Lets put some
contact back:

[you:]


| I'd probably do:
| #define get_element(x, y) ((container *) x)->funcs->getele(x, y)

I suggested replacing this with MCALL and described the problem when
there are no __VA_ARGS__:

[me:]


| Using gcc I'd use:

| #define MCALL(f, obj, ...) ((obj)->funcs->f((obj), ##__VA_ARGS__))

Your original example does not have (and does not need in my
opinion) auxiliary data. x is the container and y is the item
(index?) to 'get'.

In this context you suggested that the problem of empty __VAR_ARGS__
is not serious because of the need for auxiliary data. So I looked
back to your example (already snipped by this time) and saw none.

The need for auxiliary data /in callbacks/ hardly matters for the
MCALL macro because any 'apply callback' type operation already needs
a function to apply, and MCALL will work as well with one extra
argument as it will with two:

MCALL(apply_function, list, my_function);

works as well as

MCALL(apply_function, list, my_function, &my_data);

If, on the other hand, you are saying that /all/ operations on /all/
containers should have an auxiliary data argument then (a) I disagree
(but won't argue the point) and (b) I would have preferred to see it
in your example

#define get_element(x, y, aux) ((container *)x)->funcs->getele(x, y, aux)

so that this whole sub thread could have been avoided!

If that was not what you were saying, I still can't see the connection
to the __VA_ARG__ problem.

<snip>
--
Ben.

Seebs

unread,
Mar 19, 2010, 1:13:49 PM3/19/10
to
On 2010-03-19, Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
> But the macro was not for a callback. Zero "extra" arguments are
> perfectly normal in the context it would be used.

Hmm. Could be.

> Not this example, the one you originally gave that I proposed with the
> macro in question. There's been too much snippage. Lets put some
> contact back:

> [you:]
>| I'd probably do:
>| #define get_element(x, y) ((container *) x)->funcs->getele(x, y)

> I suggested replacing this with MCALL and described the problem when
> there are no __VA_ARGS__:

> [me:]
>| Using gcc I'd use:
>| #define MCALL(f, obj, ...) ((obj)->funcs->f((obj), ##__VA_ARGS__))

> Your original example does not have (and does not need in my
> opinion) auxiliary data. x is the container and y is the item
> (index?) to 'get'.

Sure, but you could indeed invoke it with the MCALL macro, because it
has at least one additional argument. Furthermore, I'm not sure it
wouldn't sometimes be useful to have an aux data element for that.

> In this context you suggested that the problem of empty __VAR_ARGS__
> is not serious because of the need for auxiliary data. So I looked
> back to your example (already snipped by this time) and saw none.

Well, arguably, "y" is. Even if we didn't have an "aux" argument,
we'd be doing MCALL(getele, x, y) -- so __VA_ARGS__ would have at
least one member.

> If, on the other hand, you are saying that /all/ operations on /all/
> containers should have an auxiliary data argument then (a) I disagree
> (but won't argue the point) and (b) I would have preferred to see it
> in your example

> #define get_element(x, y, aux) ((container *)x)->funcs->getele(x, y, aux)

> so that this whole sub thread could have been avoided!

I hadn't remembered it by then. I nearly always forget that there's
a recurring theme of discovering, after building an interface, that you
need a way to pass additional data or context in.

ng2010

unread,
Mar 19, 2010, 10:44:39 PM3/19/10
to

"jacob navia" <ja...@spamsink.net> wrote in message
news:hnr08l$1ev$1...@speranza.aioe.org...
> Seebs a écrit :

>> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:
>>> You misunderstand. I am not trying to invent a new way of doing
>>> those things. I am trying to invent a generalized standard way
>>> of doing that in C. This has never been done before for C.
>>
>> It's been done repeatedly, except for the "standard" part.
>>
>> I honestly don't think that generalizing to "container" is going to be
>> useful in C. In a language that doesn't have meaningful inheritance,
>> it's very unusual for this kind of approach to get widespread
>> adoption.
>
>
> I do not know of any other attempt in C.
>
> Inheritance is not necessary at all. The code works without it.

Jacob: Do you even know C++? Because it sounds like you are burying your
head in the sand and doing wishful thinking and hoping that others would
believe and follow you, but the fact of the matter is that you are the
only one who wants to put lipstick on a pig! Eventually, all the old iron
of detroit will be gone, rusted away. So will C rust away. "A few" still
drive around the old cars, but they are still deathtraps and old,
obsolete technology. Restoring them with new underpinnings like
independent suspensions, doesn't change them much (still deathtraps).
With all your zeal, you should study C++ (if you haven't) and maybe a few
or all other languages and then embark on creating a new language (though
I can generalize and say that those who are good at building compilers
make for crappy language designers, but you know what they say about
generalizations). But you aren't a compiler builder, now are you. You
sound like a young man so I wonder what the fork you are doing with C
other than as a potential intermediate representation. You have time. Use
it wisely.


ng2010

unread,
Mar 19, 2010, 10:48:07 PM3/19/10
to

"Seebs" <usenet...@seebs.net> wrote in message
news:slrnhq223i.oe0...@guild.seebs.net...
>
> I have often used list libraries. I'd use hash libraries if I needed a
> hash.
> In neither case would I use a "container" library in C -- it's the
> wrong
> level of abstraction for C, so far as I can tell. I've never in any
> language
> wanted "a container". In OO languages, it's useful that the specific
> things
> I request are also generically "containers". In C, it's not useful,
> because
> I can't do anything with it.
>

This sounds sooo much like thrashing on whether a "Line" should draw
itself or should be drawn by a "Canvas" or other abstraction. Don't walk,
run to the next level: jettison old paradigms.


ng2010

unread,
Mar 19, 2010, 10:56:54 PM3/19/10
to

"Andrew Poelstra" <apoe...@localhost.localdomain> wrote in message
news:slrnhq24u8.l...@localhost.localdomain...

> You can do OO in C. I think most people don't because they have
> it drilled into their heads that "C is not an object-oriented"
> language. Which to be fair, it isn't, but that doesn't mean that
> there are reasonably-elegant[1] ways to do OO.

Your opinion of "reasonably elegant" is just that: an opinion. Apparently
Navia is willing to make the concessions necessary also. It is simply not
necessary to keep hitting one's self in the head with a hammer. OO and C
can never be "elegant". I think maybe Navia's problem is (as is my own)
that the compiler black box is just that: a black box! If you start with
a C compiler, then you end up trying to escape C by extending it and the
complex compiler you started with. It is an error of entry. The way to go
is to start with a clean slate. No baggage, no pain (from that hammer
hitting you on the head). It's sad to see him spinning his wheels and not
getting anywhere because he is stuck in the mud of C.


Seebs

unread,
Mar 19, 2010, 11:04:24 PM3/19/10
to
On 2010-03-20, ng2010 <ng2...@att.invalid> wrote:
> This sounds sooo much like thrashing on whether a "Line" should draw
> itself or should be drawn by a "Canvas" or other abstraction. Don't walk,
> run to the next level: jettison old paradigms.

This is pretty useless advice.

Understanding what makes a design work is important regardless of language.

ng2010

unread,
Mar 19, 2010, 11:12:48 PM3/19/10
to
Nick Keighley wrote:
> On 17 Mar, 04:22, "ng2010" <ng2...@att.invalid> wrote:
>> So sad to be dying and seeing youth tackling problems already solved
>> in my own youth.
>
> and the solution was? I'm not convinced there *is* a single right
> answer for all situations.

The solution to what? I know the answer to your second question and I
could tell ya, but then I'd have to kill ya. Ya know?


ng2010

unread,
Mar 19, 2010, 11:06:54 PM3/19/10
to
Nick Keighley wrote:
> On 17 Mar, 15:36, Seebs <usenet-nos...@seebs.net> wrote:
>> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:
>
>>> You misunderstand. I am not trying to invent a new way of doing
>>> those things. I am trying to invent a generalized standard way
>>> of doing that in C. This has never been done before for C.
>>
>> It's been done repeatedly, except for the "standard" part.
>>
>> I honestly don't think that generalizing to "container" is going to
>> be useful in C. In a language that doesn't have meaningful
>> inheritance, it's very unusual for this kind of approach to get
>> widespread adoption. I think you'd do better to make a list library

>> and a hash library,
>> for instance.
>
> C++ doesn't use inheritance in its container classes. Having seen
> inheritance based conatiner classes I tend to think its the wrong
> mechanism.

Having implemented container libraries, I think that is where the layman
starts out. While I never had something like all containers derived from
a Container class, surely I did think about it (over a decade ago!). I do
think I have the "correct" architecture now (at least it is mature and
not kids stuff like Navia seems to be spouting!). Of course you'd have to
use "my" language (not yet available) to enjoy it. Stay tuned.


ng2010

unread,
Mar 19, 2010, 11:15:21 PM3/19/10
to
Seebs wrote:
> On 2010-03-20, ng2010 <ng2...@att.invalid> wrote:
>> This sounds sooo much like thrashing on whether a "Line" should draw
>> itself or should be drawn by a "Canvas" or other abstraction. Don't
>> walk, run to the next level: jettison old paradigms.
>
> This is pretty useless advice.

It wasn't advice. It was assessment of the situation of the current
dialog. aka, "been there, done that".

Seebs

unread,
Mar 19, 2010, 11:52:09 PM3/19/10
to

"Don't walk, run..." is an imperative. Unless you're the emperor,
your imperatives are "advice".

The point is, it's not useful -- people need to think about these things
to develop a good map of the problem space. There's good reasons for some
things to be done in C, and thinking about how to do them well in C is
useful.

jacob navia

unread,
Mar 20, 2010, 3:37:59 AM3/20/10
to
ng2010 a écrit :
> "jacob navia" <ja...@spamsink.net> wrote in message
> news:hnr08l$1ev$1...@speranza.aioe.org...
>> Seebs a écrit :
>>> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:
>>>> You misunderstand. I am not trying to invent a new way of doing
>>>> those things. I am trying to invent a generalized standard way
>>>> of doing that in C. This has never been done before for C.
>>> It's been done repeatedly, except for the "standard" part.
>>>
>>> I honestly don't think that generalizing to "container" is going to be
>>> useful in C. In a language that doesn't have meaningful inheritance,
>>> it's very unusual for this kind of approach to get widespread
>>> adoption.
>>
>> I do not know of any other attempt in C.
>>
>> Inheritance is not necessary at all. The code works without it.
>
> Jacob: Do you even know C++? Because it sounds like you are burying your
> head in the sand and doing wishful thinking and hoping that others would
> believe and follow you, but the fact of the matter is that you are the
> only one who wants to put lipstick on a pig!

Why?

You are misunderstanding me. I do not want to use C++!

> Eventually, all the old iron
> of detroit will be gone, rusted away. So will C rust away.

The usage of C is not decreasing but increasing. Big and important
projects like the linux kernel, Apache, and many others are written
in C. The folks in C++ have been yelling this for ages now and
the usage of C doesn't disminish at all.

They believe that throwing ad hoc complexity at problems is the solution
to everything. No, it is not. C++ has become such a monster of
complexity that not even the creator of the language is able to add
a new feature, after years of trying. ("concepts" anyone?)

> "A few" still
> drive around the old cars, but they are still deathtraps and old,
> obsolete technology.

Because you believe that more complexity is better. Go on. I believe that
the future belongs to SIMPLER languages.

What I want to do is participate to the evolution of C. This group is about
that. Note that you have comp.lang.c++ to discuss your stuff. Coming here
trolling about how C is a piece of crap is simply acknowledging that it
scares you if C would continue its own development. You, and all those
C++ zealots try to destroy C because deep in their minds they are afraid
that people realize that what is important in a language is simplicity
and power, not complexity.

Lorenzo Villari

unread,
Mar 20, 2010, 6:44:51 AM3/20/10
to
On Fri, 19 Mar 2010 21:56:54 -0500
"ng2010" <ng2...@att.invalid> wrote:

Redefine the term "elegant" and maybe, we could agree. Different people
have different meanings for that I think. I believe some, not so
horrible, OO in C could be done...

Richard Bos

unread,
Mar 21, 2010, 11:53:59 AM3/21/10
to
Nick Keighley <nick_keigh...@hotmail.com> wrote:

> On 17 Mar, 04:22, "ng2010" <ng2...@att.invalid> wrote:
> > So sad to be dying and seeing youth tackling problems already solved in
> > my own youth.
>
> and the solution was? I'm not convinced there *is* a single right
> answer for all situations.

...is the correct answer.

Richard

ng2010

unread,
Mar 24, 2010, 12:13:10 AM3/24/10
to

"Lorenzo Villari" <vll...@tiscali.it> wrote in message
news:20100320114451.047d1d82@kubuntu...

I don't even want to waste my time discussing it (OO in C). This isn't
the 1980's. (That said, a C-LIKE language who's purpose was to be an
enabler, for modern languages that are elegant, by being JUST an
intermediate language may have some merit, the point being to enable
language designers and them being able to avoid writing compiler
backends).


ng2010

unread,
Mar 24, 2010, 12:57:30 AM3/24/10
to

"jacob navia" <ja...@nospam.org> wrote in message
news:ho1u16$cl5$1...@speranza.aioe.org...
> ng2010 a �crit :

>> "jacob navia" <ja...@spamsink.net> wrote in message
>> news:hnr08l$1ev$1...@speranza.aioe.org...
>>> Seebs a �crit :

>>>> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:
>>>>> You misunderstand. I am not trying to invent a new way of doing
>>>>> those things. I am trying to invent a generalized standard way
>>>>> of doing that in C. This has never been done before for C.
>>>> It's been done repeatedly, except for the "standard" part.
>>>>
>>>> I honestly don't think that generalizing to "container" is going to
>>>> be
>>>> useful in C. In a language that doesn't have meaningful
>>>> inheritance,
>>>> it's very unusual for this kind of approach to get widespread
>>>> adoption.
>>>
>>> I do not know of any other attempt in C.
>>>
>>> Inheritance is not necessary at all. The code works without it.
>>
>> Jacob: Do you even know C++? Because it sounds like you are burying
>> your head in the sand and doing wishful thinking and hoping that
>> others would believe and follow you, but the fact of the matter is
>> that you are the only one who wants to put lipstick on a pig!
>
> Why?

Maybe if you'd study C++ that would be apparent?

>
> You are misunderstanding me. I do not want to use C++!

If you design just libraries, OK, then you fit in the category of "user"
(of the language). When you go and extend the language, you move or are
moving into language designer territory. It doesn't matter that something
is "valid C", once you start creating macros and keywords and
underpinnings that the language is not designed to support, then you are
outside of the realm of "user". You could build a house today with only
the tools that were available 100 years ago, but why? Programming
languages are nothing to be romantic about.

>
>> Eventually, all the old iron of detroit will be gone, rusted away. So
>> will C rust away.
>
> The usage of C is not decreasing but increasing. Big and important
> projects like the linux kernel, Apache, and many others are written
> in C.

Don't yell/advertise that too loudly, because that will increasingly
become a negative trait and a characteristic of obsolescence. All you did
was state large and incomprehensible codebases and poorly designed
software. (The Apache folks have some useful libraries that would be
better if not for the limitations of the language they are written in).

(Aside: Go Apache! Linux go suck a rock. GPL sucks!)

> The folks in C++ have been yelling this for ages now and
> the usage of C doesn't disminish at all.

C++ owes much of it's non-lucrativity to C. (Maybe ALL of it).

>
> They believe that throwing ad hoc complexity at problems is the
> solution
> to everything. No, it is not. C++ has become such a monster of
> complexity that not even the creator of the language is able to add
> a new feature, after years of trying. ("concepts" anyone?)

I'm not going to be sucked into flame wars with you. C++'s major weakness
is it's ancestry: C. That's why I said STUDY it rather than saying USE
it.

>
>> "A few" still drive around the old cars, but they are still deathtraps
>> and old, obsolete technology.
>
> Because you believe that more complexity is better. Go on. I believe
> that
> the future belongs to SIMPLER languages.

You're not listening. (Did I mention something about "burying your head
in the sand"?). I don't know you, so I don't know your ability to
comprehend, learn and think. But you dialog in this thread so far to me
seems to be very self-centered at worst, or childish at best.

>
> What I want to do is participate to the evolution of C.

Go for it. I think that concept is oxymoronish. Reif with romanticism
misplaced, surely. But I can address, either my misunderstanding or
yours: Where do you C as being relevant? What domains? What application
programs? Who is the target user? If you say everything from desktop GUI
programs to space shuttle life support systems, well I'll probably bozo
bin you.

> This group is about
> that.

I thought there was a ISO standard group to talk about "evolution" (I
don't think that group is interested in doing that). And if this group is
then for USERS and USAGE of C, then I think your ideas are outside of the
language's charter. I recognize you were hoping for my quick dismissal. I
just lurk in here usually. I'm not here to try to convince anyone to use
C, extend it, or use any other language. You, OTOH, DO have agenda that I
have noted that I think is outside of the realm of C. (I called you an
aspiring language-designer/evolver or something, and if you are young
still, I would hope that you wouldn't waste your time with "legacy"
code/languages).

> Note that you have comp.lang.c++ to discuss your stuff.

When you make assertions like that without knowing, I immediately
categorize you as "youngster" (no offense meant). Surely after this
response to you, you will see clearly where I was coming from and that it
was not obfuscated at all and that the "burying your head in the sand"
comment is true to your life: you are blinded by what you THINK you know.

> Coming here
> trolling about how C is a piece of crap is simply acknowledging that it
> scares you if C would continue its own development.

You can go live in the haunted house in the remote location if you want
to. I don't find it habitable, nor do I find it rebuildable/rennovatible:
it's just not worth it. It's easier to start from scratch or buy
something shiney and new. The latter will trump the capabilities of the
former in every category (except maybe historical romanticism).

> You, and all those
> C++ zealots try to destroy C because deep in their minds they are
> afraid
> that people realize that what is important in a language is simplicity
> and power, not complexity.

As if you knew something about language design.


Andrew Poelstra

unread,
Mar 24, 2010, 1:34:40 AM3/24/10
to
On 2010-03-24, ng2010 <ng2...@att.invalid> wrote:
>
> "jacob navia" <ja...@nospam.org> wrote in message
> news:ho1u16$cl5$1...@speranza.aioe.org...
>>
>> The usage of C is not decreasing but increasing. Big and important
>> projects like the linux kernel, Apache, and many others are written
>> in C.
>
> Don't yell/advertise that too loudly, because that will increasingly
> become a negative trait and a characteristic of obsolescence. All you did
> was state large and incomprehensible codebases and poorly designed
> software. (The Apache folks have some useful libraries that would be
> better if not for the limitations of the language they are written in).
>
> (Aside: Go Apache! Linux go suck a rock. GPL sucks!)
>

Ah, but surely you've noticed the popularity of
both Linux and Apache? Perhaps it's just since
all their users and developers are not as smart
as you are.

Because, obviously complexity is a Good Thing.

-plonk-

Tim Rentsch

unread,
Mar 25, 2010, 12:44:10 AM3/25/10
to
Nick <3-no...@temporary-address.org.uk> writes:

> Seebs <usenet...@seebs.net> writes:
>
>> But thinking about it more... Hmm. The problem is really the lack of
>> a good unambiguous shorthand for "container".

A better word than "container" is "collection".


> Invent a new technical term - like "box" or "sack". Why ever not?

Short words like this tend to be evocative of more specific (that
is, unintentionally or overly specific) properties, eg, a "box"
is "square" and "stackable", a "sack" will cause "everything to
be lumped together", etc. For a really abstract class a more
neutral, more generic word is better. Even "container" is more
evocative than "collection", which is neutral as to whether it
holds values or references.

Tim Rentsch

unread,
Mar 25, 2010, 1:02:22 AM3/25/10
to
Seebs <usenet...@seebs.net> writes:

> On 2010-03-17, jacob navia <ja...@spamsink.net> wrote:
>> Seebs a @C3{A9}crit :


>>> I honestly don't think that generalizing to "container" is going to be
>>> useful in C. In a language that doesn't have meaningful inheritance,
>>> it's very unusual for this kind of approach to get widespread adoption.
>
>> I do not know of any other attempt in C.
>

> I don't know of another generalization to container in C. I know of
> many lists and vectors and the like.


>
>> Inheritance is not necessary at all. The code works without it.
>

> But without inheritance, "container" is not a useful level of abstraction.

I think you're confusing two distinct concepts, namely, inheritance,
which has to do with code reuse within a class hierarchy (or library),
and interface/type conversion, which has to do with using one kind of
"thing" as a different kind of "thing". These notions are not
unrelated but still largely orthogonal; certainly it's possible to
have either of the two without having the other.

> The thing that makes "container" useful is that it provides for commonality
> between "list" and "hash". But that's only useful when list and hash are
> the types you actually work with, but because of inheritance, you can treat
> them both as containers.

Because of interface/type conversion, not because of inheritance.

> Without inheritance, either you have to call things "container" regardless
> of which they are, and thus have access to an API that only makes sense for
> a list when you're using a hash, and an API that only makes sense for a hash
> when you're using a list, or you lose the ability to write a function which
> just takes a "container".

Again, without interface/type conversion. Inheritance is an
implementation technique, and doesn't have any effect on how
client code uses a class library.

> I have often used list libraries. I'd use hash libraries if I needed a hash.
> In neither case would I use a "container" library in C -- it's the wrong
> level of abstraction for C, so far as I can tell. I've never in any language
> wanted "a container". In OO languages, it's useful that the specific things
> I request are also generically "containers". In C, it's not useful, because
> I can't do anything with it.

Actually, you could, although it takes a little more care and
little bit more effort in C than it does in languages that have
more support for object-oriented programming. That may make it
somewhat less useful in C than in other languages, but to say
absolutely that "it's not useful" in C is an overstatement.

Tim Rentsch

unread,
Mar 25, 2010, 1:24:53 AM3/25/10
to
Seebs <usenet...@seebs.net> writes:

> On 2010-03-20, ng2010 <ng2...@att.invalid> wrote:
>> This sounds sooo much like thrashing on whether a "Line" should draw
>> itself or should be drawn by a "Canvas" or other abstraction. Don't walk,
>> run to the next level: jettison old paradigms.
>
> This is pretty useless advice.
>
> Understanding what makes a design work is important regardless of language.

This comment seems somewhat naive. Some design patterns work much
better in one programming paradigm than another, and different
languages are definitely different in how well they fit different
paradigms. For example, C is just fine for procedural programming,
maybe okay for object-oriented programming, somewhere between fair
and poor (depending on "how functional") for functional programming,
and generally awful for logic programming. If someone is content to
stick just with design patterns that work in procedural programming
or (not too emphatic) object-oriented programming, then these all can
be expressed in C (or most other widely used procedural languages).
If, however, one wants to use functional programming design patterns
or logic programming design patterns, then trying to express said
designs in C will be fraught with difficulties. Of course, in the
literal sense the last statement quoted above may be true --
understanding what makes a design work _is_ important no matter which
language will be used to implement the design. But choosing a good
design, as well as understanding what makes it work, is _not_
independent of language, because not all designs work in all
languages.

Seebs

unread,
Mar 25, 2010, 1:35:47 AM3/25/10
to
On 2010-03-25, Tim Rentsch <t...@x-alumni2.alumni.caltech.edu> wrote:

> Seebs <usenet...@seebs.net> writes:
>> Understanding what makes a design work is important regardless of language.

> This comment seems somewhat naive. Some design patterns work much
> better in one programming paradigm than another, and different
> languages are definitely different in how well they fit different
> paradigms.

Sure.

> If, however, one wants to use functional programming design patterns
> or logic programming design patterns, then trying to express said
> designs in C will be fraught with difficulties.

Yes. That doesn't make it useless to look at how they work effectively,
even if the conclusion that leads you to is "this is a poor fit for
this language". :)

> Of course, in the
> literal sense the last statement quoted above may be true --
> understanding what makes a design work _is_ important no matter which
> language will be used to implement the design. But choosing a good
> design, as well as understanding what makes it work, is _not_
> independent of language, because not all designs work in all
> languages.

Agreed. But in a case like this in particular, I think it's quite
reasonable to talk about the kinds of design Jacob is looking at in
terms of C. There are good reasons to implement these things in C
at one level or another, and good reasons not to jump to C++.

Newness for the sake of newness is not a particularly good engineering
strategy.

Nick Keighley

unread,
Mar 25, 2010, 6:26:39 AM3/25/10
to
On 20 Mar, 02:48, "ng2010" <ng2...@att.invalid> wrote:
> "Seebs" <usenet-nos...@seebs.net> wrote in message
>
> news:slrnhq223i.oe0...@guild.seebs.net...
>
>
>

> > I have often used list libraries.  I'd use hash libraries if I needed a
> > hash.
> > In neither case would I use a "container" library in C -- it's the
> > wrong
> > level of abstraction for C, so far as I can tell.  I've never in any
> > language
> > wanted "a container".  In OO languages, it's useful that the specific
> > things
> > I request are also generically "containers".  In C, it's not useful,
> > because
> > I can't do anything with it.
>
> This sounds sooo much like thrashing on whether a "Line" should draw
> itself or should be drawn by a "Canvas" or other abstraction. Don't walk,
> run to the next level: jettison old paradigms.

so what's the answer?


Nick Keighley

unread,
Mar 25, 2010, 6:30:38 AM3/25/10
to

Nick Keighley

unread,
Mar 25, 2010, 6:32:22 AM3/25/10
to
On 25 Mar, 05:35, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-03-25, Tim Rentsch <t...@x-alumni2.alumni.caltech.edu> wrote:
>

replicating wooden bridge design in iron isn't good either

Nick Keighley

unread,
Mar 25, 2010, 6:46:15 AM3/25/10
to
On 24 Mar, 04:57, "ng2010" <ng2...@att.invalid> wrote:
> "jacob navia" <ja...@nospam.org> wrote in message
> news:ho1u16$cl5$1...@speranza.aioe.org...
> > ng2010 a crit :
> >> "jacob navia" <ja...@spamsink.net> wrote in message
> >>news:hnr08l$1ev$1...@speranza.aioe.org...
> >>> Seebs a crit :
> >>>> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:

ng:
If you hate C so much why do you post here?

> >> iron of detroit will be gone, rusted away. So
> >> will C rust away.

I wouldn't hold your beath though. Most of the modern clever stuff
sits on top of a C implementation layer.

> > The usage of C is not decreasing but increasing. Big and important
> > projects like the linux kernel, Apache, and many others are written
> > in C.
>
> Don't yell/advertise that too loudly, because that will increasingly
> become a negative trait and a characteristic of obsolescence. All you did
> was state large and incomprehensible codebases and poorly designed
> software. (The Apache folks have some useful libraries that would be
> better if not for the limitations of the language they are written in).
>
> (Aside: Go Apache! Linux go suck a rock. GPL sucks!)

what platform are you reading this on? I bet there's a fair amount of
C in there


> > The folks in C++ have been yelling this for ages now and
> > the usage of C doesn't disminish at all.
>
> C++ owes much of it's non-lucrativity to C. (Maybe ALL of it).

template syntax...

<snip>

> >> "A few" still drive around the old cars, but they are still deathtraps
> >> and old, obsolete technology.
>
> > Because you believe that more complexity is better. Go on. I believe
> > that the future belongs to SIMPLER languages.

"Programming languages should be designed not by piling feature on top
of feature, but by removing the weaknesses and restrictions that make
additional features appear necessary."

> You're not listening. (Did I mention something about "burying your head
> in the sand"?). I don't know you, so I don't know your ability to
> comprehend, learn and think. But you dialog in this thread so far to me
> seems to be very self-centered at worst, or childish at best.

you seem to think anyone who doesn't agree with you is stupid

<snip>


> > You, and all those
> > C++ zealots try to destroy C because deep in their minds they are
> > afraid
> > that people realize that what is important in a language is simplicity
> > and power, not complexity.

ah, back to the dark, paranoid side

> As if you knew something about language design.

you do?


--
"If you think C++ is not overly complicated, just what is a protected
abstract virtual base pure virtual private destructor, and when
was the last time you needed one?"
-- Tom Cargil, C++ Journal.

lawrenc...@siemens.com

unread,
Mar 25, 2010, 12:19:50 PM3/25/10
to

42
--
Larry Jones

I'm crying because out there he's gone, but he's not gone inside me. -- Calvin

Nick Keighley

unread,
Mar 26, 2010, 5:06:29 AM3/26/10
to
On 25 Mar, 16:19, lawrence.jo...@siemens.com wrote:

> Nick Keighley <nick_keighley_nos...@hotmail.com> wrote:
> > On 20 Mar, 02:48, "ng2010" <ng2...@att.invalid> wrote:
>
> > > This sounds sooo much like thrashing on whether a "Line" should draw
> > > itself or should be drawn by a "Canvas" or other abstraction. Don't walk,
> > > run to the next level: jettison old paradigms.
>
> > so what's the answer?
>
> 42

:-)

I suspect ng is one of those people who can issue vague platitudes by
the dumper-truck load but is rather short of substance. He likes the
pithy, gnomic phrase and the sneaky put-down but there isn't really
anything behind the facade.

I could always be wrong of course.

Tim Rentsch

unread,
Mar 26, 2010, 9:37:19 AM3/26/10
to
Seebs <usenet...@seebs.net> writes:

I was responding to the comment you made in the context of the
posting I responded to. I didn't know anything about the context
of "the kinds of design Jacob is looking at" because that context
had been snipped out of the posting I was responding to. I guess
I expect people to retain any previous context that's relevant
to what they're saying (and I admit I do sometimes err on the
side of caution in that area).

> Newness for the sake of newness is not a particularly good engineering
> strategy.

I'm sure there is more interesting discussion there but
it's getting somewhat far afield for comp.lang.c so I
will just stop here...

Tim Rentsch

unread,
Mar 26, 2010, 9:45:14 AM3/26/10
to
Nick Keighley <nick_keigh...@hotmail.com> writes:

Yes, I've read this before, and it's an interesting read.

I don't agree with his thesis that there's a linear
spectrum of language capability. For example, functional
programming and logic programming both have a lot of power,
but I wouldn't say either one is uniformly more capable
than the other. Despite that however I think the basic
lesson he's trying to convey is a useful one for most
C (and also C++) programmers.

Ben Bacarisse

unread,
Mar 26, 2010, 2:15:06 PM3/26/10
to
Tim Rentsch <t...@x-alumni2.alumni.caltech.edu> writes:

> Nick Keighley <nick_keigh...@hotmail.com> writes:
<snip>


>> http://www.paulgraham.com/avg.html
>
> Yes, I've read this before, and it's an interesting read.
>
> I don't agree with his thesis that there's a linear
> spectrum of language capability.

"Languages fall along a continuum [4] of abstractness, from the most
powerful all the way down to machine languages..."

Did you see footnote [4]?

"[4] Note to nerds: or possibly a lattice, narrowing toward the top;
it's not the shape that matters here but the idea that there is at
least a partial order."

That may not satisfy you but he addresses the issue; to the extent
that your representation of his thesis is a little misleading.

> For example, functional
> programming and logic programming both have a lot of power,
> but I wouldn't say either one is uniformly more capable
> than the other.

<snip>
--
Ben.

Tim Rentsch

unread,
Mar 26, 2010, 11:06:13 PM3/26/10
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> Tim Rentsch <t...@x-alumni2.alumni.caltech.edu> writes:
>
>> Nick Keighley <nick_keigh...@hotmail.com> writes:
> <snip>
>>> http://www.paulgraham.com/avg.html
>>
>> Yes, I've read this before, and it's an interesting read.
>>
>> I don't agree with his thesis that there's a linear
>> spectrum of language capability.
>
> "Languages fall along a continuum [4] of abstractness, from the most
> powerful all the way down to machine languages..."
>
> Did you see footnote [4]?
>
> "[4] Note to nerds: or possibly a lattice, narrowing toward the top;
> it's not the shape that matters here but the idea that there is at
> least a partial order."
>
> That may not satisfy you but he addresses the issue; to the extent
> that your representation of his thesis is a little misleading.

I didn't see the footnote, thank you for pointing it out.

However, my basic objection remains, because I don't think the
space is a lattice either (or even especially "lattice-like").
In particular, there's no obvious way to take the 'join' of
functional programming and logic programming, as one example.
The conceptual language that dominates both may not even exist,
and certainly doesn't exist now as far as I know. So although I
may have misrepresented the letter of the article's thesis, I
don't believe I've misrepresented its spirit.

(Despite the foregoing I think you're right that my previous
representation is a little misleading, which I hope has been
cleared up in this response.)

Ian Collins

unread,
Mar 27, 2010, 12:22:44 AM3/27/10
to
On 03/27/10 07:15 AM, Ben Bacarisse wrote:
> Tim Rentsch<t...@x-alumni2.alumni.caltech.edu> writes:
>
>> Nick Keighley<nick_keigh...@hotmail.com> writes:
> <snip>
>>> http://www.paulgraham.com/avg.html
>>
>> Yes, I've read this before, and it's an interesting read.
>>
>> I don't agree with his thesis that there's a linear
>> spectrum of language capability.
>
> "Languages fall along a continuum [4] of abstractness, from the most
> powerful all the way down to machine languages..."
>
> Did you see footnote [4]?
>
> "[4] Note to nerds: or possibly a lattice, narrowing toward the top;
> it's not the shape that matters here but the idea that there is at
> least a partial order."
>
> That may not satisfy you but he addresses the issue; to the extent
> that your representation of his thesis is a little misleading.

It is an interesting if flawed thesis. I prefer to consider the
expressiveness (where a language like Common Lisp can be considered more
expressive than procedural languages) rather than the capability of a
programming language. Capability goes further than mere expressiveness;
neither PHP of Java would appear high on the expressiveness table but
they are both extremely capable. Their capability comes in part from
extensive library support.

The capability of a language is also bound by the domain it is being
used in. Yes, the author was able to produce a market leading
application in an arcane language, but he was in a green field. There
weren't any competing technologies.

--
Ian Collins

ng2010

unread,
Mar 27, 2010, 11:24:30 PM3/27/10
to

"Nick Keighley" <nick_keigh...@hotmail.com> wrote in message
news:8b8941ab-26f5-40b3...@t23g2000yqt.googlegroups.com...

> On 24 Mar, 04:57, "ng2010" <ng2...@att.invalid> wrote:
>> "jacob navia" <ja...@nospam.org> wrote in message
>> news:ho1u16$cl5$1...@speranza.aioe.org...
>> > ng2010 a crit :
>> >> "jacob navia" <ja...@spamsink.net> wrote in message
>> >>news:hnr08l$1ev$1...@speranza.aioe.org...
>> >>> Seebs a crit :
>> >>>> On 2010-03-17, jacob navia <ja...@nospam.org> wrote:
>

First, I don't think JN needs a lawyer that you seem to want to be. That
said...

> ng:
> If you hate C so much why do you post here?

I can spar (since you and a few others seem to want to): you Clots
(pronounced sea-lots).
For those who like long, drawn-out, useless threads, you may want to
describe in detail how you reached the above (false) conclusion.

>
>> >> iron of detroit will be gone, rusted away. So
>> >> will C rust away.
>
> I wouldn't hold your beath though.

I don't have to wait until the bondo pops off of the sheet metal to
notice the lack of any solid metal. No one has to ever stop using it of
course and you old-timers won't and can't, because the language will
outlive you by a longshot. Sorry to sound like Mr. Grim, but it is true.
I'm not spending my "final" days here on a WWII submarine!

> Most of the modern clever stuff
> sits on top of a C implementation layer.

I already mentioned that there may be a place for something like that
(but probably not). At least YOU gave one answer to the question I posed
to JN (What is a good "domain" for C? or something like that I posed).
Good. You gave an answer, though without realizing it and without
realizing maybe that you just regurgitated an example I myself gave.

>
>> > The usage of C is not decreasing but increasing. Big and important
>> > projects like the linux kernel, Apache, and many others are written
>> > in C.
>>
>> Don't yell/advertise that too loudly, because that will increasingly
>> become a negative trait and a characteristic of obsolescence. All you
>> did
>> was state large and incomprehensible codebases and poorly designed
>> software. (The Apache folks have some useful libraries that would be
>> better if not for the limitations of the language they are written
>> in).
>>
>> (Aside: Go Apache! Linux go suck a rock. GPL sucks!)
>
> what platform are you reading this on? I bet there's a fair amount of
> C in there

There's a lot of houses with asbestos in them where people still live.
And hey, it's a fire retardant! Surely by that "logic", all houses should
make use of asbestos. That is the point you just made.

>
>
>> > The folks in C++ have been yelling this for ages now and
>> > the usage of C doesn't disminish at all.
>>
>> C++ owes much of it's non-lucrativity to C. (Maybe ALL of it).
>
> template syntax...

That's OPTIONAL. You can't get away from the C-lineage elements. BIG, BIG
difference. If C was on trial, surely you be the prosecution's best
"friend"! The new languages are coming, I assure you. Then finally that
corpse that is C can be laid to rest (yes, it has been dead for a long
time). Your curt, shoot-from-the-hip "example" is NOT one.

I couldn't resist: this is quite fun. I find discussions like this
entertaining sometimes, and I do find that, though arduous, small gems
can still be found.

>
> <snip>


>> As if you knew something about language design.
>
> you do?

I do what? Voodoo? Can you speak in complete sentences or just in C?

ng2010

unread,
Mar 27, 2010, 11:28:59 PM3/27/10
to

"Tim Rentsch" <t...@x-alumni2.alumni.caltech.edu> wrote in message
news:kfn1vf9...@x-alumni2.alumni.caltech.edu...

There are those who like "all the bells and whistles" and need them to
write the simplest of programs and those who like the basics and exploit
them to their fullest. In between, there are a few programmers, but most
lie toward one of those extremes. (At least, so I conjecture).


ng2010

unread,
Mar 27, 2010, 11:42:36 PM3/27/10
to

"Nick Keighley" <nick_keigh...@hotmail.com> wrote in message
news:d2ef87aa-ea8d-471c...@k13g2000yqe.googlegroups.com...

Dude, you're the one with curt interjection, incomplete thoughts,
indicative of lack of substance and with a whole lot of agenda, IMO. I've
read some of the other long threads in here enough to know that some of
you LUV to argue (or jack off or something together). I don't read the
names/nicks, for I don't care "who said what", but the Clots seem to be a
true "group" of some sort that isn't at all productive as far as valuable
information goes.

I'm sorry to anyone I offended and keep offending by saying "Clots". (It
is meant to be instructional/educational and not hurtful).


ng2010

unread,
Mar 27, 2010, 11:49:16 PM3/27/10
to

I not sure I want to respond to that RFP. What's my end on that after
taxes? High-side, low-side. No low-ballers need respond.


ng2010

unread,
Mar 28, 2010, 1:18:50 AM3/28/10
to
Nick Keighley wrote:
> On 17 Mar, 04:22, "ng2010" <ng2...@att.invalid> wrote:
>> So sad to be dying and seeing youth tackling problems already solved
>> in my own youth.
>
> and the solution was? I'm not convinced there *is* a single right
> answer for all situations.

Stating the obvious does not make you wise (you owe me now for I am your
teacher). I want money.

Else, shut up.


Tim Rentsch

unread,
Mar 28, 2010, 11:27:35 AM3/28/10
to
"ng2010" <ng2...@att.invalid> writes:

Hmmmm... which end would you put C++ at?

Phil Carmody

unread,
Mar 28, 2010, 12:35:15 PM3/28/10
to
"ng2010" <ng2...@att.invalid> writes:
> The new languages are coming, I assure you. Then finally that
> corpse that is C can be laid to rest (yes, it has been dead for a long
> time). Your curt, shoot-from-the-hip "example" is NOT one.

Ouch - you just bent my troll-detector's needle as it tried to
hit twelve.

One more bozo for the bin, I guess.

Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1

bartc

unread,
Mar 28, 2010, 2:30:06 PM3/28/10
to

"ng2010" <ng2...@att.invalid> wrote in message
news:homidc$70t$1...@news.eternal-september.org...

> The new languages are coming, I assure you.

Which languages are these?

--
Bartc

Richard Heathfield

unread,
Mar 28, 2010, 1:45:26 PM3/28/10
to

Ones that he hopes he will be able to understand better than he
understands C.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

Richard Bos

unread,
Mar 29, 2010, 5:12:00 PM3/29/10
to
"bartc" <ba...@freeuk.com> wrote:

> "ng2010" <ng2...@att.invalid> wrote in message
>

> > The new languages are coming, I assure you.
>
> Which languages are these?

Java and NewBASIC.

Richard

0 new messages