How would you design C's replacement?

M

Malcolm McLean

בת×ריך ×™×•× ×©× ×™,30 ב×פריל 2012 17:09:07 UTC+1, מ×ת James Kuyper:
On 04/30/2012 11:22 AM, Malcolm McLean wrote:
...

No one has that "weight". If it needs to be forced on people - if it
can't gain acceptance except by reason of being mandated by a
sufficiently powerful authority - it can't be good enough to justify
mandating it.
It doesn't really matter what you call a 3d point. Even a novice programmer, provided he was sane, could come up with a perfectly good typedef or convention, which could be used worldwide with no harm.
In this case, it is a problem of designated authority.
 
J

Jens Gustedt

Am 05/01/2012 07:43 AM, schrieb Ian Collins:
In addition to my other post concerning C++'s auto,

a nice feature, but reusing an existing keyword is a no-go, it is
simple as this
there are a number
of other additions to C++11 that would benefit in C without breaking
existing code, some examples

Scoped and strongly typed enums[1], embedded compilers often enable the
type of an enum to be selected, so may as well standardise.
yes!

Constant expressions[2] would extend the usefulness of const.

there would be a less intrusive modification to C that could achieve
similar goal: register const declarations. Just

- make it constraint violations not to initialize them
- allow them at places where compile time constant expressions are
allowed
- allow them in global scope
Alignment[3] another extension that may well be of more use in C (giving
its dominance in drivers and embedded).

this one already made it into C11

Jens
 
I

Ian Collins

Am 05/01/2012 07:43 AM, schrieb Ian Collins:

a nice feature, but reusing an existing keyword is a no-go, it is
simple as this

See the last couple of paragraphs of this section:

http://www2.research.att.com/~bs/C++0xFAQ.html#auto
Constant expressions[2] would extend the usefulness of const.

there would be a less intrusive modification to C that could achieve
similar goal: register const declarations. Just

- make it constraint violations not to initialize them
- allow them at places where compile time constant expressions are
allowed
- allow them in global scope

That's pretty much the "old" C++ usage of const, still a big improvement
over C.
Alignment[3] another extension that may well be of more use in C (giving
its dominance in drivers and embedded).

this one already made it into C11

Ah good, I missed that!
 
J

Jens Gustedt

Am 05/01/2012 10:21 AM, schrieb Ian Collins:
See the last couple of paragraphs of this section:

http://www2.research.att.com/~bs/C++0xFAQ.html#auto

yes, I know all of that

first, I think that this will not easily convince the C committee

second, this is all useless complication, why the hell they didn't
invent another keyword, something like C usually does "_Auto" if it
must or even more descriptive "_Autotype"?

third, I am probably a rare animal, but I occasionally use that in
macros for which I want to be sure that they end up in function scope
Constant expressions[2] would extend the usefulness of const.

there would be a less intrusive modification to C that could achieve
similar goal: register const declarations. Just

- make it constraint violations not to initialize them
- allow them at places where compile time constant expressions are
allowed
- allow them in global scope

That's pretty much the "old" C++ usage of const,

not quite, such an "rvalue" wouldn't have an address

I am also not sure if it would be the same for composite types. C++'s
rules for initializing global const qualified variables always scared
me. Wasn't it that you only could initialize integer constants at the
point of declaration, and other types (even floating point) hat to be
initialized/constructed at the point of definition/instantiation.
still a big improvement
over C.

Jens
 
I

Ian Collins

Am 05/01/2012 10:21 AM, schrieb Ian Collins:

yes, I know all of that

first, I think that this will not easily convince the C committee

second, this is all useless complication, why the hell they didn't
invent another keyword, something like C usually does "_Auto" if it
must or even more descriptive "_Autotype"?

Maybe the C++ committee has a more echo-friendly recycling policy! They
definitely have better aesthetic sense.
third, I am probably a rare animal, but I occasionally use that in
macros for which I want to be sure that they end up in function scope

I've never come across that use auto before. Care to enlighten me?
Constant expressions[2] would extend the usefulness of const.

there would be a less intrusive modification to C that could achieve
similar goal: register const declarations. Just

- make it constraint violations not to initialize them
- allow them at places where compile time constant expressions are
allowed
- allow them in global scope

That's pretty much the "old" C++ usage of const,

not quite, such an "rvalue" wouldn't have an address

Hence "pretty much"!
I am also not sure if it would be the same for composite types. C++'s
rules for initializing global const qualified variables always scared
me. Wasn't it that you only could initialize integer constants at the
point of declaration, and other types (even floating point) hat to be
initialized/constructed at the point of definition/instantiation.

I think you are confusing regular constants with const static members of
classes.
 
R

Rui Maciel

Ben said:
No language is perfect and so anyone assigning the tasks of
fixing "all [C's] problems and shortcomings" is setting an
impossible goal.

That didn't dissuade sompe people from investing their time designing what
they defined as "a better C", and a number of them managed quite well to
succeed in developing good programming languages.


Rui Maciel
 
R

