Container library (continued) #2

  • Follow


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
0
Reply jacob31 (869) 3/16/2010 11:07:38 PM

On 2010-03-16, jacob navia <jacob@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-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply usenet-nospam (2199) 3/16/2010 11:22:09 PM


On 2010-03-16, jacob navia <jacob@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

0
Reply apoelstra (387) 3/17/2010 1:32:29 AM

So sad to be dying and seeing youth tackling problems already solved in 
my own youth. 


0
Reply ng2010 (6) 3/17/2010 4:22:38 AM

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
0
Reply jacob24 (973) 3/17/2010 8:45:35 AM

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.
0
Reply jacob24 (973) 3/17/2010 8:46:46 AM

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.
0
Reply nick_keighley_nospam (4574) 3/17/2010 8:58:15 AM

On 16 Mar, 23:07, 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 =A0 --> 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 =A0strategy 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?

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...


0
Reply nick_keighley_nospam (4574) 3/17/2010 9:01:42 AM

> 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.
0
Reply malcolm.mclean5 (725) 3/17/2010 9:11:29 AM

On 2010-03-17, jacob navia <jacob@nospam.org> wrote:
> 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

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
0
Reply apoelstra (387) 3/17/2010 2:50:09 PM

On 2010-03-17, jacob navia <jacob@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.

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

Seebs a �crit :
> On 2010-03-17, jacob navia <jacob@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.
0
Reply jacob31 (869) 3/17/2010 4:33:26 PM

On 2010-03-17, jacob navia <jacob@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.

-s
-- 
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply usenet-nospam (2199) 3/17/2010 4:50:06 PM

On 2010-03-17, Seebs <usenet-nospam@seebs.net> wrote:
> On 2010-03-17, jacob navia <jacob@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++"

-- 
Andrew Poelstra
http://www.wpsoftware.net/andrew
0
Reply apoelstra (387) 3/17/2010 5:43:02 PM

On 2010-03-17, Andrew Poelstra <apoelstra@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
-- 
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply usenet-nospam (2199) 3/17/2010 5:47:50 PM

On Mar 16, 7:07=A0pm, 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 =A0 --> 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 =A0strategy 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

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.
0
Reply jadill33 (201) 3/17/2010 5:58:22 PM

On Mar 17, 1:47=A0pm, 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. =A0I just don't think that it's a good enough fit to rewar=
d
> 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. =A0But 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. =A0I
> suppose some kind of type indicator could help.
>
> But at this point, you end up with things that have a fair bit of overhea=
d,
> 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 alon=
e
> 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. =A0Peter Seebach / usenet-nos...@see=
bs.nethttp://www.seebs.net/log/<-- lawsuits, religion, and funny picturesht=
tp://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

0
Reply jadill33 (201) 3/17/2010 6:24:00 PM

On 03/18/10 05:50 AM, Seebs wrote:
> On 2010-03-17, jacob navia<jacob@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
0
Reply ian-news (9880) 3/17/2010 6:48:40 PM

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
0
Reply ian-news (9880) 3/17/2010 6:51:31 PM

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. =A0In 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.
0
Reply Nick 3/18/2010 8:26:26 AM

On Mar 18, 4:26=A0am, Nick Keighley <nick_keighley_nos...@hotmail.com>
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. =A0In 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.

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 =3D my_list_iterator_create( list,
my_list_front( list ) );
or maybe
my_list_iterator_t l =3D 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 =3D 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.
0
Reply ImpalerCore 3/18/2010 2:16:09 PM

On 2010-03-18, ImpalerCore <jadill33@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.

-- 
Andrew Poelstra
http://www.wpsoftware.net/andrew
0
Reply Andrew 3/18/2010 3:03:01 PM

Andrew Poelstra a �crit :
> On 2010-03-18, ImpalerCore <jadill33@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);
	}

> 
> 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.
> 
0
Reply jacob 3/18/2010 3:26:02 PM

On 2010-03-18, jacob navia <jacob@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.
>> 


-- 
Andrew Poelstra
http://www.wpsoftware.net/andrew
0
Reply Andrew 3/18/2010 3:36:42 PM

