# The D Programming Language (was: Still more new operators)

1213 views

### Dave Sill

Feb 7, 1988, 2:29:25 PM2/7/88
to
>Some years ago I invented the hypothetical notation "e1 ,, e2", which would be
>like the comma operator in that it evaluates its left operand before its
>right operand, but (unlike comma) the result would be the value of the left
>operand. Look what this buys us:
> a,, a=b /* displacement operator, like a :=:= b */
> a=(b,, b=a) /* a simple swap */
> x,, ++x /* same as x++; but generalizable */
> free(stack,, stack=stack->next) /* pop stack */
> stack->value,, pop(stack) /* pop and return stacked value */

I like it. Nice and general, fills a gap missing in C. It's not C,
but it could be D (it *should* be D, not P (pee?)).

Maybe we should start a new newsgroup/mailing-list for the discussion
of such things. It seems like a lot of the current discussion here is
about things that will never make it into ANSI C such as a power
operator, `noalias' :-) et cetera. Sure would improve the S/N ratio
for those interested only in C.

=========
The opinions expressed above are mine.

"The limits of my language mean the limits of my world."
-- Ludwig Wittgenstein

### Bob Rose

Feb 7, 1988, 7:17:40 PM2/7/88
to
In article <11...@brl-adm.ARPA>, ds...@NSWC-OAS.arpa (Dave Sill) writes:
> >Some years ago I invented the hypothetical notation "e1 ,, e2", which would be
> >like the comma operator in that it evaluates its left operand before its
> >right operand, but (unlike comma) the result would be the value of the left
> >operand. Look what this buys us:
> > a,, a=b /* displacement operator, like a :=:= b */
> > a=(b,, b=a) /* a simple swap */
> > x,, ++x /* same as x++; but generalizable */
> > free(stack,, stack=stack->next) /* pop stack */
> > stack->value,, pop(stack) /* pop and return stacked value */
>
> I like it. Nice and general, fills a gap missing in C. It's not C,
> but it could be D (it *should* be D, not P (pee?)).

But wait, we can do better. Why limit yourself to two operands? Let's
look at some other programming language (like Icon) and get the
correct operator.

The magic operator is

i(x1, x2, x3, ..., xn)

Looks like a function call eh? It's not. i is an integer in the
range from 1 to n and the operator produces the outcome of xi.

So a simple swap is

a = 1(b, b=a); /* much cleaner than ,, */

The the wonderful thing is it wont break any code. So everyone
write your ANSI rep now!!!! 8^)

BTW my vote for min and max is ?< and ?>. Also why not ?: that
produces it first operand if it is not zero else it produces it second
that why the getc macro becomes

#define getc(file) (*(file)++->char ?: _fillbuf(file))
/* note _fillbuf is smart enough to figure out if there was
a '\0' in the input stream or if it was actually at the
end of a buffer and of course the buffer size is BUFFSIZE + 1 */

-bob
--
Robert R. Rose
Northern Arizona University, Box 20023
Flagstaff, AZ 86011
.....!ihnp4!arizona!naucse!rrr

### David Keppel

Feb 7, 1988, 8:29:47 PM2/7/88
to
In article <11...@brl-adm.ARPA> ds...@NSWC-OAS.arpa (Dave Sill) writes:
>but it could be D (it *should* be D, not P (pee?)).
>
>Maybe we should start a new newsgroup/mailing-list for the discussion
>of such things. It seems like a lot of the current discussion here is
>about things that will never make it into ANSI C such as a power
>operator, `noalias' :-) et cetera. Sure would improve the S/N ratio
>for those interested only in C.

Sounds good to me.

I've been collecting interesting ideas about ``D'' off the net for a while.
If y'all would like to send me your 1 or two favorite "improvements" to
C to be incorporated in "D", I'll send you a summary in response.

Not that I intend to write D or P or whatever, but if somebody wants my

;-D on (Creativity is ... hard to define) Pardo

pa...@cs.washington.edu ..!ucbvax!uw-beaver!uw-june!pardo

### Sun ECD Software

Feb 9, 1988, 9:24:14 AM2/9/88
to

In article <11...@brl-adm.ARPA> ds...@NSWC-OAS.arpa (Dave Sill) writes:

>>Some years ago I invented the hypothetical notation "e1 ,, e2", which would be
>>like the comma operator in that it evaluates its left operand before its
>>right operand, but (unlike comma) the result would be the value of the left
>>operand. Look what this buys us:
>> a,, a=b /* displacement operator, like a :=:= b */
>> a=(b,, b=a) /* a simple swap */
>> x,, ++x /* same as x++; but generalizable */
>> free(stack,, stack=stack->next) /* pop stack */
>> stack->value,, pop(stack) /* pop and return stacked value */
>
>I like it. Nice and general, fills a gap missing in C. It's not C,
>but it could be D (it *should* be D, not P (pee?)).

Actually, the last project course at the late Wang Institute developed
a compiler and editor for the D language called Turbo-D. The D language
we used was taken from Dijkstra's guarded command language in his book
"A Discipline of Programming." For the simple swap you have shown, the
D syntax seemed to be much cleaner:
a,b := b,a

The language had some other features, including non-determinate selection
of guards for loops and conditional statements. The project was fun, the
language was useful, and the compiler was fast.

--
Gary F. Pollice | Remember the Wang Institute!!
Sun Microsystems | ARPAnet: gpol...@sun.com
Two Federal Street | UUCP: {decwrl,ihnp4,hplabs,ucbvax}!sun!gpollice
Billerica, MA 01821 | (617)671-0374