Rui Maciel

Ben said:
Jacob, I'm criticizing the hypothetical assignment given by Rui,
not anything you wrote.

It was intended to get opinions from C programmers on how the C programming
language could be improved. Why should that be a target for criticism?


Rui Maciel
 
R

Rui Maciel

Keith said:
But not persuasively, IMHO.

C is at a lower semantic level than a lot of other languages.
But the major difference between C and assembly language is that
an assembly program specifies CPU instructions, while a C program
specifies run-time behavior.

That's a huge distinction, with assembly languages on one side,
and C, C++, Ada, Python, APL, and Intercal firmly on the other.

That's true. Nonetheless, there are languages out there who are referred to
as high level assembly languages which also employ some abstractions that,
at least in some aspects, don't make their abstraction level much lower than
C's.

Another issue we might consider is that if we were given the task of
designing an assembly language which should be able to generate code for
multiple architectures, I suspect we would end up with a language which, in
terms of features, wouldn't be much different than C's core language.


Rui Maciel
 
R

Rui Maciel

That the person assigning the task get their head examined. :)

Why? Do you believe that the C programming language can't be improved,
particularly when there isn't a need to preserve backward compatibility?


Rui Maciel
 
R

Rui Maciel

BGB said:
this is more of an OS or tools issue than a language issue though.

Quite true.

I suspect that the way the C programming language handles "packages" can't
be made any simpler than it already is. The library headers are stored
somewhere (anywhere) in the file system, and so are the object files, if
there are any. Then, to be able to build our software with them, we only
need to configure the compiler to search for those header and object files
where we left them.

I suspect that this is only an issue when automatic build systems make this
to be harder than it is, and needs to be.


Rui Maciel
 
K

Keith Thompson

Rui Maciel said:
Another issue we might consider is that if we were given the task of
designing an assembly language which should be able to generate code for
multiple architectures, I suspect we would end up with a language which, in
terms of features, wouldn't be much different than C's core language.

And it wouldn't be an assembly language.
 
R

Rui Maciel

Leo said:

If that was true, and it wasn't in fact possible to get any improvement in
any project intended to fix the shortcomings of a previous one, then
nowadays no programming language would be better than the very first
incantation of Fortran.


Rui Maciel
 
B

BartC

Kaz Kylheku said:
The problem with any major changes to C's type declaration syntax is that
they break "declaration follows use".

So what? That was a crazy idea that never really worked.

A lot of people *do* have trouble with C's type-declarations; they *do* need
to employ an algorithm to understand a complex one; many have to resort to
layers of typedefs to make them simpler to read and write; and some decided
to write the Cdecl utility to help read and write them! To me, that
suggests that there is an issue.

And declaration-follows-use breaks down in many cases; inside casts for
example, where the absence of a name from the type-spec makes it even harder
to know where to start; you just end up with a mess of parentheses and
asterisks.

How does it work here:

int a; a

It seems that any type-spec is broken down into two parts: the resultant
type (eg. 'int') and anything else (ie. mix of pointer, array, function
signtature). It is this 'anything else' that needs to be literally wrapped
around individual names, resulting in this confusing syntax:

int* a, b, c;

Where you do want all names with the same type, you have to duplicate the
type-spec:

int *a[10], *b[10], *c[10];

or start creating typedefs. (BTW declaration-follows-use also breaks down
when you try and write *a[10]...)
A declarator like (*p[3])(double) gives us a p which can actually be used
by
means of the syntax (*p[0])(3.0).