On 2010-03-18, Andrew Poelstra <apoelstra@localhost.localdomain> wrote:
> On 2010-03-18, jacob navia <jacob@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.

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

Seebs a �crit :
> On 2010-03-18, Andrew Poelstra <apoelstra@localhost.localdomain> wrote:
>> On 2010-03-18, jacob navia <jacob@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.
0
Reply jacob 3/18/2010 4:04:25 PM

On 2010-03-18, jacob navia <jacob@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.  :)

-s
-- 
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply Seebs 3/18/2010 4:33:32 PM

jacob navia <jacob@nospam.org> writes:

> Andrew Poelstra a écrit :
>> On 2010-03-18, ImpalerCore <jadill33@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.

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.
0
Reply Ben 3/18/2010 5:02:51 PM

Seebs <usenet-nospam@seebs.net> writes:

> On 2010-03-18, Andrew Poelstra <apoelstra@localhost.localdomain> wrote:
>> On 2010-03-18, jacob navia <jacob@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.
0
Reply Ben 3/18/2010 5:36:35 PM

On Mar 18, 11:03=A0am, 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++. =A0This 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. =A0I 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. =A0If 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 =3D (Iter *) get_first(MyList); it; it =3D it->next) {
> =A0 T *data =3D it->data;
> =A0 data->foo =3D grommit();
> =A0 data->bar =3D 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 =3D (Iter *) get_first(MyArray); it; it =3D it->next) {
  T *data =3D it->data;
  data->foo =3D grommit();
  data->bar =3D 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 =3D 42;
my_array_t* array =3D my_array_new( 100, int );
my_array_push_back( array, &n, int );
int* p =3D my_array_front( array, int );
if ( p && *p =3D=3D 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

0
Reply ImpalerCore 3/18/2010 5:38:53 PM

On 2010-03-18, ImpalerCore <jadill33@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
http://www.wpsoftware.net/andrew

0
Reply Andrew 3/18/2010 5:52:24 PM

On 2010-03-18, Andrew Poelstra <apoelstra@localhost.localdomain> wrote:
> On 2010-03-18, ImpalerCore <jadill33@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.

-- 
Andrew Poelstra
http://www.wpsoftware.net/andrew
0
Reply Andrew 3/18/2010 5:54:57 PM

On 2010-03-18, Ben Bacarisse <ben.usenet@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.

-s
-- 
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply Seebs 3/18/2010 6:24:38 PM

Seebs <usenet-nospam@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
0
Reply Nick 3/18/2010 7:57:38 PM

Seebs <usenet-nospam@seebs.net> writes:

> On 2010-03-18, Ben Bacarisse <ben.usenet@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.
0
Reply Ben 3/18/2010 9:51:52 PM

On 2010-03-18, Ben Bacarisse <ben.usenet@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.

-s
-- 
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply Seebs 3/19/2010 2:03:07 AM

Seebs <usenet-nospam@seebs.net> writes:

> On 2010-03-18, Ben Bacarisse <ben.usenet@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.
0
Reply Ben 3/19/2010 2:23:05 AM

On 2010-03-19, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
> Seebs <usenet-nospam@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.  :)

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

Seebs <usenet-nospam@seebs.net> writes:

> On 2010-03-19, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
>> Seebs <usenet-nospam@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.
0
Reply Ben 3/19/2010 11:08:21 AM

On 2010-03-19, Ben Bacarisse <ben.usenet@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.

-s
-- 
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply Seebs 3/19/2010 5:13:49 PM

"jacob navia" <jacob@spamsink.net> wrote in message 
news:hnr08l$1ev$1@speranza.aioe.org...
> Seebs a �crit :
>> On 2010-03-17, jacob navia <jacob@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. 


0
Reply ng2010 3/20/2010 2:44:39 AM

"Seebs" <usenet-nospam@seebs.net> wrote in message 
news:slrnhq223i.oe0.usenet-nospam@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. 


0
Reply ng2010 3/20/2010 2:48:07 AM

"Andrew Poelstra" <apoelstra@localhost.localdomain> wrote in message 
news:slrnhq24u8.ls9.apoelstra@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.


0
Reply ng2010 3/20/2010 2:56:54 AM

On 2010-03-20, ng2010 <ng2010@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.

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

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. 


0
Reply ng2010 3/20/2010 3:06:54 AM

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? 


0
Reply ng2010 3/20/2010 3:12:48 AM

Seebs wrote:
> On 2010-03-20, ng2010 <ng2010@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".



0
Reply ng2010 3/20/2010 3:15:21 AM

On 2010-03-20, ng2010 <ng2010@att.invalid> wrote:
> Seebs wrote:
>> On 2010-03-20, ng2010 <ng2010@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".

"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.

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

ng2010 a �crit :
> "jacob navia" <jacob@spamsink.net> wrote in message 
> news:hnr08l$1ev$1@speranza.aioe.org...
>> Seebs a �crit :
>>> On 2010-03-17, jacob navia <jacob@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.
0
Reply jacob 3/20/2010 7:37:59 AM

On Fri, 19 Mar 2010 21:56:54 -0500
"ng2010" <ng2010@att.invalid> wrote:

> 
> "Andrew Poelstra" <apoelstra@localhost.localdomain> wrote in message 
> news:slrnhq24u8.ls9.apoelstra@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.
> 

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... 

0
Reply Lorenzo 3/20/2010 10:44:51 AM

Nick Keighley <nick_keighley_nospam@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
0
Reply raltbos 3/21/2010 3:53:59 PM

"Lorenzo Villari" <vlllnz@tiscali.it> wrote in message 
news:20100320114451.047d1d82@kubuntu...
> On Fri, 19 Mar 2010 21:56:54 -0500
> "ng2010" <ng2010@att.invalid> wrote:
>
>>
>> "Andrew Poelstra" <apoelstra@localhost.localdomain> wrote in message
>> news:slrnhq24u8.ls9.apoelstra@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.
>>
>
> 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...
>

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). 


