Has thought been given given to a cleaned up C? Possibly called C+.

  • Thread starter Casey Hawthorne
  • Start date
I

Ian Collins

Preprocessor macros would be an unfortunate edge case, but IMHO
not a fatal one. For function-like macros, you can use the inline
keyword on a function to get namespaces. For constants, you could
use an enum.

What other corner cases can you think of?

Feeling C++-ey would be simple enough without any standard library
changes:

namespace std {
#include<stdio.h>
#include<stdlib.h>
}

And boom, you've got std::malloc() and std::puts() and all that.

Though now that I think about it, using that idea would probably
cause a fair bit of confusion for linkers.

Unless there was a standard for mangled names in C. Namespaces require
name mangling.
 
T

Thomas Richter

Ian said:
Very few languages are, C++ certainly isn't.

The argument goes IMHO into the wrong direction. To make containers
really powerful and safe, you need some kind of generics support, and
some type of mechanism to hide the implementation behind the interface.
C provides only relatively weak measures for that. I afraid the result
would be of rather limited use.

So long,
Thomas
 
T

Thomas Richter

Flash said:
Yes. However, in C you at least know that + *is* addition.

Actually, it isn't. For floating point, it is a limited precision
version of addition. For integers, it is only addition in a limited
range and behaves undefined outside of that range, and for unsigned, it
is the addition in a ring. (-;

Thus, we have three different versions of addition already, overloaded
on the same symbol, and for constructs that contain two different types
of numbers, the resulting operation is often not easy to follow. Type
promotions in C are a pretty dark chapter, and pretty easy to get wrong
as well.
My experience is that operator overloading leads to confusion for
experienced users.

In most cases, it should be avoided. The C++ overloading of >> and <<
for IO operations is definitely a pretty bad idea. There are rare cases
where it does make sense because the operator has a very natural meaning
(vector addition, matrix multiplication). It is a feature that should be
used with care. But >> and << for I/O is not one of them.

So long,
Thomas
 
D

Dr Malcolm McLean

I'm not sure that the compiler is the biggest concern here. More
to help out the people reading the code, who might see

  a * b + c * a

and think, oh, I can simplify that:

  a * (b + c)
Then you've got to consider whether the operators are associative.
Technically the built-in C operators are not, but it seldom matters.
The problem is in a sense worse than with commutativity, because if an
operator is not commutative then reversing the operands is likely to
produce a wildly different result. If the operators are not
associative, however, that's often because of the limitations of
machine representation rather than mathematical fundamentals. So you
could get slight differences in values which could lead to all sorts
of subtle and hard to trace problems.
 
J

jacob navia

Seebs a écrit :
I suspect Jacob is relying somewhat on the distinction between "language"
and "library" here.

The standard makes this distinction, I did not invented it.
A standard container library does not make the "language"
part of the language more complicated. (It is a bug in English that the C
language has two components, language and library. Library functions are not
part of the language part of the language, but the library as a whole is
part of the language. This should be clear and simple to understand, and is
not because English is defective. Please file a defect report with the love
child of some random Norman/Saxon pairing in the 1500s.)

The issue, as I see it is:

Insofar as no complexity is really added, neither is any functionality; you
can't use the container library without knowing what it does.

Insofar as functionality is added, it creates additional complexity.

The designs I've seen for Jacob's container library, while reasonably
flexible, are IMHO too top-heavy for the sorts of things that normally make
it into the C standard library. They're very clearly influenced by things
learned during the development of C++ and the STL, but those things, I think,
make less sense in a pure C environment.

I do not think so. Modern C software design can be quite sophisticated.
Why should we stay at the level of, say, strcpy?

"top heavy"?

The goal was to have an extremely flexible design that can accomodate
further enhancements without making old code obsolete. True, for a
simple linked list it looks too heavy, but the advantages of a standard
container is that it makes all programs *compatible* by allowing data
interchange in a standard way.

Of course if you just want a simple linked list it is top heavy. Writing
a red/black tree implementation or a dictionary is not the same however,
and even if the syntax looks forbidding at first sight thebgains come
with regular use.
I guess the question is:

Were this part of a future spec, would we get more or fewer complaints from
confused newbies? I'd guess more. That, to me, means it is increasing
complexity.

-s

I do not think that newbies are the problem here. It is rather the
oldbies ( :) ) like me that have this FED UP feeling when they start
coding the 100th linked list implementation...
 
