things i would ban from clc

J

jacob navia

Le 13/03/12 09:52, gwowen a écrit :
Your proposal will fail, and your energy will be wasted.

Says "gwowen", widely known guy.

They have been aproved by the French Normalization committee.
Among the
many reasons for this not least because using void* as your
fundamental type shifts makes the compiler implenters life easy by
shifting all the effort onto to the programmer.

I use void pointers for the data stored in the containers, yes. This
is the generic pointer in C. If you want C++ go there and do that.

I am programming for the C language because I work in C and I do not
want C++ or templates. Now, if you do not like that it is OK with me,
use the STL!

No one want generics
where type safety is the responsibility of the programmer, and they
have to keep casting their object pointers back and forth.

There are no casts to void * needed or from void * to any other kind of
pointer needed in C, to the contrary of C++.

Learn C before you accuse me of forcing casts!
That why C++ templates win - compile time type safety.

Use templates then pleeeeze. f you want to program in C++ do that
but let me program in C.
You haven't got
that, and you haven't got exceptions,

You haven't even bothered to READ the error handling proposed
in the library. There are exceptions: they are called

"Error handling functions"

and they provide you with all the
needed hooks to change them, to trap certain kinds of error and not
others, etc.

They are provided in a
(1) Global basis (to trap ALL errors or ALL errors of a certain kind for
ALL containers
(2) IN a per class way so that you can change error behavior for lists
only, for instance
(3) In a per container way so that you can change the error behavior in
a per single list way for instance


and that means that your
interfaces and error handling is horrible to the point of
unusability.

You can always say that, but since you do not address ANY of the
specifications proposed it is just an assertion of your personal
dislike of C as a programming language. Granted, you think C++ is
the best thing since sliced bread.

Use C++ then!

So what you have will never be widely accepted.

Maybe, there are many technically sound proposals that were rejected
because the people proposing them had no political (and economic) clout.
Other reasons include your inability to accept any technical criticism
of your design. You simply won't be able to persuade anyone of
anything without a change in attitude.

You are not doing any technical criticism, just ranting. You have not
even cared to address why the error interface concretely is wrong,
what would you change in it, what the technical problems are.

Your only message is

C++ is better.
You may now accuse be of making personal attacks thereby proving my
point.

No, you are just ranting, I do not feel personally attacked, nor I
consider your critic as justified since there isn't a SINGLE concrete
reason why the error interface is bad. You just haven't even read what
I propose.
 
G

gwowen

jacob said:
Le 13/03/12 09:52, gwowen a �crit :

Says "gwowen", widely known guy.

Wow, straight in with the ad hominem.
Learn C before you accuse me of forcing casts!

Casts wasn't the right term, but the point still stands.

Suppose I have a list of doubles and want to write a function that
adds them all together and returns the result. That's a reasonable
function, right?
Can I do that without a cast? Please show the code.

Can I do that with your library in such a way that attempting to pass
a list of strings to that function is a compile time error? Please
show the code.

If the compiler can't distinguish between a container of beans and a
container of buses, the programmer is forced to carry all the type
information around in their head.

(Don't bother responding to the below unless you've provided the code
for the above).
You haven't even bothered to READ the error handling proposed
in the library.

Yes I have. I understand completely your error handling system, thank
you very much.
There are exceptions: they are called "Error handling functions"

Error handling functions are not exceptions. If you think they are
equivalent, its no wonder you don't understand other peoples technical
complaints. Error handling functions transfer code control to a
specified function at error time. Exceptions propagate down the call
chain *automatically freeing unrelated stack resources unrelated to
the object in which the error occured*.

How can your error functions can do that? Error functions can't do
resource handling unless I register a new error function at every
point in the call chain in which resources are allocated. That's
unmanageable. RAII and proper exceptions give you it for free. The
best you can do is the equivalent making the programmer use a setjmp()
at every point where resources are allocated.
 
B

Ben Bacarisse

jacob navia said:
Says "gwowen", widely known guy.

They have been aproved by the French Normalization committee.

Congratulations. Can you provide a link or document number or something
so that the progress can be tracked?

<snip>
 
J

jacob navia

Le 13/03/12 14:06, gwowen a écrit :
Wow, straight in with the ad hominem.


Casts wasn't the right term, but the point still stands.

Suppose I have a list of doubles and want to write a function that
adds them all together and returns the result. That's a reasonable
function, right?

You can do that with the valarray container.
Can I do that without a cast? Please show the code.

#include "ccl/containers.h"

int fn(void)
{
ValArrayDouble *tab = iValArrayDouble.Create(25);
iValARrayDouble.Add(tab,"boooo"); <----- compile time error
}

You can add compile time error checking using the templated source
code provided with the library. Since you have (as you imply) read
the documentation you know how to do this.
Can I do that with your library in such a way that attempting to pass
a list of strings to that function is a compile time error? Please
show the code.

The code is in the home page of the library. Use the valarray code
for instance.
If the compiler can't distinguish between a container of beans and a
container of buses, the programmer is forced to carry all the type
information around in their head.

You want C++? Well, you know where to go if you need that.
(Don't bother responding to the below unless you've provided the code
for the above).


I have presented a generic valarray container and instantiated it for
double, ints, size_t. That adds compile time checks if you need it.
Yes I have. I understand completely your error handling system, thank
you very much.


Error handling functions are not exceptions. If you think they are
equivalent, its no wonder you don't understand other peoples technical
complaints. Error handling functions transfer code control to a
specified function at error time. Exceptions propagate down the call
chain *automatically freeing unrelated stack resources unrelated to
the object in which the error occured*.

You can do that with lcc-win SEH. It is not part of the library because
that's not standard C. I am programming in C as you MAY know. I do not
need C++ nor do I need hand holding for cleaning up.

How can your error functions can do that? Error functions can't do
resource handling unless I register a new error function at every
point in the call chain in which resources are allocated.

That its not how the C language works "gwowen". Please, go to the C++
group and do not ask C software to do what C++ software does.

There are no exceptions in THAT sense in standard C. I implemented them
in lcc-win. But they aren't part of the library since the library uses
only C89.

That's
unmanageable.

No. If your error function returns you TEST THE RESULT of each operation
and act accordingly.


RAII and proper exceptions give you it for free.

But they cost the incredibly mess of C++ . That is not free, by any
means.

The
best you can do is the equivalent making the programmer use a setjmp()
at every point where resources are allocated.

Or, when you do an operation that can fail you test the result and free
the resources if you need to.
 
I

ImpalerCore

Wow, straight in with the ad hominem.


Casts wasn't the right term, but the point still stands.

Suppose I have a list of doubles and want to write a function that
adds them all together and returns the result.   That's a reasonable
function, right?
Can I do that without a cast? Please show the code.

Can I do that with your library in such a way that attempting to pass
a list of strings to that function is a compile time error? Please
show the code.

If the compiler can't distinguish between a container of beans and a
container of buses, the programmer is forced to carry all the type
information around in their head.

(Don't bother responding to the below unless you've provided the code
for the above).

I don't understand the point of this challenge. Templates are not a
part of standard C, so it's like asking him to fill a circular hole
with a square peg. If you're asking for language features that aren't
supported by C, use a different language?

I understand that there are fundamental advantages of using a language
like C++ over C, especially with the STL. It's probably one of C++'s
top 3 biggest selling points. In C, the best you can do is a tradeoff
between type-safety and code maintenance/duplication. If you want to
parameterize code using 'void*' and 'int (*cmp_fn)( const void*, const
void* )' to reduce code maintenance/duplication, I don't see how
that's the "wrong" choice to make when designing a container in C. If
type-safety matters that much to you, then you obviously won't use
Jacob's library for that reason.
Yes I have. I understand completely your error handling system, thank
you very much.