0
Reply ng2010 3/24/2010 4:13:10 AM

"jacob navia" <jacob@nospam.org> wrote in message 
news:ho1u16$cl5$1@speranza.aioe.org...
> ng2010 a �crit :
>> "jacob navia" <jacob@spamsink.net> wrote in message 
>> news:hnr08l$1ev$1@speranza.aioe.org...
>>> Seebs a �crit :
>>>> On 2010-03-17, jacob navia <jacob@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.


0
Reply ng2010 3/24/2010 4:57:30 AM

On 2010-03-24, ng2010 <ng2010@att.invalid> wrote:
>
> "jacob navia" <jacob@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-

-- 
Andrew Poelstra
http://www.wpsoftware.net/andrew
0
Reply Andrew 3/24/2010 5:34:40 AM

Nick <3-nospam@temporary-address.org.uk> writes:

> Seebs <usenet-nospam@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.
0
Reply Tim 3/25/2010 4:44:10 AM

Seebs <usenet-nospam@seebs.net> writes:

> On 2010-03-17, jacob navia <jacob@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.
0
Reply Tim 3/25/2010 5:02:22 AM

Seebs <usenet-nospam@seebs.net> writes:

> On 2010-03-20, ng2010 <ng2010@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.
0
Reply Tim 3/25/2010 5:24:53 AM

On 2010-03-25, Tim Rentsch <txr@x-alumni2.alumni.caltech.edu> wrote:
> Seebs <usenet-nospam@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.

-s
-- 
Copyright 2010, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply Seebs 3/25/2010 5:35:47 AM

On 25 Mar, 05:24, Tim Rentsch <t...@x-alumni2.alumni.caltech.edu>
wrote:
> Seebs <usenet-nos...@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 wa=
lk,
> >> run to the next level: jettison old paradigms.
>
> > This is pretty useless advice.
>
> > Understanding what makes a design work is important regardless of langu=
age.
>
> This comment seems somewhat naive. =A0Some design patterns work much
> better in one programming paradigm than another, and different
> languages are definitely different in how well they fit different
> paradigms. =A0For 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. =A0If 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. =A0Of 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. =A0But 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.

http://www.paulgraham.com/avg.html