### Karl Heuer

Feb 9, 1988, 12:37:56 PM2/9/88
to
In article <5...@naucse.UUCP> r...@naucse.UUCP (Bob Rose ) writes:
>But wait, we can do better [than the proposed ",,"]. Why limit yourself to
>two operands?

> i(x1, x2, x3, ..., xn)
>[where 1 <= i <= n; the result is xi]

If `i' is constant, this is no more powerful than `(x1, ..., xi,, ...,, xn)'
which produces the same result. If `i' is allowed to be an arbitrary integral
expression (which I presume is the case in interpretive Icon), then it is
indeed more powerful but also more expensive to compute. Part of the beauty
of `,,' is that it has a cost comparable to `,'.

>[How about an operator] that produces it first operand if it is not zero else
>it produces it second

I considered proposing that the `||' operator be so extended (yes, this could
break existing code, but only if the operands are nonboolean AND the result is
being used in a nonboolean context). After thinking about it, though, I
decided that this is a step backwards. In programs that properly distinguish
between booleans and integers, there's nothing particularly magic about
`compare against zero'. Why should there be a special-purpose notation for
`e1 != 0 ? e1 : e2' but not for `e1 != -1 ? e1 : e2', say?

What you really want is the `it' pronoun, often used in PDL.
IF long-hairy-expression != 0
RETURN it
ELSE
RETURN other-expression
ENDIF

KWZH: We need a construct like `e1 UNLESS IT==0 INWHICHCASE e2'.
GCJ: Yes, and also `IFONTHEOTHERHAND ... WEMAYSAFELYASSUME'.

### Steve Wampler

Feb 9, 1988, 7:12:14 PM2/9/88
to
> In article <5...@naucse.UUCP> r...@naucse.UUCP (Bob Rose ) writes:
> >But wait, we can do better [than the proposed ",,"]. ...

> > i(x1, x2, x3, ..., xn)
> >[where 1 <= i <= n; the result is xi]
> ... If `i' is allowed to be an arbitrary integral

> expression (which I presume is the case in interpretive Icon), then it is
> indeed more powerful but also more expensive to compute. Part of the beauty
> of `,,' is that it has a cost comparable to `,'.

Actually, if 'i' is an arbitrary integral expression, it isn't that much more
expensive to implement than if it's a constant - most of the evaluation
mechanism is already in place in C (excuse me, 'D'). The only extra expense
over computing the value if 'i' is a constant is the cost of evaluating the
expression for 'i' and a simple transfer.

Sigh, let's just keep postnews happy here...
--
Steve Wampler
{....!arizona!naucse!sbw}

### David Collier-Brown

Feb 12, 1988, 10:30:45 AM2/12/88
to
In article <243@eagle_snax.UUCP> gpollice@eagle_snax.UUCP ( Sun ECD Software) writes:
| Actually, the last project course at the late Wang Institute developed
| a compiler and editor for the D language called Turbo-D. The D language
| we used was taken from Dijkstra's guarded command language in his book
| "A Discipline of Programming." ...

| The language had some other features, including non-determinate selection
| of guards for loops and conditional statements. The project was fun, the
| language was useful, and the compiler was fast.

Can you find out if it can be posted? I'd like a (V)HLL like the
Dijkstra language to write hard, complex but non-machine-related
things in. A (M)HLL like P would be nice too (:-)).

--dave
--
David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb
Geac Computers International Inc., | Computer Science loses its
350 Steelcase Road,Markham, Ontario, | memory (if not its mind)
CANADA, L3R 1B3 (416) 475-0525 x3279 | every 6 months.

### Karl Heuer

