Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

1,254 views
Skip to first unread message

Dave Sill

unread,
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

unread,
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 */

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

David Keppel

unread,
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
ideas (take my ideas, please!)

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

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

Sun ECD Software

unread,
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

unread,
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

Karl W. Z. Heuer (ima!haddock!karl or ka...@haddock.isc.com), The Walking Lint
KWZH: We need a construct like `e1 UNLESS IT==0 INWHICHCASE e2'.
GCJ: Yes, and also `IFONTHEOTHERHAND ... WEMAYSAFELYASSUME'.

Steve Wampler

unread,
Feb 9, 1988, 7:12:14 PM2/9/88
to
In article <25...@haddock.ISC.COM>, ka...@haddock.ISC.COM (Karl Heuer) writes:
> 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

unread,
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

unread,
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

unread,
Feb 17, 1988, 9:41:56 AM2/17/88
to
In article <25...@haddock.ISC.COM>, ka...@haddock.ISC.COM (Karl Heuer) writes:
> 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}

Frank Adams

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

Frank Adams ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate 52 Oakland Ave North E. Hartford, CT 06108

Karl Heuer

unread,
Feb 18, 1988, 3:47:20 PM2/18/88
to
In article <5...@naucse.UUCP> s...@naucse.UUCP (Steve Wampler) writes:
>In article <25...@haddock.ISC.COM>, ka...@haddock.ISC.COM (Karl Heuer) 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

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

In article <25...@haddock.ISC.COM> ka...@haddock.ima.isc.com (Karl Heuer) writes:
>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

unread,
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

unread,
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

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

agree; unsure about C++/ANSI syntax

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

I thought about this; it gets sticky, and I am still unsure. C's
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
understanding. I am undecided about this.

>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

unread,
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.
>I thought about this; it gets sticky, and I am still unsure. C's
>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

unread,
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

unread,
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
to be addressed.

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

unread,
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

unread,
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, "addl", ADDR, sizeof( some_type ), REG, r1 );
asm( 0, "subl", ADDR, sizeof( some_type ), ADDR, splat );
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
#define ADD "addl"
#else
#define ADD "add"
#endif

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

No, I haven't thought to closely about this, there may be some fatal flaw.
The worst thing is that this is almost portable ;->

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

Johnson Noise

unread,
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

unread,
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

asm(" addl x,y,z");
asm(" addwc u,v,w");

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

unread,
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
and read about 88tran, the totally new language with two heads, brought
to you by X3J3.

Gideon Yuval

unread,
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

Frank Adams

unread,
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 different answer.

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

Overloaded functions are fine, though.

|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

unread,
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
>a different answer.

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

unread,
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

unread,
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

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

Mark Brader

unread,
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

unread,
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

James Jones

unread,
Feb 27, 1988, 4:25:54 AM2/27/88
to
In article <1988Feb25....@utzoo.uucp>, he...@utzoo.uucp (Henry Spencer)
writes:

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

Perhaps the original author was referring to letting undeclared identifiers
which are followed by something that looks like an actual parameter list
default to being an extern function returning int, and to the ability to
elide int from declarations (which, if I rightly understand the X3J11 Draft,
can still be done as long as there's *some* keyword that lets the compiler
conclude that it's looking at a declaration). If that's indeed what the
original author was referring to, I sincerely agree with him. (It would
be nice if X3J11 deprecated it, too--which it may have, I don't recall.)

James Jones

Richard A. O'Keefe

unread,
Feb 27, 1988, 6:39:48 AM2/27/88
to
In article <24...@cca.CCA.COM>, g-...@cca.CCA.COM (Richard Harter) writes:
> 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
>
He has just re-invented BCPL. Where C has { and }, BCPL had $( and $).
The name for these was "section brackets". There was an extra hack:
"tagged section brackets". If <id> looked like an identifier,
$(<id> and $)<id> were tagged section brackets (each was a single token).
So in BCPL this example would be
TEST boolean-expression THEN
$(FOO
...
$)FOO
ELSE
$(BAR
...
$)BAR

PL/I has a similar feature, one can write
label: DO;
statements
END label; /* I may have this wrong */
There is a difference, though. In BCPL, the tags on the brackets must
match exactly, but in PL/I a tagged END may close any number of tagged
and untagged DOs.

Can anyone who has experience with using this feature suggest why it has
remained rare. In particular, does anyone know why it isn't in C, given
that it was in BCPL? (Not that I think it's needed.)

Herman Rubin

unread,
Feb 27, 1988, 6:51:56 AM2/27/88
to
In article <1988Feb25....@utzoo.uucp>, he...@utzoo.uucp (Henry Spencer) writes:
> > 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.

This is another reason for the user to be able to force the compiler to put
things in registers. The stupid compiler should not be able to force the
user to use many instructions because it does not see the need for register
variables. This applies also to such constructs as register pairs, triples,
etc. Naturally, this would require some way of modifying the register number,
but so what? This is simple, compared to the machinations that compilers
now undertake.

Also, it is rash to assume that the programmer does not make mistakes. If the
location types of the arguments do not work with the instruction, this is a
programming error; what are diagnostic and error messages for?

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

Someone has posted an example where the failure was due to a " in the assembler
instruction. It is just as easy, since C requires a ; to end a statement, to
tell the compiler that until it sees ); to continue processing for the
assembler, and to have some escape mechanism for inserting ); into the
assembler statement. Alternatively, if we get rid of the ;s as mandatory
terminators (which I think is a good idea), have an escape mechanism for
inserting ) in an assembler statement. Is this worse than not being able
to put ", or even "), in an assembler statement?

Richard Harter

unread,
Feb 27, 1988, 6:14:38 PM2/27/88
to
In article <7...@cresswell.quintus.UUCP> o...@quintus.UUCP (Richard A. O'Keefe) writes:
>In article <24...@cca.CCA.COM>, g-...@cca.CCA.COM (Richard Harter) writes:
>> Here is an alternative to endif et al. Use labels to start blocks and
>> 'end labels' to end them....

>He has just re-invented BCPL.

Er, you give me too much credit. A feature of BCPL, perhaps,
but not the whole thing> :-)

>Where C has { and }, BCPL had $( and $).
>The name for these was "section brackets". There was an extra hack:
>"tagged section brackets". If <id> looked like an identifier,
>$(<id> and $)<id> were tagged section brackets (each was a single token).
>So in BCPL this example would be
> TEST boolean-expression THEN
> $(FOO
> ...
> $)FOO
> ELSE
> $(BAR
> ...
> $)BAR

>PL/I has a similar feature, one can write
> label: DO;
> statements
> END label; /* I may have this wrong */
>There is a difference, though. In BCPL, the tags on the brackets must
>match exactly, but in PL/I a tagged END may close any number of tagged
>and untagged DOs.
>
>Can anyone who has experience with using this feature suggest why it has
>remained rare. In particular, does anyone know why it isn't in C, given
>that it was in BCPL? (Not that I think it's needed.)

As it turns out I do have experience with this exact feature in PL/I.
I once inherited a 40,000 line PL/I program with a 5000 line main program
which used nested tagged begin/end blocks. I can tell you that multiple
closure is a real disaster. Fundamentally, the problem is that you can
remove an end statement, thereby changing the block structure of the program,
and the program is still syntactically correct and compiles. In a large
program which runs across many pages you can't visually confirm that all
the blocks align properly. It's been a long time now, and I can't recall
the gory details any more. However the practical effect was the same as
having a C switch construct with some of the terminating case 'break'
statements unintentionally missing.

As a side point, I like the suggestion that someone made that there be
a fallthrough statement rather than automatic fallthrough.

As to rarity of usage, I suspect the problem is that it is a nice feature
if you use it in a standardized disciplined manner, but that if it is not
obligatory it will be used haphazardly, and that it has no particular value
in that case. Now that I think on it, you don't need it for small pieces
of code, where everything is clear. It may have some value for large
programs (as in large number of lines per file). However my experience
is that the way to deal with the difficulties created by writing large
procedures is not to not write large procedures! :-).

OK, Richard, you win -- D should not have labelled blocks.

Doug Gwyn

unread,
Feb 27, 1988, 7:32:41 PM2/27/88
to
In article <1988Feb25....@utzoo.uucp> he...@utzoo.uucp (Henry Spencer) writes:
>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.

Be careful; cause and effect are circular here. I've been contacted by
more than one computer architect who wanted bit addressability but had
trouble convincing management to accept the slightly added expense because
they would observe that such a facility could not be exploited from popular
high-level languages. In fact, I have many applications for bit arrays
and bit maps, and there is a severe performance penalty caused by lack of
hardware support for them (and high-level language access to such support).

My "short char" proposal did not REQUIRE bit addressability, but it did
allow it to be exploited if the implementor decided it was wanted.
(1 = sizeof(short char) <= sizeof(char).) The other main implementation
would be to let a "short char" be an 8-bit byte and a normal "char" be
big enough to hold an entire textual unit (typically 16 bits in Japan).
Unfortunately not many committee members seem to be bit-map programmers...

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

A better reason for a change here is the problems cause by "dangling else"
and accidental ";" after the closing ")" of a while(). The idea that such
clauses control a single statement (which might be a compound statement)
makes C susceptible to such errors; using unique bracketing keywords would
be safer.
while condition do ;-separated_statements done
if condition then ;-separated_statements else ;-separated_statements fi
If would also be nice if such statements could return values (so ?: could
be dispensed with). Better yet, adopt notation more supportive of concurrent
processing, such as Dijkstra's "guarded" commands. Why not support the future?