D

Dr Malcolm McLean

Really you need to be able to define new operators, even if this is just
syntactic sugar for functions.  Give them all the same precedence and
off you go.
Exponentiation is the obvious basic operation that lacks an operator.
The convention is Chinese hat. Unfortunately that has been used for
XOR. So two Chinese hats. However that looks too much like logical
XOR.
So maybe two asterisks. This could be made to work. However asterisks
are already used for both multiplication and pointer derferencing. It
might be hard to read. Worse, it might be easy to read when playing
about with it, hard to read when you get into subtle, speed-critical,
complex areas of real code.
 
N

Nick

Dr Malcolm McLean said:
Exponentiation is the obvious basic operation that lacks an operator.
The convention is Chinese hat. Unfortunately that has been used for
XOR. So two Chinese hats. However that looks too much like logical
XOR.
So maybe two asterisks. This could be made to work. However asterisks
are already used for both multiplication and pointer derferencing. It
might be hard to read. Worse, it might be easy to read when playing
about with it, hard to read when you get into subtle, speed-critical,
complex areas of real code.

a = b pow c;

That's the sort of thing I was thinking of.
 
J

jacob navia

Richard Bos a écrit :
I'm sorry, but... did you _really_ just write something to the tune of:
"C is a simple language. Adding a large, complicated gathering of data
structures to it won't make it any bigger and more complicated"?

Because if you did, I'd like to know what the French government thinks
of the stuff you imported from some "coffee shop" in Amsterdam; and if
you didn't, I'd like to know how you can possibly think that any
flexible container library that could be good enough to use by the
majority of C users could ever _not_ be too large, complicated, and
highly over-specced to use.

Richard

The container library is around 80K (32 bit machines)

In that space I have
o lists (double/sinlgle linked)
o bitstrings
o AVL trees
o Red/Black trees
o Dictionary (Hash tables)
o Flexible arrays.

Is 80K "too large" ???

Over-specced?

You have remained silent (as all other "regs") in the discussions
about the library here.

It is very easy. You limit yourself to piss at other people's proposals
without ever proposing anything.
 
I

Ike Naar

There is already an operator for logical a xor b:
``a != b'' if a and b are known to be 0 or 1, or otherwise ``!a != !b''.
a = b pow c;

That's the sort of thing I was thinking of.

But in that case, ``pow'' would probably have to be a keyword, and then
it could not be used as a fuction name anymore.

It would be more in the spirit of C to use ``a = b static c;''
 
I

Ian Collins

The argument goes IMHO into the wrong direction. To make containers
really powerful and safe, you need some kind of generics support, and
some type of mechanism to hide the implementation behind the interface.
C provides only relatively weak measures for that. I afraid the result
would be of rather limited use.

I agree. That is one reason why containers are part of the C++ standard
library and not the C one. Containers were a bodge in Java before
generics were bolted onto that language.
 
A

Alan Curry

|
|> jacob navia wrote:
|> >
|> > a+b <--> b+a
|> > a*b <--> b*a
|>
|> What do you have against a-b and a/b?
|
|And against vector multiplication?

scalar*vector follows the rule just fine. And vector*vector as long as you
mean dot product. Cross product is exactly where you have gone too far if you
overload the "*" operator for it.

Matrix multiplication is just crazy. I don't see why the mathematicians
insist on calling it "multiplication" at all.
 
J

jacob navia

Thomas Richter a écrit :
In most cases, it should be avoided. The C++ overloading of >> and <<
for IO operations is definitely a pretty bad idea. There are rare cases
where it does make sense because the operator has a very natural meaning
(vector addition, matrix multiplication). It is a feature that should be
used with care. But >> and << for I/O is not one of them.

The main applications are
(1) numeric.
I added 352 bit floats and bignums to lcc-win using this feature

(2) Array access
This makes counted strings and counted buffers as easy to use as
normal arrays. Instead of

idxCountedStr(str,5)

you write

str[5]

Operations with other objects can be meaningful but you have to
take special care not to do constructs like addition for strings,
or multiplication for strings
a= "abc"
a*4 --> "abcabcabcabc"