Error handling functions are not exceptions.  If you think they are
equivalent, its no wonder you don't understand other peoples technical
complaints.  Error handling functions transfer code control to a
specified function at error time.  Exceptions propagate down the call
chain *automatically freeing unrelated stack resources unrelated to
the object in which the error occured*.

How can your error functions can do that?  Error functions can't do
resource handling unless I register a new error function at every
point in the call chain in which resources are allocated. That's
unmanageable. RAII and proper exceptions give you it for free. The
best you can do is the equivalent making the programmer use a setjmp()
at every point where resources are allocated.

Again, you are asking for support for implicitly executed destructors,
not part of the standard C.

It seems that you think that writing a container library is a fool's
errand when C++ is so readily available. That is certainly a strong
argument for choosing the right language. But if you've chosen C to
do your job, you have to live with the consequences. If you want to
abstract container code, the programmer will have to live with
carrying the type information around in his head. You may think the
burden is too much, but we're C programmers! We write our own linked
lists and string libraries and we like it.

With that said, while I am in favor of creating a generic container
library, in my opinion it should at best be relegated to something of
a de-facto standard like Boost to see if it gains wide acceptance
(whatever that means), then maybe consider it for standardization as
you'd have at least a little political pull.

But if Jacob wants to swim in dangerous waters, who are we to deny
him?