Feb 16, 1988, 6:14:35 PM2/16/88
to
In article <5...@naucse.UUCP> s...@naucse.UUCP (Steve Wampler) writes:
>> > i(x1, x2, x3, ..., xn)
>> >[where 1 <= i <= n; the result is xi]
>[Karl Heuer states that the generalization to nonconstant `i' is expensive]

>Actually, if 'i' is an arbitrary integral expression, it isn't that much more
>expensive to implement than if it's a constant - most of the evaluation
>mechanism is already in place in C (excuse me, 'D'). The only extra expense
>over computing the value if 'i' is a constant is the cost of evaluating the
>expression for 'i' and a simple transfer.

Sorry, I stand by my statement. If this `pick' operator is supposed to be a
generalization of my proposed `,,' operator, it must preserve the guarantee of
evaluating all of the `x?' operands, in left-to-right order. It sounds like
you're thinking of the expression equivalent of `switch', which would evaluate
exactly one of them. (Which may also be useful, but that's a separate topic.)

### Steve Wampler

Feb 17, 1988, 9:41:56 AM2/17/88
to
> In article <5...@naucse.UUCP> s...@naucse.UUCP (Steve Wampler) writes:
> >> > i(x1, x2, x3, ..., xn)
> >Actually, if 'i' is an arbitrary integral expression, it isn't that much more
> >expensive to implement than if it's a constant - most of the evaluation
> >expression for 'i' and a simple transfer.
> Sorry, I stand by my statement. If this `pick' operator is supposed to be a
> generalization of my proposed `,,' operator, it must preserve the guarantee of
> evaluating all of the `x?' operands, in left-to-right order. It sounds like
> you're thinking of the expression equivalent of `switch', which would evaluate
> exactly one of them. (Which may also be useful, but that's a separate topic.)

Actually, no. However, I wasn't thinking of this as an exact replacement
for the ',,' operator, just as something that does equivalent work. You
can evaluate all the operands and then fairly easily make an arbitrary one
of them available. Think of 'i(x1, x2, x3,..., xn)' as being analogous to
calling a function 'i' that returns its ith argument. Then think of ways
to avoid implementing 'i' as a function. I suppose that compared to the ',,'
operator, there is the overhead of verifying that 'i' evaluated to the
proper range, but that is really a cost of the extra generality, and can
be eliminated if 'i' is a constant.

Of course, the evaluation order for ',,' is well defined, while the
evaluation order (in 'C' at least) for 'i(...)' would match the evaluation
order for function calls, which is much messier. (In 'D', however....).

I think ',,' is an interesting operator, but I personnally prefer 'i(...)',
having used it extensively in Icon - it seems 'more natural' to me. To each
his own.

--
Steve Wampler
{....!arizona!naucse!sbw}

Feb 18, 1988, 1:46:38 PM2/18/88
to

Any serious effort to design a successor to C (which does not attempt to be
upward compatible) should first consider what should be taken out and/or
done differently. Adding new things is secondary.

The first thing I would remove is the automatic conversion of arrays to
pointers. This was an understandable mistake, but a mistake nevertheless.
Removing it clears the way for treating arrays as first class objects. (A
consequence of this change is that "a[b]" is no longer definable as
"*(a + b)". We still have that it is equivalent to "*(&a[0] + b)", but this
cannot, of course, be used as a definition.)

Second on the list is defaulting of variables. An undeclared variable
should be an error, not an int. Likewise for functions. I would favor
mandating ANSI-style function prototypes. (Except that the "f(void)"
construct would not be needed -- "f()" means a function with no arguments.)

Another thing that should go is the assumption that the unit of storage is
the byte. The base unit of storage is the bit, and sizeof should return the
number of bits in the object. This enables to treat objects smaller than a
byte as first class objects.

I would also like to do away with having control statements control single
statements. For example, instead of writing "if (foo) {stmt1; stmt2;}" I
would write "if (foo) stmt1; stmt2; end;". Likewise, I would rewrite the
"for" statement as "for <stmts> while (<exp>) next <stmts> do <stmts> end;".
The "while" and "do ... while" I would generalize to "loop <stmts> while
(<exp>) <stmts> end;". In keeping with the spirit of C, we avoid
superfluous words, and keep the ones we do use short.

With these changes, the {} statement delimiters become much less useful. I
would probably drop them, and add a "begin ... end;" construct for those
cases where a local declaration is desired.

Another shortcoming to be fixed is the automatic fallthrough for select
statements. The default should be exit the statement when a new case is
encountered, with an option to fall through. I don't much like the current
syntax, either. In any event, the syntax should include specifying multiple
values for a case (what is now accomplished by "case a: case b:").

To get even more radical -- with typedefs, enums, const declarations, and
(if we add them) inline functions, do we really need the pre-processor any
more? Some kind of include statement should be provided, of course. Any
decent compiler will optimize "const int foo = 1; if (foo) ... else ...
end;", so preprocessor conditional compilation is hardly necessary.

I would omit the automatic insertion of a null byte at the end of character
constants. If you want nul terminated strings, write the nul. If you want
strings with counts, the language should not get in your way.

I think I would also drop the convention that 0 is a null pointer. Make
"null" a keyword, representing a null pointer of any type.
--

Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108

### Karl Heuer

Feb 18, 1988, 3:47:20 PM2/18/88
to
In article <5...@naucse.UUCP> s...@naucse.UUCP (Steve Wampler) writes:
>>It sounds like you're thinking of the expression equivalent of `switch',
>>which would evaluate exactly one of [its right operands].

>
>Actually, no. However, I wasn't thinking of this as an exact replacement
>for the ',,' operator, just as something that does equivalent work. You
>can evaluate all the operands and then fairly easily make an arbitrary one
>of them available.

Yes, you can implement it as
(temp[1]=x1, temp[2]=x2, ..., temp[n]=xn, temp[i])
if you're willing to live with the space requirement. (This was noted in the
first draft of my earlier article, but I cut it before posting.)

>I suppose that ... there is the overhead of verifying that 'i' evaluated to
>the proper range ...

Actually, it would be well within "the spirit of C" to let an out-of-range
selector be an undefined condition. Then the verification can be omitted.

>Of course, the evaluation order for ',,' is well defined, while the
>evaluation order (in 'C' at least) for 'i(...)' would match the evaluation
>order for function calls, which is much messier.

And in private correspondence:
>Also, note that, in 'C' at least, the types of e1,...,en
>must match (this isn't true in Icon).

This is important. If we add this `pick' operator but not `,,' on the grounds
that the former can simulate the latter, we would have to assert that
(a) `pick' guarantees to evaluate its right operands left-to-right, and
(b) the right operands must all have the same type if the left operand is
nonconstant, but may be of varying types if the left operand is constant.

(a) is an arbitrary restriction that shouldn't apply to `pick' for the same
reason that it shouldn't apply to function calls (we should let the compiler
do whatever is the most efficient thing), and (b) is a kludge of the same
magnitude as the recently-proposed enhancement to "++" for non-lvalues.

It looks like the best solution is to add both operators! (After all, we're
talking about a hypothetical `D' language here.)

### Alan J Rosenthal

Feb 18, 1988, 10:24:04 PM2/18/88
to

In article <5...@naucse.UUCP> r...@naucse.UUCP (Bob Rose ) writes:
>>[How about an operator] that produces its first operand if it is not zero,
>>else it produces its second.

>I considered proposing that the `||' operator be so extended ...
>After thinking about it, though, I decided that this is a step backwards...

>Why should there be a special-purpose notation for `e1 != 0 ? e1 : e2' but
>not for `e1 != -1 ? e1 : e2', say?
>
>What you really want is the `it' pronoun, often used in PDL.
> IF long-hairy-expression != 0
> RETURN it
> ELSE
> RETURN other-expression
> ENDIF

An obvious (at least to me) way to extend C to provide this is using the
?: operator. e1 ? e2 : e3 compiles to something vaguely like:

calculate e1
jump-if-zero L1
calculate e2
jump-always L2
L1: calculate e3
L2: ...

so, something like "e1 ? : e3" could consistently compile to something like:

calculate e1
jump-if-zero L1
jump-always L2
L1: calculate e3
L2: ...

i.e. just missing the "calculate e2" line, corresponding to the absence
of code in this part of the expression. (yes yes, the two adjacent
jumps can be reduced to one jump.)

Obviously, this would not break any existing code as "e1 ? : e2" is
currently a syntax error. And I think this answers Karl Heuer's
question quoted above.

ajr
--
"noalias considered sailaon"

### Brian T. Schellenberger

Feb 19, 1988, 12:59:50 AM2/19/88
to
|> In article <5...@naucse.UUCP> r...@naucse.UUCP (Bob Rose ) writes:
|> >But wait, we can do better [than the proposed ",,"]. ...
|> > i(x1, x2, x3, ..., xn)
|> >[where 1 <= i <= n; the result is xi]
|> ... If `i' is allowed to be an arbitrary integral <problems?>

Actually, there is a much more natural and powerful way to handle this in D:
one of the nicer things about C is the way you can get letters out of strings
by doing things like:

"abcdefghijklmnopqrstuvwxyz"[letter]

Why not extend this and allow in-line arrays? This would allow the "choose"
operator to work as, for example:

array int {x1, x2, x3, ...}[i]

This of course means that "abc" is exactly the same as

array char {'a', 'b', 'c', '\0'}

. . . just another silly idea.
--
--Brian.
(Brian T. Schellenberger) ...!mcnc!rti!sas!bts

DISCLAIMER: Whereas Brian Schellenberger (hereinafter "the party of the first

### gary sarff

Feb 19, 1988, 2:09:29 PM2/19/88
to

I am interested in "alternative" computer languages, and the ICON computer
language has structures such as are being talked about here, for a general
pick (nth) operator, the exact syntax of <expr>(x1,x2...xn) is used.
<expr> can be an integer constant, an arithmetic expression, the name of
a function in which case the function will be called with all the xi's as
arguments. One can also use &'s instead of commas in which case expression
failure of an xi causes failure of the rest of the expressions and evaluation
halts there. All three <expr> types are handled uniformly, (ICON is written
in C) they all pass through the same C code since something like
2(a,b,c) can be looked at as a function named "2" that returns its second
argument, (but all of them get evaluated anyway).

--
Gary Sarff {uunet|ihnp4|philabs}!spies!argus!gsarff
To program is human, to debug is something best left to the gods.
"Spitbol?? You program in a language called Spitbol?"
The reason computer chips are so small is that computers don't eat much.

### Chris Torek

Feb 20, 1988, 9:16:40 AM2/20/88
to
In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
>Any serious effort to design a successor to C (which does not attempt to be
>upward compatible) should first consider what should be taken out and/or
>done differently. Adding new things is secondary.

Uh oh. A ray of sensibility on the net! :-)

Oddly enough (or perhaps given the impending Standard, it is not
so odd), I have been considering the same sort of thing myself.
For those who want to wade through details (such as they are), they
appear below.

One of the nicest things about the C language is what it does NOT
do. The language is small enough to learn and comprehend entirely
in a short time; the list of language oddities is not empty, but
is small (most of them appear below).

>The first thing I would remove is the automatic conversion of arrays to
>pointers.

I am not sure I would make this `first', but I agree. In fact, this
is a side effect of what I would do with aggregate types.

>Second on the list is defaulting of variables. An undeclared variable
>should be an error, not an int.

(An undeclared variable *is* an error, unless you claim `register i'
leaves `i' undeclared.)

>Likewise for functions.

>Another thing that should go is the assumption that the unit of storage is
>the byte.

structure bitfields are the wrong way to get at bits; in particular,
it would be nice to have arrays of bits. But the basic unit of
storage has a way of creeping into the rest of the language, no
matter how hard one attempts to keep them apart.

>I would also like to do away with having control statements control single
>statements. For example, instead of writing "if (foo) {stmt1; stmt2;}" I
>would write "if (foo) stmt1; stmt2; end;". Likewise, I would rewrite the
>"for" statement as "for <stmts> while (<exp>) next <stmts> do <stmts> end;".
>The "while" and "do ... while" I would generalize to "loop <stmts> while
>(<exp>) <stmts> end;".

I disagree with the details, but will note that some human factors
studies have shown (and I agree) that a paired `end' is better than
a single `end', e.g., `if e stmts endif', `while e stmts endwhile'.
On the other hand, other studies have shown that `noise words' inhibit

>Another shortcoming to be fixed is the automatic fallthrough for select
>statements.

agree

>To get even more radical -- with typedefs, enums, const declarations, and
>(if we add them) inline functions, do we really need the pre-processor any
>more?

Probably. Inline functions should most certainly be added; they
nearly obviate the need for macros.

>I would omit the automatic insertion of a null byte at the end of character
>constants. If you want nul terminated strings, write the nul. If you want
>strings with counts, the language should not get in your way.

A general aggregate constructor is necessary. A specific version of
one that constructs null-terminated strings might be declared in
<strings.h> (or its equivalent). I would like to be able to create
C-style arrays (blocks of memory) as easily as `real arrays' (with
dope vectors). If I could come up with some way of merging arrays
and structures/unions into a single `aggregate' type....

>I think I would also drop the convention that 0 is a null pointer. Make
>"null" a keyword, representing a null pointer of any type.

This would, at one stroke, eliminate half the confusion that plagues
comp.lang.c .... (about 1/3 :-) )

I think the following are important considerations:

- the language should be made as small as possible, but no smaller.

- we should assume that compilers for this language are going to
do a great deal of optimisation; in particular, they will optimise
across entire compilations, not just single files.

- it should be relatively easy to translate `old C' to the new
language.

- it might also be a good idea to steal liberally from C++ (which
of course steals liberally from SIMULA and others).

Very few of my ideas along this line are firm. My biggest worry
is that if the language is too small and malleable, it will suffer
from the same problems as some of the old dynamically-extensible
languages. One solution is to make the language small but the
support `library' (including headers that define standard aggregates
like C-style arrays and strings) a `part' of the language.
--
In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163
(hiding out on trantor.umd.edu until mimsy is reassembled in its new home)
Domain: ch...@mimsy.umd.edu Path: not easily reachable

### Doug Gwyn

Feb 20, 1988, 11:15:33 AM2/20/88
to
In article <23...@umd5.umd.edu> ch...@trantor.umd.edu (Chris Torek) writes:
>>Another thing that should go is the assumption that the unit of storage is
>>the byte.
>structure bitfields are the wrong way to get at bits; in particular,
>it would be nice to have arrays of bits. But the basic unit of
>storage has a way of creeping into the rest of the language, no
>matter how hard one attempts to keep them apart.

It isn't that bad, really -- I once went through an earlier C dpANS
and identified all the changes necessary to support a distinction
between "byte" (smallest accessible storage unit, which could be a
bit if you wanted to make it so) and "character" (smallest unit of
text). The particular type names I used were "short char" and "char",
respectively. It turned out that it wasn't too difficult to make
the distinction. The idea lost out to the "multi-byte character"
approach embodied in the current draft, which is a pity since that
doesn't support bit addressability and it requires specific calls
to convert MBC sequences to and from textual units (wchar_t). If
you guys really are planning on developing the language D, I hope
you'll consider something along these lines. By the way, if that
becomes a real project, it should get its own mailing list; there's
too many suggestions for changes to C in this newsgroup already..

### Eddie Wyatt

Feb 20, 1988, 12:54:46 PM2/20/88
to

> >Another shortcoming to be fixed is the automatic fallthrough for select
> >statements.
>
> agree

However, some means of fall through should be provided, BUT it should be
explicitly expressed.

>
> >To get even more radical -- with typedefs, enums, const declarations, and
> >(if we add them) inline functions, do we really need the pre-processor any
> >more?
>
> Probably. Inline functions should most certainly be added; they
> nearly obviate the need for macros.

Not probably, definately we still need the pre-processor. The
pre-processor supports a limited form of types as parameters.
Example:

#define alloc(type) ((type *) malloc(sizeof(type)))

Unless you are going to support some other form of polymorphism that
will allow the above to be expressed, leave in the pre-processor.

> >I think I would also drop the convention that 0 is a null pointer. Make
> >"null" a keyword, representing a null pointer of any type.
>
> This would, at one stroke, eliminate half the confusion that plagues
> comp.lang.c .... (about 1/3 :-) )

Unless you require function prototypes to be within scope, null
will not do you much good.

>
> I think the following are important considerations:
>
> - the language should be made as small as possible, but no smaller.

I agree, a very very very important point.

>
> - we should assume that compilers for this language are going to
> do a great deal of optimisation; in particular, they will optimise
> across entire compilations, not just single files.

Which brings up a question, what happens to the asm statement then.
If you have the write you code such that you have no idea
where variables are stored, how can you reliable use assemble statement
that play with storage. I think the conclusion will be trash asm.

--

Eddie Wyatt e-mail: e...@ius1.cs.cmu.edu

### John B. Nagle

Feb 20, 1988, 2:33:19 PM2/20/88
to

Let me suggest a few ground rules for designing a successor to C:

1) It need not be upward compatible with C, but automatic upward
translation should be possible. At the very least, automatic
translation with reliable automatic flagging of nonportable
constructs should be possible.