Doug Gwyn

unread,
Feb 27, 1988, 7:49:01 PM2/27/88
to
In article <10...@maccs.UUCP> gor...@maccs.UUCP (gordan) writes:
>... defaulting to int. _Has_ this been changed in ANSI C?

No, like other warts, since this is widely used in correctly-written
(according to K&R rules) C code, and since it does not pose any true
technical problems, it must continue to be tolerated. Fix it in "D".

a...@alice.uucp

unread,
Feb 28, 1988, 9:16:50 PM2/28/88
to
The best scheme I've seen for labelled blocks comes from SETL.
In SETL, statements like `IF' and `WHILE' begin blocks which
must be ended by `END' statements. Thus one can write:

IF x > y
THEN max := x;
ELSE max := y;
END;

(I think I have the semicolons right; I'm sure about the one after END)

When these structures are nested deeply, one may be confused about
just what is being ended. To reduce confusion, the programmer may
insert any number of tokens from the opening statement between the
END and the semicolon:

IF x > y
THEN max := x;
ELSE max := y;
END IF x > y;

These tokens are optional, but if they appear, they must match
the corresponding tokens from the opening statement.

Ralf....@b.gp.cs.cmu.edu

unread,
Feb 29, 1988, 8:06:01 AM2/29/88
to

In article <24...@cca.CCA.COM>, g-...@cca.CCA.COM (Richard Harter) writes:
}As a side point, I like the suggestion that someone made that there be
}a fallthrough statement rather than automatic fallthrough.

So, you would like to have to write
switch(var)
{
case foo: fallthrough;
case bar: fallthrough;
case baz: fallthrough;
case mung: /* code to do something for all four cases */
}
?

Or add yet another special case (automatic fallthrough if and only if there
is no code between the two labels)?

--
{harvard,uunet,ucbvax}!b.gp.cs.cmu.edu!ralf -=-=- AT&T: (412)268-3053 (school)
ARPA: RA...@B.GP.CS.CMU.EDU |"Tolerance means excusing the mistakes others make.
FIDO: Ralf Brown at 129/31 | Tact means not noticing them." --Arthur Schnitzler
BITnet: RALF%B.GP.CS.CMU.EDU@CMUCCVMA -=-=- DISCLAIMER? I claimed something?

Guy Middleton

unread,
Feb 29, 1988, 1:27:07 PM2/29/88
to
In article <24...@cca.CCA.COM> g-...@CCA.CCA.COM.UUCP (Richard Harter) writes:
> In article <7...@cresswell.quintus.UUCP> o...@quintus.UUCP (Richard A. O'Keefe) writes:
> >In article <24...@cca.CCA.COM>, g-...@cca.CCA.COM (Richard Harter) writes:
> >> Here is an alternative to endif et al. Use labels to start blocks and
> >> 'end labels' to end them....
>
> >He has just re-invented BCPL.

There is another thing that should be reintroduced: case ranges in switch
statements. These were part of B (although they were not in BCPL):

switch (x) {
case <0: /* ... */
break;
case 0::10: /* ... */
break;
case >10: /* ... */
default:
}

John Stanley

unread,
Feb 29, 1988, 3:28:49 PM2/29/88
to

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

While I'm totaly against changing the existing functionality of the
sizeof() operator, what I would be totaly in favor of would be the
addition-to-ansi-C of a new operator that would have a similar
functionality, but which would return the number of -bits- in
something. The name bitsize() would be my suggested name for this
operator.

This would provide one MAJOR advantage. It would allow writing code
or header files that would be 100% portable without having to know
about each and every compiler/OS/machine's identifer defines. If you
needed a 12 bit integer type, your headers could have #if statements
that would provide the next integer type equal or larger that 12 bits.
No more #ifdef'ing special integer types individualy for each system
when you're trying to make efficient code run on multiple machines.

An additional minor advantage would be the capability of writing
the kinds of functions we normaly use sizeof for to work with bitfield
variables..

This is a relatively minor addition to any existing compiler
(multiply sizeof by 8 for most machines... and return the bitsize
that's probably already a field in the evaluation structure for a
bitfield variable...) and would make some major advancements possible
in source code portability...

Doug Gwyn, I'd appreceate hearing your reaction on this suggestion.
If it's never come up as a suggestion, feel free to play with it. If
it's been considered and rejected, I'd like to hear the reasoning
behind the rejection.

---
John Stanley (jo...@viper.UUCP)
Software Consultant - DynaSoft Systems
UUCP: ...{amdahl,ihnp4,rutgers}!meccts!viper!john

Jonathan Leffler

unread,
Feb 29, 1988, 4:08:59 PM2/29/88
to
In article <63...@iuvax.UUCP> cd...@iuvax.UUCP (Charles Daffinger) writes:
>I think the language you want was already designed by Nicolas Wirth: Pascal.

More likely: Modula-2

After all, that was what Wirth intended to design when he designed Pascal.

#include <disclaimer.h>
Jonathan Leffler (jo...@sphinx.co.uk)

Frank Adams

unread,
Feb 29, 1988, 6:07:47 PM2/29/88
to
In article <24...@cca.CCA.COM> g-...@CCA.CCA.COM.UUCP (Richard Harter) writes:
| if (boolean expression)
| ....
| end
| else
| ....
| end

Note that this does *not* solve the dangling else problem. That being the
case, I see no reason to prefer it to the current syntax.

Frank Adams

unread,
Feb 29, 1988, 6:40:56 PM2/29/88
to
In article <1988Feb25....@utzoo.uucp> he...@utzoo.uucp (Henry Spencer) writes:
>> ... 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.

Mea culpa. The C compilers I use give warnings for undeclared functions and
several other things, which I treat as errors; so sometimes I forget which
ones are really errors.

The point still stands as regards undeclared functions, though.

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

Yes.

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

This makes C nicely efficient on *many* machines; but there are others on
which a larger size would be much better. Not every machine is byte
addressable.

Conversely, on those machines which *do* have bit addressing, C provides
very inefficient access to it.

We need to figure out how to make D efficient without regard to the
addressing unit of the machine. Off-hand, I'm not sure how to do that.

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

I was thinking that with the other changes I proposed, the compound
statement would be needed only for declaring variables local to part of a
function. This use is not important enough to justify allocating two special
symbols to it.

This overlooks the compound statement forming the body of the function. This
is easily enough dealt with by making the function syntax be:
type declarator declarations statements end ;
instead of
type declarator { declarations statements }

One possible use for the braces would be as type parentheses, so one could
write:
{int *} a, b;
to make both a and b pointers to int. I think using this for casts would
improve readability as well. (That is, replace the parentheses around the
cast type with braces.)

This is an off-the-cuff idea, there may be better ones.

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

Overall, the preprocessor seems to be used as a way to hack prototypes for
the next extension to the language. C++ people tend to use it for
parameterized types, early C used it for consts and enums, etc. This may be
an argument for keeping it.

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

struct string {char * data; int size};
char dummy[] = "This is my string."
struct string s = {&dummy, sizeof(dummy)};

If you want the length immediately preceding the string, you need new syntax
and/or the pre-processor to avoid writing the string twice.

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

And how do you specify what flavor of string is "is use?".

Frank Adams

unread,
Feb 29, 1988, 6:46:24 PM2/29/88
to
Clearly, assembler statements should have been defined as:

#asm <statement>

instead of

asm("statement");

This is almost worth doing in C; I would certainly do it in D (assuming the
preprocessor is kept).

Dave Decot

unread,
Feb 29, 1988, 10:45:27 PM2/29/88
to
Array first-class-ness and aggregate constants could be easily provided
within C (not that I want to discourage D-zigners; it's a meritorious idea).

The basic ideas are that "a[]" is an array lvalue, and that aggregate
constants are natively typeless and must always be either cast or assigned
to the appropriate type. Two examples follow.

(Watch out for the extensions to printf(3S) and scanf(3S) for array handling.)

I will explain any of this if desired.

EXAMPLE 1

int thing(i, a, b)[2]
int i, a[2], b[2];
{
int val[2];

val[0] = a[i] - b[0];
val[1] = a[i] - b[1];

return (val[]);
}


main()
{
typedef int PAIR[2];

char *message = "END-OF-EXAMPLE";

PAIR p1, p2, p3[2];

p1[] = {2, -3};
printf(p1: "%(2)4d\n", p1);

p2[] = {1, 7};
printf("p2: %(2)4d\n\n", p2);

p3[0][] = thing(0, p1[], p2[]);
p3[1][] = thing(1, p1[], (PAIR) {1, 7});

printf("p3: %(2; )(2, )d\n\n", p3);

printf("%(* )c\n", strlen(message), message);
printf("%(*:-])c\n", strlen(message)*2/3, (char *)NULL);
}

prints

p1: 2 -3
p2: 1 7

p3: 1, -5; -4, -10

E N D - O F - E X A M P L E
:-]:-]:-]:-]:-]:-]:-]:-]:-]


ANOTHER EXAMPLE

main()
{
int array[10][10];
int array2[100][10] = {0}; /* fills entire auto array with 0s */
int row;

scanf("%(10 )(10 )d", array); /* reads free-format 10x10 array */

/* copy array into top 10 rows of array2 */
for (row = 0; row < 10; row++)
array2[row][] = (int [100]) array[row][]; /* cast is not needed */

reduce( (int [100][100]) array2[], 10); /* this cast is required */

for (row = 0; row < 10; row++) /* copy the rows back */
array[row][] = array2[row][];

printf("%(10\n)(10 )6d\n", array); /* display square array */
}


reduce(a, n)
int a[100][100];
int n;
{
/* ... */
}

Barnacle Wes

unread,
Mar 1, 1988, 1:39:45 AM3/1/88
to
Frank, if you want to write your programs in Ada, write them in Ada.
Don't try to re-write a C compiler to accept Ada programs. In fact,
you should re-post this message in comp.lang.ada, I think you'd find a
more receptive audience there. Since the name Ada has already been
used, and your language is sufficiently different from C to NOT name
it D, perhaps you could call it "DoD". But that's been used, too,
hasn't it?

(-: :-) (-: :-) (-: :-)

--
/\ - "Against Stupidity, - {backbones}!
/\/\ . /\ - The Gods Themselves - utah-cs!utah-gr!
/ \/ \/\/ \ - Contend in Vain." - uplherc!sp7040!
/ U i n T e c h \ - Schiller - obie!wes

Dave Sill

unread,
Mar 1, 1988, 1:23:13 PM3/1/88
to
In article <2258...@uxe.cso.uiuc.edu> mcdo...@uxe.cso.uiuc.EDU writes:
>I find it hard to believe that a successor to C is needed or would be
>appreciated.

Yes, C is adequate for most of today's needs. But it does have its
problems and weaknesses. If we want to have a language to take its
place tomorrow, we had better start thinking about it today, though.

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

To varying degrees. Hopefully D will learn from C, and at least not
repeat the same mistakes.

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

Certainly an appropriate behavior for a systems programming language
designed in the early seventies. But D should be targeted to a more
general purpose, as C is being used today. Also, D should be more
adaptable to unconventional processors than C is. E.g., it should be
more suitable for parallel processing environments.

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

D would not be for people who dislike C. It would be for people who
like C but find it lacking by today's standards in certain areas.

>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
>and read about 88tran, the totally new language with two heads, brought
>to you by X3J3.

We aren't designing D here. We are pointing out those things lacking
in C that we'd like to see done right in a currently hypothetical
successor. Of course if somebody wanted to digest our discussions,
design a language based on them, implement a compiler (perhaps based
on GNU C or C++), call it D, and distribute it freely, I wouldn't
complain.

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

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

Dave Sill

unread,
Mar 1, 1988, 3:03:10 PM3/1/88
to
(Not really a C issue)

Am I the only person in the world that thinks it's time to scrap
ASCII?

Look at the contortions we have to go through in C because there
aren't really enough characters for the operators needed. Look at the
messes we get into under the UNIX shells with quote characters,
delimiters, et cetera. Wouldn't it be simpler if punctuation was
punctuation and metacharacters were metacharacters and there was no
overlap between the two?

APL, of course, solved this problem by inventing its own character
set. Unfortunately, it was nonstandard and there was almost no
equipment that used that character set.

The time is ripe for a more flexible "Code for Information
Interchange". How many more years/decades will we be forced to make
do with a lousy 95 symbols: all predefined, most vastly overloaded?

C would have been much more usable language if it hadn't had to have
been mapped to ASCII. D could be the best of C and APL if a larger
character set was available.

I know, I know, the cost of such a change would be phenomonal. Even
deciding on a new standard will be hard/expensive/time-consuming, but
it's *got* to be done sooner or later. (Not until we've lived with
several incompatible proprietary systems for a while, though.)

I just needed to get that off my chest, sorry if I bothered you.

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

"There is very little importance in instruction sets."
-- Ted Nelson

"There is very much importance in character sets."
-- Me

Doug Gwyn

unread,
Mar 1, 1988, 4:43:11 PM3/1/88
to
In article <12...@brl-adm.ARPA> ds...@NSWC-OAS.arpa (Dave Sill) writes:
>The time is ripe for a more flexible "Code for Information
>Interchange". How many more years/decades will we be forced to make
>do with a lousy 95 symbols: all predefined, most vastly overloaded?

ISO extended the character set several years ago. It has also been
extended (in more than one way) to accommodate Kanji characters.
C source can be in EBCDIC (for example); it seems inappropriate to
require either a specific character code "standard", or an even
larger set of characters than it already uses, given the amount of
trouble with this we've already had.

Karl Heuer

unread,
Mar 1, 1988, 7:50:52 PM3/1/88
to
>In article <1988Feb25....@utzoo.uucp> he...@utzoo.uucp (Henry Spencer) writes:
>>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.

"Word-addressible cannot handle bytes with anywhere near the efficiency
with which they handle words; the appropriate base unit for efficient code
is the word." Right?

On a word-addressible machine, there is a perceived need to address objects
smaller than one word; hence most C compilers give you access to individual
bytes via "char". (There may be some that define char as a machine word, but
I'm not familiar with any.) Similarly, on byte-addressible machines there is
a (less) perceived need to address objects smaller than one byte.

If sizeof were measured in bits (the original statement in this thread, I
believe), then (a) no functionality would be lost, because you get the number
of char-sized bytes by using sizeof(thing)/sizeof(char); and (b) it becomes
possible to add a datatype "bit" with sizeof(bit)==1. Code that doesn't use
it would still be just as efficient as it used to be. Code that does use it
on a bit-addressible machine would have access to the entire address space.
And code that uses it on a byte- or word-addressible machine may have to use
goofy pointers, just like (char *) on a word-addressible machine. (Presumably
the author of such code is aware of the space-time tradeoffs.)

In article <73...@brl-smoke.ARPA> gw...@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>My "short char" proposal did not REQUIRE bit addressability, but it did
>allow it to be exploited if the implementor decided it was wanted.
>(1 = sizeof(short char) <= sizeof(char).)

This is a less radical proposal, which would be consistent with C.

>The other main implementation would be to let a "short char" be an 8-bit byte
>and a normal "char" be big enough to hold an entire textual unit (typically
>16 bits in Japan).

I see this as a different problem, which is better solved by "long char". For
example, a Japanese system on a bit-addressible machine should be able to use
both features: 1-bit short char, 8-bit char, 16-bit long char.

>>Please explain how avoiding superfluous words and keeping necessary ones
>>short is consistent with changing {/} to begin/end for no particular reason.
>
>A better reason for a change here is the problems cause by "dangling else"
>and accidental ";" after the closing ")" of a while().

A better change would be to leave the punctuation alone, and but make the
braces required even for a null- or single-statement body. In other words,
change the syntax to read "compound-statement" instead of "statement".

>If would also be nice if such statements could return values (so ?: could
>be dispensed with).

Yes, let's make *all* statements return values (more precisely, remove the
distinction between expressions and statements). Then there's no need for the
distinction between ?: vs. if-else, nor () vs. {}, nor the comma operator vs.
semicolon. (The semicolons in the "for" statement are a minor nuisance, but
no worse than non-operator commas. "for ((i=0; j=N); i<N; (++i; --j))" is
parsable.) Statements that have no obvious value (while; elseless if) could
be void expressions.

Karl W. Z. Heuer (ima!haddock!karl or ka...@haddock.isc.com), The Walking Lint

Karl Heuer

unread,
Mar 1, 1988, 7:59:03 PM3/1/88
to
In article <73...@brl-smoke.ARPA> gw...@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:

In a similar vein, using "int" (or the "implied int" you get by leaving out
the type) for a function which returns no value should disappear.

Hey Doug, couldn't this be deprecated on the same grounds as old-style
function declarations? A new syntax ("void") has been standardized which does
the job better, and the old syntax makes it harder to diagnose certain bugs.

Dave Sill

unread,
Mar 2, 1988, 10:14:06 AM3/2/88
to
>In article <12...@brl-adm.ARPA> ds...@NSWC-OAS.arpa (Dave Sill) writes:
>>The time is ripe for a more flexible "Code for Information
>>Interchange". How many more years/decades will we be forced to make
>>do with a lousy 95 symbols: all predefined, most vastly overloaded?
>
>ISO extended the character set several years ago. It has also been
>extended (in more than one way) to accommodate Kanji characters.

Yes, I've read the ISO standards you refer to (ISO 646, ISO 2022, ISO
2375, ISO 6429), they're sitting on my desk right now. ISO 646 is
like ASCII, except that it allows the construction of "composite
graphic characters". This is great, the sequence "=<CR>/", for
example, could be displayed as a "not-equal" symbol. Unfortunately,
ISO 646 doesn't say what these composite characters look like, so it
could be displayed as a ham sandwich, or as an equals sign with the
first character of the line replaced with a /. Real useful.

ISO 2022 covers extensions to ISO 646 using alternate graphical
character sets, escape sequences, and 8-bit codes. But it says
nothing about what a given pattern looks like in a given character
set. It does, however, maintain interchangeability between 7-bit and
8-bit standard and extended environments, which is A Good Thing.

ISO 2375 is a procedure for registering ISO 2022 escape sequences.
This seems like a step in the right direction. Too bad they don't
have such a procedure for the alternate graphical character sets.

ISO 6429 contains control functions for display devices. It's
interesting to note that although this standard has been available
since '83, only one vendor that I'm aware of claims conformance
(Canon, in their laser printers. If there are others you're aware of,
I'd like to know). Not exactly overwhelming acceptance.

The real problem, though, is not so much in the code itself as it is
in the display devices, terminals, keyboards, et cetera, that are used
to enter and display these characters. Even if the ISO standards
defined the code for a right-pointing-arrow, what key or key-
combination would have to be used to enter one? How could it be
displayed?

>C source can be in EBCDIC (for example); it seems inappropriate to
>require either a specific character code "standard",

So you're saying we can't extend the set of graphical characters we
use in languages because someone might not have the characters
available? What about trigraphs, or a similar mechanism?

>or an even
>larger set of characters than it already uses, given the amount of
>trouble with this we've already had.

The trouble is not that we have too many characters available, it's
that we have too few! For example, if we had a left-pointing-arrow
character that could be used for assignment, the whole == versus =
problem would not exist.

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

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

Ned Nowotny

unread,
Mar 2, 1988, 11:40:20 AM3/2/88
to
Followup -To:


In discussing various successor languages, perhaps the following naming
conventions would be in order:

C - The language we all know and love (or loath, as the case may be).

C++ - The well-know C-like language with object-oriented extensions.

D - The natural C-like successor language.

D++ - The natural C++-like successor language.

C+C - C with extensions for numerical analysis.

C[N] - C with extensions for vector architectures and optimization.

(C) - Functional C.

!C - A pseudo-C with a high degree of structuring and strong typing.

&&C++ - ANSI C.

--

Ned Nowotny (n...@ghostwheel.aca.mcc.com.UUCP)

Doug Gwyn

unread,
Mar 2, 1988, 12:52:20 PM3/2/88
to
In article <28...@haddock.ISC.COM> ka...@haddock.ima.isc.com (Karl Heuer) writes:
>If sizeof were measured in bits ...

>In article <73...@brl-smoke.ARPA> gw...@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>>My "short char" proposal did not REQUIRE bit addressability, but it did
>>allow it to be exploited if the implementor decided it was wanted.
>>(1 = sizeof(short char) <= sizeof(char).)

The reason for not insisting on sizeof() being in bits was that it would
add at least three bits to the required size_t for a byte-oriented
implementation, with no particular gain in that case.

>Yes, let's make *all* statements return values ...

I once designed a language like this for a special purpose. It worked, but
you need to figure out what to do about declarations. What values should
they return?

Doug Gwyn

unread,
Mar 2, 1988, 12:54:11 PM3/2/88
to
In article <28...@haddock.ISC.COM> ka...@haddock.ima.isc.com (Karl Heuer) writes:
>Hey Doug, couldn't this be deprecated on the same grounds as old-style
>function declarations?

It's been suggested before, but hey, send it in. Maybe you can think of
more persuasive arguments.

Doug Gwyn

unread,
Mar 2, 1988, 1:04:55 PM3/2/88
to
In article <6...@viper.Lynx.MN.Org> jo...@viper.UUCP (John Stanley) writes:
>... addition-to-ansi-C of a new operator that would have a similar

>functionality, but which would return the number of -bits- in
>something. The name bitsize() would be my suggested name for this
>operator.

It's already basically there:

#include <limits.h> /* (we may have to rename this header) */
#define bitsize(obj) (CHAR_BIT*sizeof(obj))

The only thing this doesn't work on is bit-fields, functions, or
incomplete types.

Doug Gwyn

unread,
Mar 2, 1988, 1:14:09 PM3/2/88
to

My point is that it does no good to introduce a language that uses
funny APL-like symbols, when the vast majority of existing and
near-future terminals and printers won't support the symbols. (I
doubt that many even support the full set already registered with
ISO.) What you end up with are a bunch of kludges, like the proposed
ANSI C trigraphs, that everybody ends up having to cope with. By
limiting the language symbols to those commonly available, you make
programs much more readable in practice.

It isn't clear to me that funny APL-like symbols are preferable to
short keywords (for example). Note that even the mathematicians are
starting to use such notations in preference to inventing mystical
symbols, especially in category theory.

Doug Gwyn

unread,
Mar 2, 1988, 1:30:43 PM3/2/88
to
In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
>We need to figure out how to make D efficient without regard to the
>addressing unit of the machine. Off-hand, I'm not sure how to do that.

Obviously, you let the compiler take care of allocating suitable sizes.
For it to do this, the programmer needs to specify something about the
intended usage of the variable, such as is done with enumeration types,
Booleans, and subscript ranges in various languages.

Doug Gwyn

unread,
Mar 2, 1988, 1:35:54 PM3/2/88
to
In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
>Clearly, assembler statements should have been defined as:
>#asm <statement>
>instead of
>asm("statement");

A properly-designed system programming language should not have such
a feature at all. (It is not guaranteed in C, either.) The interface
between the optimized code produced for the HLL and the in-line
assembly code is quite problematic. Also, the compiler should not be
forced to have an assembler built-in just to handle such stuff; many
compilers directly generate relocatable object code.

If there is some feature that might be worth having asm() for, for
example "rotate" instructions, then consider designing it into the
HLL.

Chris Torek

unread,
Mar 2, 1988, 5:22:57 PM3/2/88
to
-In article <24...@cca.CCA.COM> g-...@cca.CCA.COM (Richard Harter) writes:
-}As a side point, I like the suggestion that someone made that there be
-}a fallthrough statement rather than automatic fallthrough.

In article <2229...@ralf.home> Ralf....@B.GP.CS.CMU.EDU writes:
-So, you would like to have to write
- switch(var)
- {
- case foo: fallthrough;
- case bar: fallthrough;
- case baz: fallthrough;
- case mung: /* code to do something for all four cases */
- }

While this would work, if we assume D has aggregate constructors,
there is a handsomer way:

switch (e) {
case [1, 2, 3, 5, 7, 13, 19, 23]: ...
}
/* syntax above is only for demonstration */
--
In-Real-Life: Chris Torek, Univ of MD Computer Science, +1 301 454 7163
(still on trantor.umd.edu because mimsy is not yet re-news-networked)
Domain: ch...@mimsy.umd.edu Path: ...!uunet!mimsy!chris

Frank Adams

unread,
Mar 2, 1988, 8:26:29 PM3/2/88
to
In article <2...@aiva.ed.ac.uk> ric...@uk.ac.ed.aiva (Richard Tobin) writes:
|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.

I certainly *would* require this.

Matt Landau

unread,
Mar 2, 1988, 8:49:12 PM3/2/88
to
In comp.lang.c (<24...@umd5.umd.edu>), ch...@trantor.umd.edu (Chris Torek) writes:
>While this would work, if we assume D has aggregate constructors,
>there is a handsomer way:
>
> switch (e) {
> case [1, 2, 3, 5, 7, 13, 19, 23]: ...
> }
> /* syntax above is only for demonstration */

And of course we add ranges, giving

switch(e)
{
case [1, 2, 3..7, 13, 19, 23..36]:
.
.
.
default:
.
.
.
}
/* what he said */

Richard A. O'Keefe

unread,
Mar 2, 1988, 9:29:14 PM3/2/88
to
In article <12...@brl-adm.ARPA>, ds...@NSWC-OAS.arpa (Dave Sill) writes:
> Am I the only person in the world that thinks it's time to scrap ASCII?
> The time is ripe for a more flexible "Code for Information
> Interchange". How many more years/decades will we be forced to make
> do with a lousy 95 symbols: all predefined, most vastly overloaded?
> Even deciding on a new standard will be hard/expensive/time-consuming,
> but it's *got* to be done sooner or later.

It has already been done. DIS 8859/1 (it may be a full ISO standard by now)
is an 8-bit extension of ASCII. DEC already have it (almost) and SUN are
moving in that direction. At long last we have a *standard* character set
where C-with-a-ring-around-it is an actual character. The System V
Interface Definition hints that 8-bit characters will be an official part
of some future System V.

Richard Harter

unread,
Mar 3, 1988, 12:12:05 AM3/3/88
to
In article <24...@umd5.umd.edu> ch...@trantor.umd.edu (Chris Torek) writes:
>-In article <24...@cca.CCA.COM> g-...@cca.CCA.COM (Richard Harter) writes:
>-}As a side point, I like the suggestion that someone made that there be
>-}a fallthrough statement rather than automatic fallthrough.

>While this would work, if we assume D has aggregate constructors,


>there is a handsomer way:

> switch (e) {
> case [1, 2, 3, 5, 7, 13, 19, 23]: ...
> }
> /* syntax above is only for demonstration */

Well, yes, one ought to be able to do that. However it is isn't quite
as strong as fallthrough, where one can say

switch (e) {
case foo:
some code;
fallthrough;
case baz:
some more code;
}


In C as it stands now you can do this -- indeed, the complaint is that
one can do this unintentionally. If one adds aggregate constructors and
takes away automatic fallthrough, it seems to me that you weaken the
language. No doubt there are purists that say you shouldn't do the
sort of thing given above. I wouldn't go that far, but I would agree
that one should be able to use aggregate constructors when cases actually
share code.

--

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

Richard Harter

unread,
Mar 3, 1988, 12:34:28 AM3/3/88
to
In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
>In article <24...@cca.CCA.COM> g-...@CCA.CCA.COM.UUCP (Richard Harter) writes:
|| if (boolean expression)
|| ....
|| end
|| else
|| ....
|| end
|
|Note that this does *not* solve the dangling else problem. That being the
|case, I see no reason to prefer it to the current syntax.

I wasn't suggesting it as a resolution of the dangling else problem,
because, as you note, it isn't whether or not one has labels. It struck me
as an idea that might have some value -- and it might if the compiler pro-
duced a listing that labelled each line with the block that was part of.
I am now persuaded that the idea has no particular merit.

If one is really concerned about the dangling else problem there
is a very simple solution -- use different keywords for two sided if's and
one sided if's. For example, the presence of a 'then' keyword guarantees
an 'else' and its absence guarantees the lack of an 'else'. E.g.

if (e1) then
if (e2) A;
else B; <---- this pairs with the first if

if (e1)
if (e2) then A;
else B; <---- this pairs with the second if

if (e1)
if (e2) A;
else B; <---- this is a syntax error

Another cure is to always require that an 'else' statement be
present, even it if it is null. Personally, I am inclined to feel that
all of the cures (including endif) are worse than the disease.

ELIN Forsch.z.

unread,
Mar 3, 1988, 8:23:21 AM3/3/88
to
In article <6...@viper.Lynx.MN.Org> jo...@viper.UUCP (John Stanley) writes:
>
> While I'm totaly against changing the existing functionality of the
>sizeof() operator, what I would be totaly in favor of would be the

>addition-to-ansi-C of a new operator that would have a similar
>functionality, but which would return the number of -bits- in
>something. The name bitsize() would be my suggested name for this
>operator.
>
> This would provide one MAJOR advantage. It would allow writing code
>or header files that would be 100% portable without having to know
>about each and every compiler/OS/machine's identifer defines.

This seems superflous to me. ANSI guarantees sizeof(char) to be 1 and
provides a macro in <limits.h> named CHAR_BIT that expands to the number
of bits used for one char. So the number of bits for a specific data type
is simply sizeof(SpecificDataType)*CHAR_BIT.

>If you
>needed a 12 bit integer type, your headers could have #if statements
>that would provide the next integer type equal or larger that 12 bits.
>No more #ifdef'ing special integer types individualy for each system
>when you're trying to make efficient code run on multiple machines.

You cannot use the sizeof operator in #if expressions as the preporcessor
does not know anything about types. Symetrically it would not know anything
about bit sizes. I cannot see, how you would be able to use bitsize during
preprocessing.

>
> An additional minor advantage would be the capability of writing
>the kinds of functions we normaly use sizeof for to work with bitfield
>variables..
>
> This is a relatively minor addition to any existing compiler
>(multiply sizeof by 8 for most machines... and return the bitsize
>that's probably already a field in the evaluation structure for a
>bitfield variable...) and would make some major advancements possible
>in source code portability...

Try the following:
#define bitsize(whatever) sizeof(whatever)*CHAR_BIT
This has only one disadvantage: you are not able to use a syntax without
parentheses as you can with sizeof (e.g. sizeof "a text").

My opinion is, not to create operators too freely. In C operators have been
chosen in a way, that (nearly) every operator yields in one processor operation
(+, -, ...) or a constant (sizeof). This helps when one has to estimate about
the runtime of a program. For this reason I dislike operators that yield
(always) in functions like power, sin, etc. bitsize does not fall into this
category, but into category of not needed. Anyway such a new operator could
start an inflation that "optimizes away" some nice philosophies of C.

Dietmar Weickert,
ALCATEL-ELIN Research Center, Vienna, Austria.

P.S.: I apologize if my English is of unreadable style!

Herman Rubin

unread,
Mar 3, 1988, 8:52:34 AM3/3/88
to
In article <74...@brl-smoke.ARPA>, gw...@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
> >Clearly, assembler statements should have been defined as:
> >#asm <statement>
> >instead of
> >asm("statement");
>
> A properly-designed system programming language should not have such
> a feature at all. (It is not guaranteed in C, either.)

I agree with Frank on this, but I would even go farther--I would have the
asm on until turned off. Those who believe that the language gurus can
_possibly_ anticipate how someone who understands the machine will want
to do things are either totalitarian, ignorant, or stupid. Quite frequently
I come up with the observation that this feature can be used for something
which I, at least, did not know before. In too many cases, I have seen that
the feature is a misfeature, that with essentially no cost much more could be
attained; this is not just true in programming.

I maintain that anyone who understands whatever computer is being programmed
for will, without effort, see situations in which the HLL concepts (any HLL)
are not the right way to do things. This should be encouraged; progress in
programming should no be based on "thou shalt not do this because

It can be done thusly (but not necessarily efficiently).

It can get you into trouble.

Why would anyone want to do this?"
--
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

Dave Sill

unread,
Mar 3, 1988, 10:07:24 AM3/3/88
to
(I'm risking beating a dead horse here, but I *do* want to make sure
it's dead.)

In article <73...@brl-smoke.ARPA> Doug Gwyn <gw...@brl-smoke.arpa> writes:
>My point is that it does no good to introduce a language that uses
>funny APL-like symbols, when the vast majority of existing and
>near-future terminals and printers won't support the symbols.

I totally agree. It's the latter I lament.

>It isn't clear to me that funny APL-like symbols are preferable to
>short keywords (for example).

It isn't clear to some people that icons are preferable to filenames,
either. However, I think the majority prefers mnemonic symbols for
operators. X <- Y is more mnemonic for assignment than X = Y. Nobody
would really prefer the <- digraph to a real left-arrow character,
though.

>Note that even the mathematicians are
>starting to use such notations in preference to inventing mystical
>symbols, especially in category theory.

I don't know diddly about category theory. But I do know that some
day, maybe 10 years from now, maybe 50 years from now, we will finally
have to admit that the typewriter keyboard designed at the turn of the
century is simply no longer adequate.

As Wittgenstein points out, the limits of our language (or our
alphabet) limit our ability to conceptualize and communicate clearly.
It's not good enough to say that we have an unlimited number of
combinations of characters available so we're really not limited.
That's the equivalent of saying we only need a 5000 (or whatever) word
vocabulary since all others words can be defined using the fixed
vocabulary.

Henry Spencer

unread,
Mar 3, 1988, 1:04:24 PM3/3/88
to
> ... It is just as easy, since C requires a ; to end a statement, to
> tell the compiler that until it sees ); to continue processing for the
> assembler, and to have some escape mechanism for inserting ); into the
> assembler statement...

Have you never heard of string escapes? (If they don't work in asm()s
despite the resemblance to strings, speak to your compiler implementor
about this bug.) Why re-invent the wheel?

Actually, my number one suggestion for D would be to avoid asm() entirely.
My C compiler doesn't support it; oddly enough, I have never missed it.
(It helps that Dennis Ritchie knew how to generate good local code.)
--
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

unread,
Mar 3, 1988, 1:26:45 PM3/3/88
to
> >Most machines cannot handle bits with anywhere near the efficiency
> >with which they handle bytes...
>
> Be careful; cause and effect are circular here. I've been contacted by
> more than one computer architect who wanted bit addressability but had
> trouble convincing management to accept the slightly added expense because
> they would observe that such a facility could not be exploited from popular
> high-level languages...

I once had the opportunity to ask Bill Wulf what he thought of bit-oriented
machines; his answer was "I wish they weren't so damned slow". I'm afraid
I haven't seen anything since that invalidates that assessment. There is
something to be said for providing bit addressability, but one must realize
that actually exploiting it will be slow and that there will still be a
large payoff for trying to work on byte or word boundaries whenever possible.

Also, designing D so it will run real well on our hypothetical dream machine
is probably not a good idea.

> >Please explain how avoiding superfluous words and keeping necessary ones
> >short is consistent with changing {/} to begin/end for no particular reason.
>
> A better reason for a change here is the problems cause by "dangling else"

You misunderstood here, Doug. I have no objection to self-bracketing
control constructs, in fact I quite like them. What I was objecting to was
retaining an explicit bracketing construct but changing its spelling.

Henry Spencer

unread,
Mar 3, 1988, 1:44:03 PM3/3/88
to
>>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.
>
>"Word-addressible cannot handle bytes with anywhere near the efficiency
>with which they handle words; the appropriate base unit for efficient code
>is the word." Right?

See Bliss and BCPL, which were built for word-addressed machines. The fact
is that C assumes a byte-addressible machine. It has been ported to word-
addressed machines; this involves problems, and C programs are sometimes
quite inefficient on such machines, but it does work. Basing C on bytes
was probably the right thing to do (even ignoring the fact that portability
originally wasn't a big consideration), because most modern machines support
them well. I question the wisdom of basing a new portable general-purpose
language on the bit, which very few existing machines support well.

Henry Spencer

unread,
Mar 3, 1988, 1:51:06 PM3/3/88
to
> >I would suggest that "abc" should mean a length-3 string with any necessary
> >terminator, regardless of what flavor of string is in use...
>
> And how do you specify what flavor of string is "is use?".

Pick a way. I can think of several. The point is that the compiler, not
the user, should be charged with translating a string constant into the
correct internal representation. It can generate a count just as easily
as it can generate a trailing NUL, and either way this is much better than
making the programmer do it.

Karl Heuer

unread,
Mar 3, 1988, 2:25:02 PM3/3/88
to

When in doubt, make it a void expression. Personally, I think even strcpy()
should be void.

Alternately, if only one object can be declared per statement, it could return
that object (if it was initialized) or its address (assuming it has one).

paul pedersen

unread,
Mar 3, 1988, 4:56:59 PM3/3/88
to
In article <25...@cca.CCA.COM> g-...@CCA.CCA.COM.UUCP (Richard Harter) writes:
>Well, yes, one ought to be able to do that. However it is isn't quite
>as strong as fallthrough, where one can say
>
> switch (e) {
> case foo:
> some code;
> fallthrough;
> case baz:
> some more code;
> }
>
>
>In C as it stands now you can do this -- indeed, the complaint is that
>one can do this unintentionally. If one adds aggregate constructors and
>takes away automatic fallthrough, it seems to me that you weaken the
>language. No doubt there are purists that say you shouldn't do the
>sort of thing given above. I wouldn't go that far, but I would agree
>that one should be able to use aggregate constructors when cases actually
>share code.
>

Fallthrough may be occasionally justifiable. One good example (stolen
from Knuth's classic article "Structured programming with go to statements")
is a P-code-type interpreter, where the Subtract case may negate one
operand and then branch to the Add case. I think that a better D option
would be to mark this explicitly with the classic language for marking
an "abnormal" transfer of control:

switch (op) {
case Add:
blah-blah-blah
case Subtract:
negate operand;
goto case Add;
/* more cases */
}

This 'goto' is signalled as exceptional by the reserved word 'case' appearing
in place of a label. The use of 'goto' rather than 'fallthrough'
is also superior because it is not as fragile if a new case is introduced.

I do not think, however, that such a "general" concept as either fallthrough
or on-the-fly constructors should be used to support the common
use of multiple cases which execute exactly the same code.
Here some other syntax is needed. The natural 'case a,b,c:' is defeated
by C's comma operator, and 'case a:b:c:' is not LL(1) parseable, but
some other C-ish syntax can probably be invented.

In current practice, when I need to fall through, I always use the conventional
comment /* FALLTHROUGH */ to mark the spot.

Dr. T. Andrews

unread,
Mar 3, 1988, 7:18:42 PM3/3/88
to
Portable "asm". Right. All the world isn't a 68K, but all machines
have the same instruction set and registers.

Now, if I were implementing an "asm" construct, I'd probably do
something cheesy like
#asm
Assembly code here. Syntax as proper for local assembler.
Be sure to enclose the "#asm" block within local #ifdef or
be prepared for a surprise when you try to port. May not
be available on the compiler for the next machine you need.
#endasm

The local pre-processor (if not part of CC) needs to know how to pass
the "#asm" and "#endasm", of course. Put it on the same list as the
thing that passes "#line" constructs.
--
{allegra clyde!codas decvax!ucf-cs ihnp4!codas killer}!ki4pv!tanner

Richard A. O'Keefe

unread,
Mar 3, 1988, 7:37:23 PM3/3/88
to
In article <25...@cca.CCA.COM>, g-...@cca.CCA.COM (Richard Harter) writes:
> If one is really concerned about the dangling else problem there
> is a very simple solution -- use different keywords for two sided if's and
> one sided if's.

BCPL did this: TEST is the two-armed version, and IF the one-armed one.
There was presumably a reason why C did not inherit this feature;
does anyone know what the reason was?

Doug Gwyn

unread,
Mar 4, 1988, 8:14:09 AM3/4/88
to
In article <1988Mar3....@utzoo.uucp> he...@utzoo.uucp (Henry Spencer) writes:
>I once had the opportunity to ask Bill Wulf what he thought of bit-oriented
>machines; his answer was "I wish they weren't so damned slow". I'm afraid
>I haven't seen anything since that invalidates that assessment. There is
>something to be said for providing bit addressability, but one must realize
>that actually exploiting it will be slow and that there will still be a
>large payoff for trying to work on byte or word boundaries whenever possible.

Bit-addressable architectures need not be slow; you could apply the same line
of reasoning to "prove" that byte-addressability makes a machine too slow,
but of course they aren't necessarily slow. The main trick to is handle most
operations at a large alignment and revert to bit accesses only when called
for, in which case they will certainly be faster than the corresponding code
on an equivalent non bit-addressable architecture.

David Collier-Brown

unread,
Mar 4, 1988, 9:09:57 AM3/4/88
to

In article <74...@brl-smoke.ARPA> gw...@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>)
writes:
[re a discussion of "asm" in C]

| A properly-designed system programming language should not have such
| a feature at all. (It is not guaranteed in C, either.) The interface
| between the optimized code produced for the HLL and the in-line
| assembly code is quite problematic. Also, the compiler should not be
| forced to have an assembler built-in just to handle such stuff...

The interfaces are hard, but within state-of-practice (I hate the
idea of assembler escapes for other reasons).

As an example, in Honeywell's experimental ADAsil (an incomplete
implementation of Ada[tm]), one could specify the interface to
either a procedure or instruction, and whether its was to be placed
inline or not. The compiler, having been informed about the
restrictions on parameters via a pragma, arranged to do any register
allocations and transfers required to execute the code.
Specifically, one coded system calls by producing an object file
containing the instruction (a trap), and placing the restrictions,
the request to put it in-line and the requirements in pragmas
preceding the call. The compiler would then insert the instruction,
and make sure the registers were used properly around the
instruction.

Yes, its hard. But it was claimed to have been harder to write
the pragma interpreter to find out what to do than to write the
optimizer code to do it.

--dave c-b
ps: Corrections re difficulty and exact details welcome: this was some
years ago! (Ada is old?)

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

Lawrence Crowl

unread,
Mar 4, 1988, 12:26:51 PM3/4/88
to
In article <1988Mar3....@utzoo.uucp> he...@utzoo.uucp
(Henry Spencer) writes:
>I once had the opportunity to ask Bill Wulf what he thought of bit-oriented
>machines; his answer was "I wish they weren't so damned slow". I'm afraid
>I haven't seen anything since that invalidates that assessment. There is
>something to be said for providing bit addressability, but one must realize
>that actually exploiting it will be slow and that there will still be a
>large payoff for trying to work on byte or word boundaries whenever possible.

It seems to me that aligned access to all items larger than a bit would allow
a bit addressable machine to be every bit as fast as a byte or word addressable
machine. Am I missing something?

A bit addressable machine would allow us to use single bits, nibbles, BCD, etc.
with much greater ease. Besides, bit addressability seems "right". (I know,
"right" isn't a rational statement!)
--
Lawrence Crowl 716-275-9499 University of Rochester
cr...@cs.rochester.edu Computer Science Department
...!{allegra,decvax,rutgers}!rochester!crowl Rochester, New York, 14627

Mark Brader

unread,
Mar 4, 1988, 8:43:25 PM3/4/88
to
Dave Decot (de...@hpisod2.HP.COM) writes:
> Array first-class-ness and aggregate constants could be easily provided
> within C (not that I want to discourage D-zigners; it's a meritorious idea).
>
> The basic ideas are that "a[]" is an array lvalue, and that aggregate
> constants are natively typeless and must always be either cast or assigned
> to the appropriate type. Two examples follow.

The a[] syntax isn't needed, any more than you need a special syntax
for struct assignment. Dave's first example revised:

int thing(i, a, b)[2]
int i, a[2], b[2];
{
int val[2];
...
return val;
}

Since the type to be returned is int[2], the value "val" is left as an
int[2] type item and not converted to int *.

The one thing that would have to change, of course, is the present rule
that the formal parameter declaration int a[2] means int *a. As I have
said before, this rule change could be introduced into the language along
with prototype syntax.

Mark Brader, utzoo!sq!msb, m...@sq.com C unions never strike!

Brian Case

unread,
Mar 4, 1988, 9:38:22 PM3/4/88
to
In article <73...@sol.ARPA> cr...@cs.rochester.edu (Lawrence Crowl) writes:
>In article <1988Mar3....@utzoo.uucp> he...@utzoo.uucp
>(Henry Spencer) writes:
>It seems to me that aligned access to all items larger than a bit would allow
>a bit addressable machine to be every bit as fast as a byte or word addressable
>machine. Am I missing something?

Yes, the alignment network is always there whether an instruction uses it or
not.

Richard Harter

unread,
Mar 5, 1988, 1:30:53 AM3/5/88
to
Here is another feature for D whose absence in C has been irksome to
me -- I would like to be able to return several items from a function.
The problem is that arguments to C are passed by copying the value --
this is loverly since it means that my function can't munge the stuff
passed to it. But how do I get stuff back. I can pass one thing back
via the return statement. To pass more than one thing I have to play
games. Things which are returned need a mechanism equivalent to pass
by address.

An ancient and venerable way to handle this is to have 'in', 'out', and
'update' qualifiers for arguments. I have seen this used in several
languages, and my observation is that it doesn't work; people end up
bypassing the mechanism.

The following example is illustrative syntax only:

[int *,int] foobar();
....
[ptr,flag] = foobar(arg)
int arg;
{
int *a, *b;
....
return [a,1];
....
return [b,0];

Carsten Bormann

unread,
Mar 5, 1988, 11:13:39 AM3/5/88
to
In article <25...@cca.CCA.COM> g-...@CCA.CCA.COM.UUCP (Richard Harter) writes:
[about a solution to get back some expressive power that will be lost if
``case'' implies ``break'':]
() switch (e) {
() case foo:
() some code;
() fallthrough;
() case baz:
() some more code;
() }

(Current) C already has a good fallthrough statement.
It is called (surprise):

goto.

switch (e) {
case foo:
some code;

goto baz_case;
case baz:
baz_case:
some more code;
}

Any optimizer will throw away the superfluous branch implied by the goto.
This also has the advantage to use the existing ``spaghetti code warning''
keyword, and to allow you to give a descriptive name for the ``baz_case''.
Now if D had a comefrom...
--
Carsten Bormann, <ca...@tub.UUCP> <ca...@db0tui6.BITNET> <ca...@tub.BITNET>
Communications and Operating Systems Research Group
Technical University of Berlin (West, of course...)
Path: ...!pyramid!tub!cabo from the world, ...!unido!tub!cabo from Europe only.

Henry Spencer

unread,
Mar 5, 1988, 7:25:18 PM3/5/88
to
> >I once had the opportunity to ask Bill Wulf what he thought of bit-oriented
> >machines; his answer was "I wish they weren't so damned slow". I'm afraid
> >I haven't seen anything since that invalidates that assessment. There is
> >something to be said for providing bit addressability, but one must realize
> >that actually exploiting it will be slow and that there will still be a
> >large payoff for trying to work on byte or word boundaries whenever possible.
>
> It seems to me that aligned access to all items larger than a bit would allow
> a bit addressable machine to be every bit as fast as a byte or word addressable
> machine. Am I missing something?

No and yes.

No, in that this is exactly what I said in the last sentence of my comments,
although somewhat obscurely. (Note that "bit-oriented" and "bit-addressable"
aren't the same thing in the terminology I was using.) As an extreme case,
one can envision a bit-addressable machine -- that is, one whose pointers
use the low-order three bits to indicate a bit within a byte -- that traps
whenever those bits aren't zero, leaving the actual use of bit pointers
entirely up to the software. When all accesses were in fact aligned, this
would incur essentially no overhead except the reduction in address space.

Yes, in that almost any attempt to make bit-aligned objects easier to handle
is going to mean extra hardware, quite possibly in a critical path where
every added gate slows the whole machine down. Even if it's not in a
critical path, it will steal chip area from other things that could boost
performance. The tradeoffs depend on the design details.

Dave Burton

unread,
Mar 5, 1988, 10:07:01 PM3/5/88
to
In article <25...@cca.CCA.COM> g-...@CCA.CCA.COM.UUCP (Richard Harter) writes:
>Here is another feature for D whose absence in C has been irksome to
>me -- I would like to be able to return several items from a function.
>... But how do I get stuff back.
>... Things which are returned need a mechanism equivalent to pass
>by address.

Please don't design D until you understand C.
C has had pass by reference for a very long time (since its inception?).
The following useless code illustrates:

int flag, foobar();
x = foobar(&flag);
...
int foobar(arg)
int *arg;
{
*arg = 1;
return 0;
}

Now, what could be simpler?
--
--------------------"Well, it looked good when I wrote it"---------------------
Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb
V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd.
#include <disclaimer.h> Naperville, IL 60540

Dave Burton

unread,
Mar 5, 1988, 10:18:06 PM3/5/88
to
In article <6...@l.cc.purdue.edu> c...@l.cc.purdue.edu (Herman Rubin) writes:
|In article <74...@brl-smoke.ARPA>, gw...@brl-smoke.ARPA (Doug Gwyn ) writes:
|> In article <27...@mmintl.UUCP> fra...@mmintl.UUCP (Frank Adams) writes:
|> >Clearly, assembler statements should have been defined as:
|> >#asm <statement>
|> >instead of
|> >asm("statement");
|>
|> A properly-designed system programming language should not have such
|> a feature at all. (It is not guaranteed in C, either.)

What's all this about #asm < > ?

First, #asm is really a way to change programming languages in
mid-stream. Second, kindly explain how #asm sections are portable?
Third, why not use separate assembly modules instead? If you _really_ need
the flexibility of assembly to do low-level programming, use an
assembler. I can see no need to mix assembly and C at the C source
level (why was the language designed in the first place?).

|... Those who believe that the language gurus can


|_possibly_ anticipate how someone who understands the machine will want
|to do things are either totalitarian, ignorant, or stupid.

Agreed.
Of course, you are not suggesting that Doug is one of these, are you?

But let's go further on this point:


Those who believe that the language gurus can _possibly_ anticipate

how everyone (knowledgeable, ignorant, other) will want to do _any_
thing are ...

The language gurus themselves do not claim this.
A language is designed to perform a certain class of tasks - even the
class 'general', of which C is not a member. To even start to hope
that a non-machine specific language will produce *truly* optimal
code for other machine architectures is futile. Iff (not a typo) you
really must have use a machine's features for efficiency (which is
the point you argue [...understands the machine...]), drop down to that
machines optimal language, assembly. And do it in a file all by itself.

Do *not* mix languages in a single source file.

|I maintain that anyone who understands whatever computer is being programmed
|for will, without effort, see situations in which the HLL concepts (any HLL)
|are not the right way to do things. This should be encouraged; progress in
|programming should no be based on "thou shalt not do this because
| It can be done thusly (but not necessarily efficiently).
| It can get you into trouble.
| Why would anyone want to do this?"

I disagree. You presume that this same individual also knows how the HLL
implements itself on that machine. This is not the case. Very few people
that know both the HLL and the machine instruction set will know what kind
of code the compiler will produce.

What do you mean by 'progress in programming'?

True, it is unwise to place arbitrary restrictions upon a society
because the ruler-makers deem the masses incapable. (Follow this one
up to talk.flame, or wherever). In the context of programming, especially,
this has a deadening effect. However, for instructional purposes, a few
'thou shalt nots' are highly beneficial.

Herman Rubin

unread,
Mar 6, 1988, 6:13:17 AM3/6/88
to
In article <25...@cca.CCA.COM>, g-...@cca.CCA.COM (Richard Harter) writes:

........

> But how do I get stuff back. I can pass one thing back
> via the return statement. To pass more than one thing I have to play
> games. Things which are returned need a mechanism equivalent to pass
> by address.

No, what is needed is to abandon the mistaken notion that a function
returns a single result. From day one, lists should have been allowed
to the left of the replacement sign--this is not just for functions,
but even for direct operators. For example, the infamous frexp function
in C should not have the syntax

y = frexp(x,&n);

but

y,n = frexp(x);

This would, for example, allow n to be in a register, which is probably
where it should be anyhow.

Another example would be to have

q,r = a///b;

where the quotient and remainder are simultaneously produced. Possibly
if that were in the language, we would not find the operation disappearing
from hardware.

......


>
> The following example is illustrative syntax only:
>
> [int *,int] foobar();
> ....
> [ptr,flag] = foobar(arg)
> int arg;
> {
> int *a, *b;
> ....
> return [a,1];
> ....
> return [b,0];
> }

I would drop the brackets, but otherwise the notation is reasonable.
Another thing is to allow the return value to be stored _before_ the
return statement. It may be desirable to do other computations after
computing the value, especially for functions with side effects, such
as random number procedures.

Richard Harter

unread,
Mar 6, 1988, 2:08:59 PM3/6/88
to
In article <4...@tub.UUCP> ca...@tub.UUCP (Carsten Bormann) writes:
>In article <25...@cca.CCA.COM> g-...@CCA.CCA.COM.UUCP (Richard Harter) writes:
>[about a solution to get back some expressive power that will be lost if
> ``case'' implies ``break'':]
>
>(Current) C already has a good fallthrough statement.
>It is called (surprise):
>goto.

[transferring between cases goto shown.]

But, but, but... I had naturally supposed that the goto would be
dropped from D. :-)

Actually, does anyone use goto's in C to any signifigant extent?
Currently I average about one goto per 10,000 lines of code, all of them
being transfers to a procedure epilog, e.g

foobaz() {
....
allocate space and other setup
....
if (some_special_condition) goto wrapup;
....
wrapup:
deallocate space and other cleanup
}

Almost every language has a goto construct, apparently on the
principle "We know you won't use goto's, but there might be a special
case where you need one, so here it is - better to be safe than sorry."
But do people actually use it to any signifigant extent? Why not just
drop it?

Bob Babcock

unread,
Mar 6, 1988, 5:14:10 PM3/6/88
to
> Almost every language has a goto construct, apparently on the
>principle "We know you won't use goto's, but there might be a special
>case where you need one, so here it is - better to be safe than sorry."
>But do people actually use it to any significant extent? Why not just
>drop it?

I don't understand. First you give a perfectly reasonable example of
the use of goto (which would be awkward to code otherwise), and then
you propose eliminating goto from the language because you don't use
it very often. One of the reasons I like programming in C rather than
(pre-77) Fortran is that you have the flow control constructs
necessary to eliminate abusive use of goto's, but you still have
goto available for the occasional place where it best expresses
what you want to do.

Wayne A. Throop

unread,
Mar 6, 1988, 5:59:44 PM3/6/88
to
> gw...@brl-smoke.ARPA (Doug Gwyn )
>> he...@utzoo.uucp (Henry Spencer)
>>Bill Wulf [... states ...] of bit-oriented
>>machines [...] "I wish they weren't so damned slow". I'm afraid

>>I haven't seen anything since that invalidates that assessment.

I have.

> Bit-addressable architectures need not be slow; you could apply the same line
> of reasoning to "prove" that byte-addressability makes a machine too slow,

Exactly so. The only problem that bit addressability (as opposed to byte
addressability) brings to the game is an eight-times smaller address
space for a given number of bits. But nobody claims that the
four-or-eight-times smaller address space of byte-granular vs
word-granular architectures means word-granular architectures are the
only viable ones, nor that byte-granular ones are noticeably slower.

And having participated in developing language tools for a bit-granular
addressed architecture, I'll add that bit granularity eliminates a whole
raft of inefficent and ugly kludgerey associated with simulating the bit
granularity needed in so many places. I'm convinced it's worth it.

But perhaps I'm misunderstanding what Henry means by "bit-oriented"...
I'm arguing only for bit-granular addressing.

--
IBM manuals are written by little old ladies in Poughkeepsie who are
instructed to say nothing specific.
--- R. T. Lillington
--
Wayne Throop <the-known-world>!mcnc!rti!xyzzy!throopw

Richard Harter

unread,
Mar 6, 1988, 6:31:13 PM3/6/88
to
In article <12...@brl-adm.ARPA> PEPRBV%CFAAMP...@husc6.harvard.EDU (Bob Babcock) writes:

>I don't understand. First you give a perfectly reasonable example of
>the use of goto (which would be awkward to code otherwise), and then
>you propose eliminating goto from the language because you don't use
>it very often. One of the reasons I like programming in C rather than
>(pre-77) Fortran is that you have the flow control constructs
>necessary to eliminate abusive use of goto's, but you still have
>goto available for the occasional place where it best expresses
>what you want to do.

My apologies for muddying the waters. Yes, there are rare occasions where
a goto lets you build by hand a construct that is not available in the
language. Most of these instances reflect deficiencies in the language.
In the example I cited the deficiencies are:

(a) C has two escape statements, break and return. 'return' escapes
from the outermost containing block (the function). 'break' is a little
ambiguous. By analogy one would expect it to escape from the innermost
containing block. Actually, of course, it escapes from loops and switch
control structures. C would be improved if it had better escape constructs.

(b) C has no provision for epilogs -- an epilog being a block of code
executed after an escape. I don't quite see how one puts epilogs in C
in any natural fashion.

The question I was raising was whether the rare instances where a goto
is actually useful warrant retaining it in the language. You and I, of
course, will use them wisely and only when warranted. But I could do
without them in C. The times that I would have to get around not having
them available are few compared to other awkwardnesses in the language.

Incidentally, the objection I have to older Fortran is not so much
the abusive use of goto's (a complaint I will leave to theoreticians)
but is their awkwardness -- expressing any kind of complicated logic
in Fortran 66 is rather like solving a chinese box puzzle.

Dave Decot

unread,
Mar 7, 1988, 2:32:03 AM3/7/88
to
> Dave Decot (de...@hpisod2.HP.COM) writes:
> > The basic ideas are that "a[]" is an array lvalue...
>
> The a[] syntax isn't needed...

>
> int thing(i, a, b)[2]
> int i, a[2], b[2];
> {
> int val[2];
> ...
> return val;
> }
>
> Since the type to be returned is int[2], the value "val" is left as an
> int[2] type item and not converted to int *.

This sounds great; I like the idea that it's possible for the intuitive
array name to refer to the whole array.

However, the meaning of function calls containing array names would
depend so heavily on the declarations of the arguments,
and the fact that it is unworkable without ANSI strong typing,
makes me still lean toward having an explicit way to request what
I want to happen. Perhaps this would be desirable for no other
reason than to allow cc or lint to catch misuses.

For instance, I'm not sure how to tell varargs functions whether
I'm talking about an array pointer or a whole array if the name
might mean either.

Dave Decot
hpda!decot

Dave Decot

unread,
Mar 7, 1988, 2:41:48 AM3/7/88
to
> The following example is illustrative syntax only:
>
> [int *,int] foobar();
> ....
> [ptr,flag] = foobar(arg)
> int arg;
> {
> int *a, *b;
> ....
> return [a,1];
> ....
> return [b,0];
> }

How about this syntax:

struct foo { int *x, y; } foobar();

struct foo foobar(arg)


int arg;
{
int *a, *b;

...
return {a, 1};
...
return {b, 0};
}

This way, all you're adding to the existing language is aggregate expressions.

Dave Decot
hpda!decot

ELIN Forsch.z.

unread,
Mar 7, 1988, 4:31:41 AM3/7/88
to
In article <77...@alice.UUCP> a...@alice.UUCP writes:
>The best scheme I've seen for labelled blocks comes from SETL.
>In SETL, statements like `IF' and `WHILE' begin blocks which
>must be ended by `END' statements. Thus one can write:
>
> IF x > y
> THEN max := x;
> ELSE max := y;
> END;
>
>(I think I have the semicolons right; I'm sure about the one after END)
>
>When these structures are nested deeply, one may be confused about
>just what is being ended. To reduce confusion, the programmer may
>insert any number of tokens from the opening statement between the
>END and the semicolon:
>
> IF x > y
> THEN max := x;
> ELSE max := y;
> END IF x > y;
>
>These tokens are optional, but if they appear, they must match
>the corresponding tokens from the opening statement.

CHILL (CCITT High Level Language, a realtime application language)has a similar
but less confusing syntax:

IF x > y
max := x;
ELSE
max := y;
FI;

There is also somethimg similar to the repetition of the opening statement
at the end:

Label: BEGIN
blah blah
END Label;

This syntax helps the programmer to find better structures, but unfortunately
the compilers cannot use the redundancy for a better recovery. The only
advantage are sometimes improved error messages. Besides, studying this
language will show anybody who is interested, how a language may be designed
in a most horrible way from the compiler writer's point of view (many many
keywords, indeterminisms, semantics nobody understands totally, etc.).

Dietmar Weickert,
ALCATEL-ELIN Research Center, Vienna, Austria.

Michael R. DeCorte

unread,
Mar 7, 1988, 9:13:38 AM3/7/88
to
Posting-Front-End: GNU Emacs 18.47.2 of Thu Dec 10 1987 on sun.mcs.clarkson.edu (berkeley-unix)


In article <7...@l.cc.purdue.edu> c...@l.cc.purdue.edu (Herman Rubin) writes:

No, what is needed is to abandon the mistaken notion that a function
returns a single result. From day one, lists should have been allowed
to the left of the replacement sign--this is not just for functions,
but even for direct operators. For example, the infamous frexp function
in C should not have the syntax

y = frexp(x,&n);

but

y,n = frexp(x);


Isetl has something of this sort. In Isetl [1,2,3] is a tuple and
if you say
[a,b] := [b,a];
you have a swap routine.

[a,b,c] := f();

and f() returns [1,2,3] you will get the assignments that you want.


Views expressed here do not represent Clarkson University or any part of it.
Michael DeCorte // (315)268-3704 // P.O. Box 652, Potsdam, NY 13676
Internet m...@clutx.clarkson.edu // BIX DMichael
Bitnet m...@clutx.bitnet // Compuserve 72220,3724

Tim Boemker

unread,
Mar 7, 1988, 5:42:20 PM3/7/88
to
Since the interface between C and in-line asm seems to be so
problematic (not to mention non-portable), why not write
those routines that should be written in assembly in assembly?

(Please don't tell me about needing just a rotate here or there
for performance; reconsider the original partitioning of the task
and find an alternative that separates the high-level part and
the low-level part.)

(Yes, I have written separately compiled assembly routines, and
I have repartitioned tasks to find an aesthetically appealing,
efficient alternative.)

Tim Boemker

Earl Killian

unread,
Mar 7, 1988, 6:39:00 PM3/7/88
to

In article <73...@sol.ARPA> cr...@cs.rochester.edu (Lawrence Crowl) writes:

A bit addressable machine would allow us to use single bits,
nibbles, BCD, etc. with much greater ease. Besides, bit
addressability seems "right". (I know, "right" isn't a rational
statement!)

It's more right in certain environments. For example the TI 34010
graphics processor is bit-addressed, which is a good match for pixel
operations. Also, when we have 64-bit addresses, using bit addresses
will make sense (this is independent of whether you have bit
load/stores).

Richard A. O'Keefe

unread,
Mar 7, 1988, 7:47:05 PM3/7/88
to
In article <25...@cca.CCA.COM>, g-...@cca.CCA.COM (Richard Harter) writes:
> Currently I average about one goto per 10,000 lines of code, all of them
> being transfers to a procedure epilog, e.g
>
> foobaz() {
> ....
> allocate space and other setup
> ....
> if (some_special_condition) goto wrapup;
> ....
> wrapup:
> deallocate space and other cleanup
> }
>
> But do people actually use it to any signifigant extent? Why not just
> drop it?
> --

I very often write code of the form

sometype foo()
{
int state = 0;

<side effect 1> /* open file, or allocate memory */
state = 1;
<side effect 2> /* same sort of thing */
...
state = N;
<return new object>
ERROR:
switch (state) {
case N: /* undo side effect N */
/* falls through to */
case N-1: ...


case 1: /* undo side effect 1 */
case 0: /* return error code */
}
}

If you are trying to write code that other people can use,
it really isn't good manners to lose chunks of memory just
because you couldn't open a file. One of these per library
package, and one per program, doesn't seem excessive.

This is a sufficiently stylised approach that it could be replaced by
some other mechanism. (Nested exception handlers? C++ destructors?
unwind-protect?) But in a language like C, why not just keep the goto?
{Actually, a break-from-labelled-statement would work too, but that's
just another goto.}

There's another reason for retaining the goto. Look at the output of
YACC some time. I counted five labels in yyparse(), but may have
missed some. It isn't just people who write C, you know! Why shouldn't
people be allowed to write compilers which generate C?

Richard A. O'Keefe

unread,
Mar 7, 1988, 8:12:16 PM3/7/88
to
In article <7...@l.cc.purdue.edu>, c...@l.cc.purdue.edu (Herman Rubin) writes:
> No, what is needed is to abandon the mistaken notion that a function
> returns a single result. From day one, lists should have been allowed
> to the left of the replacement sign--this is not just for functions,
> but even for direct operators.
MESA does this. Every function in MESA takes a record as argument and
delivers a record as result. Since MESA has keyword constructors for
records, this magically yields keyword inputs _and_ keyword results.
It is loading more messages.
0 new messages