Best regards,
John D.
 
D

Don Y

Hi Keith,

Don Y said:
Why not support for *tasking* -- native to the language
(instead of in a library!) like Limbo?
[...]

The 2011 ISO C standard includes (optional) support for threading.

See<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf>
section 7.26.

OK. But that's just another standard library. The language
itself doesn't include those provisions.

E.g., Limbo includes a "spawn" keyword and the mechanisms
to dynamically create that "thread" (trying not to get
bogged down into thread/process/task/etc. lexicon) along
with mechanisms to *load* modules ("programs"), tear
"processes" down and pass values between "processes".

It's not an "add on" but, rather, an integral part of
the language, itself.
 
B

Ben Pfaff

Don Y said:
OK. But that's just another standard library. The language
itself doesn't include those provisions.

What's the advantage of putting threading into language instead
of the library? (You explained *how* Limbo integrates threading
into the language, but not why it does.)
 
J

jacob navia

Le 13/03/12 14:06, gwowen a écrit :
Wow, straight in with the ad hominem.

Yes, that was utterly unnecessary.

The problem is that we have gone through this too many times. I loose
my mind. You say I will fail because I write C, and C++ is much better
as everybody knows.

That is not an excuse to start with a stupid sentence like I did.

I apologize for that.
 
D

Don Y

Hi Ben,

What's the advantage of putting threading into language instead
of the library? (You explained *how* Limbo integrates threading
into the language, but not why it does.)

It elevates threads to first-class objects. It recognizes
that programs are more "collections of threads" than "monolithic,
single-threaded processes" that have to *struggle* to
CO-operate.

C could have put all floating point math operations
(including +, -, etc.) into a "floating point library".
Instead, floats/doubles are an integral part of the
language -- even on platforms where supporting
floats is "troublesome" (no FP hardware).

Moving things into the language also changes who is
responsible for the implementation and performance of
the feature. In Limbo, the "compiler"/runtime VM handle
ALL of the mechanisms associated with these features.
it means that those features are accessible to your
code on any platform that can support Limbo programs.
(double edged sword... if you don't like how they do
it, you can't just swap out that aspect like you can with
a separate library).

I also think you end up with skinnier interfaces and
"simpler" (cleaner?) syntax.

(Again, all this comes at a price -- you don't have
the same sort of control that you do when the
*mechanisms* are "exported" in a library... that you
could potentially *modify*)

As to the creators' reasons... <shrug> you would have
to ask them (Pike, Dorward, Winterbottom)
 