2) Syntactic changes should be avoided unless a definite gain can
be shown. "I like it better another way" is not sufficient.
Changes to syntax tend to arouse opposition all out of proportion
to their importance. The major problems in language design are
not syntatic.

3) C started life as a weakly typed language, and has been modified
slowly into a strongly typed one. This has resulted in some
strange semantics. This needs to be dealt with.

4) The basic model of a static language close to the machine should
be retained. Attempts to bolt on a very dynamic environment
with heavy underlying machinery, along the lines of LISP or
Smalltalk, should be resisted.

5) The semantics of types is probably the most important issue

6) The semantics of finite-precision integer arithmetic need to
very well thought out. The semantics of arithmetic should
be independent of the underlying hardware, so that the same
answer is obtained on all machines for all valid operations.
(This is possible, and can be done efficiently, but the
solutions are not well known.)

John Nagle

### Charles Daffinger

Feb 21, 1988, 5:47:38 PM2/21/88
to
In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
>
>Any serious effort to design a successor to C (which does not attempt to be
>upward compatible) should first consider what should be taken out and/or
>done differently. Adding new things is secondary.
>
[lots of oh, so familiar changes which just don't look like C...]

I think the language you want was already designed by Nicolas Wirth: Pascal.

-charles

--
Charles Daffinger \ Take me to the river / (812) 339-7354
Box 1662 \ drop me in the water / cd...@iuvax.cs.indiana.edu
Bloomington, IN 47402-1662 {pur-ee,rutgers,pyramid,ihnp4}!iuvax!cdaf
Home of the Whitewater mailing list: whitewate...@iuvax.cs.indiana.edu

### David Keppel

Feb 21, 1988, 7:51:00 PM2/21/88
to
In article <9...@PT.CS.CMU.EDU> e...@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
>> - we should assume that compilers for this language are going to
>> do a great deal of optimisation; in particular, they will optimise
>> across entire compilations, not just single files.
>
> Which brings up a question, what happens to the asm statement then.
>If you have the write you code such that you have no idea
>where variables are stored, how can you reliable use assemble statement
>that play with storage. I think the conclusion will be trash asm.

I think not. I think it will be to change the semantics of asm into a
varargs function (which may even have the register allocator at its
disposal?):

void
dumb_function( doit_to )
int *splat;
{
enum Labels { START = 1, LOOP, DONE };
extern int splodge;
int r1, r2;

_reg_alloc(2);
asm( START, "movl", ADDR, &splodge, REG, r1 = _register() );
asm( 0, "clrl", REG, r2 = _register() );
asm( LOOP, "tstl", REG, r2 );
asm( 0, "bgeq" LAB, DONE );
asm( 0, "brb", LOOP );
asm( DONE, NULL );
_reg_unalloc();
/* r1 is just thrown away ... */
}

Alternatively, the opcode could specify the format of the arguments that
it takes (much as printf works), but I think this is unnatural, since if
you had a bunch of typedefs, you couldn't just do:

#ifdef VAX
#else
#endif

(or something slightly less sick, but I hope this puts the idea across).

The worst thing is that this is almost portable ;->

;-D on (Well, C is just portable SNOBOL ;-) Pardo

### Johnson Noise

Feb 21, 1988, 8:09:36 PM2/21/88
to
In article <63...@iuvax.UUCP> cd...@iuvax.UUCP (Charles Daffinger) writes:
>In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
>>
>>Any serious effort to design a successor to C (which does not attempt to be
>>upward compatible) should first consider what should be taken out and/or
>>done differently. Adding new things is secondary.
>>
>[lots of oh, so familiar changes which just don't look like C...]
>
>I think the language you want was already designed by Nicolas Wirth: Pascal.
>
>
>-charles
>

Yeah, I think so. There are even those who want to change
= to :=. Computer users (I stress users -- see below) seem to be the
biggest complainers of all "scientists". Algol and PL/1 were designed
a long time ago, everyone thought that they would be THE programming
languages for all humanity/applications. Now people think that ADA
and Modula 2 are THE programming languages. Not many people stop to
look at history. C was just something Ritchie came up with -- it
wasn't a _software_engineering_environment_, just a simple, portable,
utility. It has probably become (along with UN*X) the second greatest
computer science accomplishment ever. It was not due to some great
"design by commitee", just necessity.
A guy I work with sometimes asks the question: "now that we
have all these great modular languages like ADA and Modula 2, I would
think there would be more software using them". This has to do with
Mac stuff which is mostly written in C. The answer is simple: computer
systems people (I stress systems people -- see below) are more interested
in getting the job done. Let's face it, a compiler is just a tool.
It does not write code for you, it does not find algorithmic errors
for you, it is just a way to avoid assembly (this is the reason FORTRAN
is the first greatest computer science accomplishment).
If you don't like C, don't use it. There must be at least 100
different programming languages, none of which are radically different
from Algol, FORTRAN, or LISP. All three of these were invented in the
late 50's-early 60's, so I think you can find what you are looking for
in some variant.
C was designed as a systems implementation language, not THE
language for all humanity/applications. I think it does a very, very
good job. What most people are suggesting (with respect to D) is
another Algol, PL/1, ADA, Modula 2 and whatever else comes up in the
next five years. It will suffer the same fate: crash and burn.

#define systems_person one who gets the job done

#ifdef systems_person
#define user !systems_person
#else
#define user one who waits for someone|something to do the job for him
#endif

I think Henry Spencer's quote says it all: "those who do not understand
UNIX are condemned to reinvent it, poorly".

This is not meant as a flame, just my personal observations.

### Herman Rubin

Feb 22, 1988, 7:56:20 AM2/22/88
to
In article <42...@june.cs.washington.edu>, pa...@june.cs.washington.edu (David Keppel) writes:
> In article <9...@PT.CS.CMU.EDU> e...@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
> >> - we should assume that compilers for this language are going to
> >> do a great deal of optimisation; in particular, they will optimise
> >> across entire compilations, not just single files.
> >
> > Which brings up a question, what happens to the asm statement then.
> >If you have the write you code such that you have no idea
> >where variables are stored, how can you reliable use assemble statement
> >that play with storage. I think the conclusion will be trash asm.

If we have the compiler replace names by locations (register and/or memory)
of the variables used, there is no more problem with global optimization
than before. In fact, we should do this in C; it is not prohibited by the
language standards, and it certainly makes more sense to be able to write
assembler statements in which the location of the variable is inserted by
the compiler.

Most of the C compilers I know do not do this; it is at the least annoying
not to be able to write such things as

and have the compiler include those location for the variables. (What I do
is to first compile as above and then edit, but it does not always work.)
We also should get rid of those quotes in the process; since asm is a reserved
operator, and its structure requires that what follows starts with ("
and ends with "), while the parentheses may be useful as separators, the
quotes are totally unnecessary (and have been known to cause errors).
--
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hru...@l.cc.purdue.edu (ARPA or UUCP) or hru...@purccvm.bitnet

### mcdo...@uxe.cso.uiuc.edu

Feb 22, 1988, 9:19:00 AM2/22/88
to

I find it hard to believe that a successor to C is needed or would be
appreciated. I come to this as a former 100% Fortran (and assembler)
programmer who now uses C about 80 % of the time. C does have a few,
minor defects (for instance, I will never , ever understand the syntax
of declarations; I have had a guru make up a huge chart listing dozens of
them, which I carry in my wallet.) So does every other language. C does
one thing extremely well: convert the heart of the machine operations of
a byte-addressible, conventional processor (i.e. the PDP11) into a nice
higher language. It is pleasantly compact, and very full of nice
shortcuts (e.g. "string"[i] ). If you dislike C , try other languages:
Fortran, Pascal, Ada ,Modula 2. Me, well , I like C and Fortran and loathe
the rest. But if a new language is to be designed, and done really well, it
won't be done by committee. For the perfect example look in comp.lang.fortran
to you by X3J3.

### Gideon Yuval

Feb 23, 1988, 2:11:46 PM2/23/88
to

> very well thought out. The semantics of arithmetic should
> be independent of the underlying hardware, so that the same
> answer is obtained on all machines for all valid operations.
> (This is possible, and can be done efficiently, but the
> solutions are not well known.)

Indeed they are not. Can you post a pointer to these solutions?
--
Gideon Yuval, +972-52-522255 (work), -2-690992 (home), yu...@taux02.nsc.com

Feb 23, 1988, 4:23:40 PM2/23/88
to
In article <23...@umd5.umd.edu> ch...@trantor.umd.edu (Chris Torek) writes:
|In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
|>Any serious effort to design a successor to C (which does not attempt to be
|>upward compatible) should first consider what should be taken out and/or
|>done differently. Adding new things is secondary.
|
|Oddly enough, I have been considering the same sort of thing myself. One of

|the nicest things about the C language is what it does NOT do. The language
|is small enough to learn and comprehend entirely in a short time; the list
|of language oddities is not empty, but is small (most of them appear below).

Agreed.

|>I would also like to do away with having control statements control single

|>statements. ... "if (foo) stmt1; stmt2; end;" ...
|>"for <stmts| while (<exp|) next <stmts| do <stmts| end;" ...

|>"loop <stmts| while (<exp|) <stmts| end;".
|
|I disagree with the details,

I would like to see other proposals.

|[may prefer 'endif' to 'end', but has doubts]

I debated whether to put in 'endif', etc., or 'end' in the above, and
finally opted for the shorter form. Ask me on another day and you might get

|A general aggregate constructor is necessary.

Any suggestions on how to do this?

|I think the following are important considerations:
|
| - the language should be made as small as possible, but no smaller.
|
| - we should assume that compilers for this language are going to
| do a great deal of optimisation; in particular, they will optimise
| across entire compilations, not just single files.

I don't think we should *require* this. The language should still have a
place for the fast and cheap compiler, which still produces reasonably good
code.

| - it should be relatively easy to translate `old C' to the new
| language.
|
| - it might also be a good idea to steal liberally from C++ (which
| of course steals liberally from SIMULA and others).

Yes, but I would not put the object oriented stuff into D. For that, you
get D++.

|My biggest worry is that if the language is too small and malleable, it
|will suffer from the same problems as some of the old dynamically-extensible
|languages. One solution is to make the language small but the support
|`library' (including headers that define standard aggregates like C-style
|arrays and strings) a `part' of the language.

Definitely. Library development should go on in parallel to the language
development, and whatever flexibility the language provides should be
reflected in the library.

### Richard Harter

Feb 25, 1988, 4:35:33 AM2/25/88
to
In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
>In article <23...@umd5.umd.edu> ch...@trantor.umd.edu (Chris Torek) writes:
>
>|[may prefer 'endif' to 'end', but has doubts]
>
>I debated whether to put in 'endif', etc., or 'end' in the above, and
>finally opted for the shorter form. Ask me on another day and you might get

Here is an alternative to endif et al. Use labels to start blocks and
'end labels' to end them. For example,

if (boolean expression)
foo: ....
end foo
else
bar: ....
end bar

This may look odd, but it does have the advantage that it makes the block
delimiting explicit. One would also need to be able to use unlabelled blocks
(in macros, for example), so

if (boolean expression)
....
end
else
....
end

would also fly. A disadvantage (from some viewpoints) is that, since labels
now delimit control blocks, they can't be used for goto's.

Sometimes, I think this might be a good idea.
--

In the fields of Hell where the grass grows high
Are the graves of dreams allowed to die.
Richard Harter, SMDS Inc.

### Richard Tobin

Feb 25, 1988, 12:43:09 PM2/25/88
to
In article <9...@PT.CS.CMU.EDU> e...@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
>> >I think I would also drop the convention that 0 is a null pointer. Make
>> >"null" a keyword, representing a null pointer of any type.
>> This would, at one stroke, eliminate half the confusion that plagues
>> comp.lang.c .... (about 1/3 :-) )
> Unless you require function prototypes to be within scope, null
>will not do you much good.

Ah, but if you you don't make the representation of the null pointer
be the same as that of an integer (or anything else) then you can make
it illegal to pass it (uncast) to a function for which there is no
prototype. You can't do that with zero, unless you want to have to say
(int)0 to pass an integer zero.

Of course, when designing a new language you certainly could require
that functions never be used unless there is a prototype (or
"declaration" as one might call it) in scope.

-- Richard
--
Richard Tobin, JANET: R.T...@uk.ac.ed
AI Applications Institute, ARPA: R.Tobin%uk.a...@nss.cs.ucl.ac.uk
Edinburgh University. UUCP: ...!ukc!ed.ac.uk!R.Tobin

### Henry Spencer

Feb 25, 1988, 3:22:37 PM2/25/88
to
> ... An undeclared variable should be an error, not an int.

Um, perhaps you should learn C before you start designing D...? An
undeclared variable *is* an error.

> Another thing that should go is the assumption that the unit of storage is
> the byte. The base unit of storage is the bit, and sizeof should return the
> number of bits in the object. This enables to treat objects smaller than a
> byte as first class objects.

Here we have a key decision: is D to share C's emphasis on generation
of efficient code? (Bearing in mind that this had a lot to do with C's
success.) If so, then trying to forget that bytes exist is a serious
mistake. Most machines cannot handle bits with anywhere near the efficiency
with which they handle bytes; the appropriate base unit for efficient code
*is* the byte.

> ... In keeping with the spirit of C, we avoid

> superfluous words, and keep the ones we do use short.
>
> With these changes, the {} statement delimiters become much less useful. I

> would probably drop them, and add a "begin ... end;" construct...

Please explain how avoiding superfluous words and keeping necessary ones
short is consistent with changing {/} to begin/end for no particular reason.

> To get even more radical -- with typedefs, enums, const declarations, and
> (if we add them) inline functions, do we really need the pre-processor any

> more? ...

The C++ people claim that the answer is "not much", given inline functions
in particular. They do still use it for some specialized problems, though.

> I would omit the automatic insertion of a null byte at the end of character
> constants. If you want nul terminated strings, write the nul. If you want
> strings with counts, the language should not get in your way.

Pray tell, how do you write a counted-string constant? I would suggest
that "abc" should mean a length-3 string with any necessary terminator,
regardless of what flavor of string is in use. That way you get a choice,
without recoding all your string constants.
--
Those who do not understand Unix are | Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly. | {allegra,ihnp4,decvax,utai}!utzoo!henry

### Henry Spencer

Feb 25, 1988, 3:34:25 PM2/25/88
to
> If we have the compiler replace names by locations (register and/or memory)
> of the variables used...

This does of course assume that all locations are addressable in all
instructions, which is emphatically not the case on many machines.

> We also should get rid of those quotes in the process...

What if I want to write asm("mov ')', r0")? The quotes are a reasonable way
of keeping the syntax of the assembler entirely out of the compiler's own
syntax handling, which is a good thing, especially for portable compilers.

Feb 25, 1988, 7:19:57 PM2/25/88
to
> Any serious effort to design a successor to C (which does not attempt to
> be upward compatible) should first consider what should be taken out and/or
> done differently. Adding new things is secondary.
>
> The first thing I would remove is the automatic conversion of arrays to
> pointers.

So far I agree.

> (A consequence of this change is that "a[b]" is no longer definable as
> "*(a + b)".

Here I disagree. We can have it both ways. Allow automatic conversion
of arrays to pointers *where pointers are required*. That is, if you say
"b = a;", where a is an array, you get *either* a pointer assignment or
an array assignment, depending on whether b is a pointer or array variable.

The present definitions of * and [] can then be happily retained. In fact,
the entire present treatment of arrays can be happily retained, and thus
arrays-as-first-class-objects could go into C itself -- except for one thing.
Function calls.

If the rule was that a prototype of the form "void fun (int a[4], int *b);"
declared a function with one array and one pointer argument, then calls to
this function could follow the semantics I outlined above; a call of the form
fun(a,a); would pass the whole array a as the first argument, and a pointer
to its start as the second argument. (Barring some form of "conformant
arrays", the dimension 4 would have to match exactly.)

Of course, in the present draft, that declaration declares a function with
two pointer arguments. If this becomes as entrenched in the language in
connection with the new prototype syntax as it is with the old function
definition syntax, we will never get arrays-as-first-class-objects.
This is one reason why I and others have suggested that declarations such
as the above should at least cease to have their present meaning.

Mark Brader "C takes the point of view
SoftQuad Inc., Toronto that the programmer is always right"
utzoo!sq!msb, m...@sq.com -- Michael DeCorte

### gordan

Feb 26, 1988, 11:12:29 PM2/26/88
to
-> ... An undeclared variable should be an error, not an int.
-
- [various flames stating that an undeclared variable *is* an error]

Perhaps what the original poster meant by his statement was that, for
instance, the following is legal:

foo (a, b)
char a; /* b is implicitly an int */
{
...
}

(Chapter and verse: K & R, Appendix A, Section 10.1, "Any identifiers
whose type is not given are taken to be _int_.").

Of course, in the above example, 'b' is not a variable, but a formal
parameter. Still, this is a problem... I once had a hard-to-find bug
that resulted from a missing formal parameter declaration defaulting to
int. _Has_ this been changed in ANSI C?
--
I am the Lizard King "Vous cherchez Jim, Monsieur?"
and I can do anything
-- caretaker at Gordan Palameta
-- Jim Morrison Pere Lachaise mnetor!lsuc!maccs!gordan