That looks very clever, but it leads to incomprehesible code.
 
I

Ian Collins

Actually, it isn't. For floating point, it is a limited precision
version of addition. For integers, it is only addition in a limited
range and behaves undefined outside of that range, and for unsigned, it
is the addition in a ring. (-;

Thus, we have three different versions of addition already, overloaded
on the same symbol, and for constructs that contain two different types
of numbers, the resulting operation is often not easy to follow. Type
promotions in C are a pretty dark chapter, and pretty easy to get wrong
as well.


In most cases, it should be avoided. The C++ overloading of >> and <<
for IO operations is definitely a pretty bad idea. There are rare cases
where it does make sense because the operator has a very natural meaning
(vector addition, matrix multiplication). It is a feature that should be
used with care. But >> and << for I/O is not one of them.

Don't forget there are other operators along with the arithmetic
operators. Frequently used operators in the C++ world include [], ->
and () (for function objects).
 
A

Andrew Poelstra

There is already an operator for logical a xor b:
``a != b'' if a and b are known to be 0 or 1, or otherwise ``!a != !b''.

Oh :)
But in that case, ``pow'' would probably have to be a keyword, and then
it could not be used as a fuction name anymore.

It would be more in the spirit of C to use ``a = b static c;''

If there was an operator keyword (or something) that would declare
a one-or-two parameter function to take its arguments in that style,
there would be no need for extra keywords.

Then you could have

a = b pow c;

as well as

w = u dot v;
iA = inv A;
At = transvert A;
name = fname cat lname;

Plus all manner of abuses, of course:

plane = truck plus wings;
mule = horse bang donkey;
 
S

Seebs

Thus, we have three different versions of addition already, overloaded
on the same symbol, and for constructs that contain two different types
of numbers, the resulting operation is often not easy to follow. Type
promotions in C are a pretty dark chapter, and pretty easy to get wrong
as well.

I disagree. We have one version of addition, which happens to be influenced
by characteristics that each type consistently has for all operations you
can perform on it.

Addition means the same thing for both signed and unsigned values, however,
their behaviors when *any* operation generates something out of range are
different. Similarly, it means the same thing for both integer and floating
point values, but their behaviors in storing values are different.

-s
 
A

Andrew Poelstra

The container library is around 80K (32 bit machines)

In that space I have
o lists (double/sinlgle linked)
o bitstrings
o AVL trees
o Red/Black trees
o Dictionary (Hash tables)
o Flexible arrays.

Is 80K "too large" ???

Over-specced?

You have remained silent (as all other "regs") in the discussions
about the library here.

It is very easy. You limit yourself to piss at other people's proposals
without ever proposing anything.

Is any or all of your library usably complete (and available)
right now?
 
F

Flash Gordon

jacob said:
Nick Keighley a écrit :

For instance:

A full blown IDE under 1MB

The smallest C++ program I have is 11K. So lets assume that 1 byte is my
program and the rest is the overheads of using C++. Based on that, your
IDE would still be approximately 11MB if you did the minimum changes so
that it would build correctly with a C++ compiler (renaming any
variables named "new" etc), your IDE would *still* only be 11.01MB!
A fast floating point package with 352 bits precision, in C+asm. The
core in assembler, the full C math library plus many other
special functions in C. Size: 204K.

I like C. The problem with modern softawre is BLOAT. Too much
features you do not need, too much inefficiency, the
contrary of "small is beautiful".

You don't need to use the facilities you don't want to use. I don't
think that under 11K of overhead is really that significant on a PC
these days. If I was programming for an embedded device the
considerations would be different.
Well, I guess its a philosophical question anyway.

It's more a question of how you choose to use the language.
 
A

Andrew Poelstra

Matrix multiplication is just crazy. I don't see why the mathematicians
insist on calling it "multiplication" at all.

Because English supports operator overloading, and these
decisions were made long before we realized the dangers.
 
E

Eric Sosman

[...]
If there was an operator keyword (or something) that would declare
a one-or-two parameter function to take its arguments in that style,
there would be no need for extra keywords.

Then you could have

a = b pow c;

"Hello, world!\n" fputs stdout;
 

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
473,774
Messages
2,569,598
Members
45,144
Latest member
KetoBaseReviews
Top