B

Ben Pfaff

Don Y said:
It elevates threads to first-class objects. It recognizes
that programs are more "collections of threads" than "monolithic,
single-threaded processes" that have to *struggle* to
CO-operate.

That is a nice statement of principles, but it's hard for me to
imagine what practical effect it would have on threaded C
programs. Do you have an example to propose?
Moving things into the language also changes who is
responsible for the implementation and performance of
the feature. In Limbo, the "compiler"/runtime VM handle
ALL of the mechanisms associated with these features.
it means that those features are accessible to your
code on any platform that can support Limbo programs.
(double edged sword... if you don't like how they do
it, you can't just swap out that aspect like you can with
a separate library).

Threading is intentionally an optional feature for C
implementations, because C is supposed to work on platforms that
do not or cannot support threads.
 
J

James Kuyper

Hi Keith,

On 3/13/2012 5:59 AM, Keith Thompson wrote: ....

OK. But that's just another standard library. The language
itself doesn't include those provisions.

It's not just another standard library. The specifications for the
language itself required numerous modifications in order for it to be
feasible to define the behavior of that library in the way it has been
defined. See section 5.1.2.4 "Multi-threaded executions and data races",
and section 6.7.2.4 "Atomic type specifiers". There's new pre-defined
identifiers __SDTC_NO_ATOMICS__ and __STDC_NO_THREADS__. There's new
concepts like "thread storage duration", and new keywords like
_Thread_local. Search sections 1-6 for words like "atomic", or "thread",
or "sequenced" to see further examples of what I'm referring to.
 
K

Keith Thompson

Threading is intentionally an optional feature for C
implementations, because C is supposed to work on platforms that
do not or cannot support threads.

<threads.h>, like most of the standard library, is specified only for
hosted implementations. Certainly most mainstream hosted platforms
support threading; I'm skeptical that there are any hosted systems
that are likely to support C2011 that *can't* support threads.

I think <threads.h> was made optional mostly to ease the burden
on implementers, and encourage them to develop conforming
implementations when they otherwise wouldn't.
 
K

Kaz Kylheku

If you are interested in knowing what the container's library is about
look at

http://code.google.com/p/ccl/

There you will find the whole containers library for C, the
documentation, and the source code.

"containers" means lists (single/double linked), hash-tables,
flexible arrays, buffers, circular buffers, trees, and several others.

My proposal is to standardize this in a similar way to C++
stl and allow you to use lists and hashtables in your C code without
reinventing the wheel.

I made a decent little library for hashing, trees and lists more than fifteen
years ago.

http://www.kylheku.com/~kaz/kazlib.html

Fairly widely used and well-tested. E.g. lookie here:

http://git.kernel.org/?p=fs/ext2/e2fsprogs.git;f=e2fsck/dict.c;hb=HEAD

I wrote a standard-like document (almost a pardody of such things) describing
everything to a ridiculous detail.

Another useful thing are the BSD macros "queue.h" et cetera.

We have quasi-standard things for containers in the C culture which, in
practical terms is as good (if not better) as having them in the language.

Those who reinvent wheels just don't know how to use Google.
 
J

Jens Gustedt

Am 03/13/2012 02:20 PM, schrieb Ben Bacarisse:
Congratulations. Can you provide a link or document number or something
so that the progress can be tracked?

yeah, would be nice if there would be a page where one could check for
the progress on that national committee. Last time I search I didn't
find any sensible information (but a phone number I guess) on the web

Jens
 
D

Don Y

Hi Ben,
That is a nice statement of principles, but it's hard for me to
imagine what practical effect it would have on threaded C
programs. Do you have an example to propose?

See below.
Threading is intentionally an optional feature for C
implementations, because C is supposed to work on platforms that
do not or cannot support threads.

Yes. This goes to my comment (elsewhere) about the "attitude"
(philosophy?) that C presents vs. other languages. E.g.,
C exposes lots of fine-grained detail and gives you a great
deal of control over what's happening "now".

By contrast, Limbo (and its Inferno base) *hides* lots of
detail from the developer. E.g., (apologies for any typos)

greetings(
surname: string,
children: list of (string, int)
) {
sys = load Sys Sys->PATH;

sys->print("Season's Greetings from the %s family!\n"
surname);
while (children != nil) {
(firstname, age) := hd children;
fullname := firstname + " " + surname;
sys->print("%s (%d years old)\n" firstname, age);
children = tl children;
}
}

Note that the only function invoked in the above is
"print" from the "Sys" module. The string support, list
support, tuples, etc. are all part of the language itself.
(so there is a garbage collector hiding behind the scenes
as well!)

The routine could just as easily have delivered its
"output" to a *channel" (communication mechanism):

greetings(
surname: string,
children: list of (string, int)
output: chan of string
) {
output <-= "Season's Greetings from the "
+ surname + " family!\n";

while (children != nil) {
(firstname, age) := hd children;
description := firstname + " " + surname;
description = description
+ " (" + age + " years old)";
output <-= fullname;
children = tl children;
}
}

Some other thread could similarly watch a channel and
pass anything inbound directly to the "print" device:

logging(
input: chan of string
) {
sys = load Sys Sys->PATH;

while (FOREVER) {
text :=<- input;
sys->print("%s\n", text)
}
}

This channel can be shared between these two threads:

job(surname: string,
children: list of (string, int)
) {
pipe: channel of string;

spawn logging(pipe);
spawn greetings(surname, children, pipe)
...
}

Any of those threads can be located on another "node"/machine;
the communications can be transparently encrypted, etc.

You can conceivably push *modules* (i.e., the "Sys"
executable) across a pipe and execute them on the other
remote end, etc.

But, like I said, you lose lots of fine grained control over
what is happening -- and *when*. In return, you don't
worry about silly details that are closely tied to an
*implementation* (e.g., when do you invoke the garbage
collector? Did you remember to NUL terminate your
"strings"? Who cleans up the resources used by a
thread when the thread exits -- stack, string space, etc.)
 
B

Ben Pfaff

Don Y said:
Yes. This goes to my comment (elsewhere) about the "attitude"
(philosophy?) that C presents vs. other languages. E.g.,
C exposes lots of fine-grained detail and gives you a great
deal of control over what's happening "now".

By contrast, Limbo (and its Inferno base) *hides* lots of
detail from the developer. E.g., (apologies for any typos)

The difference, at least in the way that you present it, goes far
beyond threading, so I wonder how applying the "Limbo philosophy"
to only a single feature of C (threading) would be useful in C.
 
D

Don Y

Hi James,

On 03/13/2012 04:49 PM, Don Y wrote:

It would have been more helpful if your example had involved, as
specified, a "threaded C program".

That's left as an exercise for one of the language lawyers! :>
(Note that you and keith are the ones who raised the topic of C's
support for these features)

Actually would be interesting to compare the size/complexity
of the two approaches. Anyone with a *functional* knowledge
of the 2011 draft want to take a stab at it?
 
D

Don Y

Hi Ben,


[examples elided]
The difference, at least in the way that you present it, goes far
beyond threading, so I wonder how applying the "Limbo philosophy"
to only a single feature of C (threading) would be useful in C.

You can elide the use of tuples, lists, strings, etc. and
concoct a more trivial example. *But*, with threading,
you still need communications (between threads), resource
management (for the spawned threads creation/termination),
etc.

I suspect that if you trim the Limbo example down to passing
a const int back and forth between two threads (I originally
considered sending "ping" from A to B and having B reply with
"pong", etc.) you could come up with a similar implementation
in C that does the exact same thing -- and see how you would
approach it. From there, think about how you would pass
larger objects, communicate between multiple threads, implement
synchronization primitives, etc.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top