(Your example gives an error in Cdecl unless something like 'int' is added
in front. See, I didn't even know that from looking!)
If you change how it is declared, but don't make a parallel change to the
expression syntax then you still have (*p[0])(3.0) /and/ the new syntax
which
is inconsistent with this.

Part of the problem is that C's dereference syntax is also back-to-front:
*p[0] instead of p[0]*.

But, if you have to design a new language that was fully-typed like C, would
you still use this type syntax or not?

(I would write your example, in another language, as follows (where 'real'
means double, and ^ means dereference):

[3]ref function(real)int p

p[1]^(3.0)

This was written directly using Cdecl's output as a guide: "declare p as
array 3 of pointer to function (double) returning int". The only difference
is I put "p" at the end rather than at the start.)
 
B

BartC

Ian Collins said:
On 05/ 1/12 11:24 AM, BartC wrote:
More often than not there's something wrong with the programmer who
conjurers up such a convoluted declaration! Seriously, 99.9% of the time
complex type declarations are unnecessary.

But when it is, it tends to be crucial.
One simplification that would help not break (much!) code would be to
adopt C++'s reuse of "auto".

C++ is so complicated, that it's probably necessary. (In fact, when you
spend even a short time looking at C++ and at *its* quirks, you start to
think that perhaps there's nothing much wrong with C after all!)
 
R

Rui Maciel

Rui said:
If you were given the task to design a replacement for the C programming
language intended to fix all its problems and shortcomings, what would you
propopose?

Here are a couple of suggestions:

- namespaces
They aren't necessarily required to write software, but they are handy and,
depending on how they are implemented, they may be able to solve a
considerable number of problems. Let's consider a namespace implementation
which provides a way for a programmer to specify a prefix to be used
implicitly in declarations and definitions, and that lets programmers
specify a set of identifier prefixes that are taken into accoun when parsing
identifiers. For example, consider the following declaration:

<code>
namespace foo
{
int bar(void);
}
</code>

That would be equivalent to the following declaration:
<code>
int foo_bar(void);
</code>


then, with this declaration, the following code would be valid:
<code>
int main(void)
{
using namespace foo;
bar(void);

return 0;
}
</code>

....which would be equivalent to:
<code>
int main(void)
{
foo_bar(void);

return 0;
}
</code>

Any ambiguity regarding the use of specific namespace prefixes would be
signaled as a compiler error. So, for example, the following code would
fail to compile:
<code>
namespace foo
{
int bar(void)
{
return some_constant;
}
}

namespace baz
{
int bar(void)
{
return some_other_constant;
}
}

int main(void)
{
using namespace foo, baz;
foo_bar(void); // good
baz_bar(void); // also good
bar(void); // compiler error: ambiguous identifier

return 0;
}
</code>

This, inadvertently, would provide a way to add polymorphism to C, in a way
which I believe is better than C11's generic. For example:

<code>
namespace foo
{
namespace int
{
bar(int); // this would define foo_int_bar(int)
}
namespace float
{
bar(float); // this would define foo_float_bar(float)
}

// The following would automatically include nested namespaces
using namespace int, float;
}

int main(void)
{
using namespace foo; // this includes foo_int and foo_float
bar(1); // calls foo_int_bar(int)
bar(1.0f); // calls foo_float_bar(float)
return 0;
}
</code>

Although the keyword "namespace" has been used in this example, any other
keyword would do. Maybe it would be better to use some other keyword such
as "prefix", to avoid any compatibility problem with C++'s namespaces.


- include the standard library in a dedicated namespace.
There are some issues affecting C's standard library, and yet there is no
way to fix them without breaking backward compatibility. One way to avoid
that mistake would be to include each version of the standard library in a
dedicated namespace that would explicitly reflect the standard version. For
example:

<code>
#include <stdio.h>
/* with C11, this could include c89/stdio.h, c99/stdio.h and c11/stdio.h,
each one reflecting the standard library as defined by each standard. Each
header would, in turn, enclose every definition in a dedicated namespace,
similar to:

namespace std
{
namespace c89
{
// ...
}
namespace c99
{
// ...
}
namespace c11
{
// ...
}
}
*/

int main(void)
{
using namespace std; // in a C11 implementation this would
actually include namespace std and std_c11

char *buffer;
// some stuff happens
gets(buffer); // oops, compiler error. There is no such
thing as a gets() in C11's standard library.
std_c99_gets(buffer); // but this function would be defined
c99_gets(buffer); // this would also be ok

return 0;
}
</code>



Rui Maciel
 
R

Rui Maciel

Keith said:
And it wouldn't be an assembly language.

Discussing whether such a language could be considered an high level
assembly language or not would essentially be the same as discussing whether
a particular shade of grey could be considered light or dark grey.


Rui Maciel
 
J

James Kuyper

On 05/01/2012 03:17 AM, Keith Thompson wrote:
....
If we're trying to come up with something better than #include, I'd
rather create a new mechanism that isn't part of the preprocess, and
doesn't look like it is (#pragma).

For example, this:

#include <stdio.h>

could be replaced by:

import stdio;

This would make all the declarations in the stdio "module" visible; it
would be up to the implementation to determine how to do that. There's
no implication that "import" performs a textual replacement.

That makes sense in a new language where preprocessing doesn't exist, or
at least is not needed to implement the standard library modules.
Otherwise, it's rather problematic.
 
J

James Kuyper

Am 05/01/2012 07:43 AM, schrieb Ian Collins:

a nice feature, but reusing an existing keyword is a no-go, it is
simple as this

No, it is not that simple. Backwards compatibility is an important goal,
but it's only one of the goals the committee needs to take into
consideration. While auto technically is a C keyword, it is never
needed, and therefore is almost never used; as a practical matter the
only sense in which it is a keyword is that it's not available for use
as a user-defined identifier. As a result, there's essentially no
backwards compatibility issue. What little code there is that currently
does use 'auto' would mostly become easily identified syntax errors
under the proposed new meaning.
 
J

James Kuyper

I've never come across that use auto before. Care to enlighten me?

"function scope" is the wrong phrase; statement labels are the only kind
of identifier which can have function scope (6.2.1p3). What he means is
called "block scope" (6.2.1p4).

What he's referring to is the fact that the auto keyword is not
meaningful, and is therefore disallowed, in external declarations (6.9p2).
 

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

No members online now.

Forum statistics

Threads
474,083
Messages
2,570,591
Members
47,212
Latest member
RobynWiley

Latest Threads

Top