0
Reply Nick 3/25/2010 10:30:38 AM

On 25 Mar, 05:35, Seebs <usenet-nos...@seebs.net> wrote:
> On 2010-03-25, Tim Rentsch <t...@x-alumni2.alumni.caltech.edu> wrote:
>
> > Seebs <usenet-nos...@seebs.net> writes:
> >> Understanding what makes a design work is important regardless of lang=
uage.
> > This comment seems somewhat naive. =A0Some 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. =A0That 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". =A0:)
>
> > 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. =A0But 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. =A0But 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. =A0There 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.

replicating wooden bridge design in iron isn't good either



0
Reply Nick 3/25/2010 10:32:22 AM

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.
0
Reply Nick 3/25/2010 10:46:15 AM

Seebs <usenet-nospam@seebs.net> writes:

> On 2010-03-25, Tim Rentsch <txr@x-alumni2.alumni.caltech.edu> wrote:
>> Seebs <usenet-nospam@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++.

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...
0
Reply Tim 3/26/2010 1:37:19 PM

Nick Keighley <nick_keighley_nospam@hotmail.com> writes:

> On 25 Mar, 05:24, Tim Rentsch <t...@x-alumni2.alumni.caltech.edu>
> wrote:
>> Seebs <usenet-nos...@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.
>
> 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.  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.
0
Reply Tim 3/26/2010 1:45:14 PM

Tim Rentsch <txr@x-alumni2.alumni.caltech.edu> writes:

> Nick Keighley <nick_keighley_nospam@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.
0
Reply Ben 3/26/2010 6:15:06 PM

Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Tim Rentsch <txr@x-alumni2.alumni.caltech.edu> writes:
>
>> Nick Keighley <nick_keighley_nospam@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.)
0
Reply Tim 3/27/2010 3:06:13 AM

On 03/27/10 07:15 AM, Ben Bacarisse wrote:
> Tim Rentsch<txr@x-alumni2.alumni.caltech.edu>  writes:
>
>> Nick Keighley<nick_keighley_nospam@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
0
Reply Ian 3/27/2010 4:22:44 AM

"Nick Keighley" <nick_keighley_nospam@hotmail.com> wrote in message 
news:8b8941ab-26f5-40b3-89e7-e6b5779be8b9@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?



0
Reply ng2010 3/28/2010 3:24:30 AM

"Tim Rentsch" <txr@x-alumni2.alumni.caltech.edu> wrote in message 
news:kfn1vf9otwa.fsf@x-alumni2.alumni.caltech.edu...
> Seebs <usenet-nospam@seebs.net> writes:
>
>> On 2010-03-20, ng2010 <ng2010@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.
>

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). 


0
Reply ng2010 3/28/2010 3:28:59 AM

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. 


0
Reply ng2010 3/28/2010 5:18:50 AM

"ng2010" <ng2010@att.invalid> writes:

> "Tim Rentsch" <txr@x-alumni2.alumni.caltech.edu> wrote in message 
> news:kfn1vf9otwa.fsf@x-alumni2.alumni.caltech.edu...
>> Seebs <usenet-nospam@seebs.net> writes:
>>
>>> On 2010-03-20, ng2010 <ng2010@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.
>>
>
> 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). 

Hmmmm...  which end would you put C++ at?
0
Reply Tim 3/28/2010 3:27:35 PM

"ng2010" <ng2010@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
0
Reply Phil 3/28/2010 4:35:15 PM

"ng2010" <ng2010@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 

0
Reply bartc 3/28/2010 5:32:09 PM

bartc wrote:
> 
> "ng2010" <ng2010@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?

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
0
Reply Richard 3/28/2010 5:45:26 PM

"bartc" <bartc@freeuk.com> wrote:

> "ng2010" <ng2010@att.invalid> wrote in message 
> 
> > The new languages are coming, I assure you.
> 
> Which languages are these?

Java and NewBASIC.

Richard
0
Reply raltbos 3/29/2010 9:12:00 PM

73 Replies
40 Views

(page loaded in 1.516 seconds)

Similiar Articles:







7/28/2012 9:02:11 PM


Reply: