[comp.lang.c] The D Programming Language

dsill@NSWC-OAS.arpa (Dave Sill) (02/08/88)

>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

rrr@naucse.UUCP (Bob Rose ) (02/08/88)

In article <11702@brl-adm.ARPA>, dsill@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

pardo@june.cs.washington.edu (David Keppel) (02/08/88)

In article <11702@brl-adm.ARPA> dsill@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

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

gpollice@eagle_snax.UUCP ( Sun ECD Software) (02/09/88)

In article <11702@brl-adm.ARPA> dsill@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: gpollice@sun.com
Two Federal Street       | UUCP:    {decwrl,ihnp4,hplabs,ucbvax}!sun!gpollice
Billerica, MA  01821     | (617)671-0374

karl@haddock.ISC.COM (Karl Heuer) (02/10/88)

In article <558@naucse.UUCP> rrr@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 karl@haddock.isc.com), The Walking Lint
KWZH: We need a construct like `e1 UNLESS IT==0 INWHICHCASE e2'.
GCJ:  Yes, and also `IFONTHEOTHERHAND ... WEMAYSAFELYASSUME'.

sbw@naucse.UUCP (Steve Wampler) (02/10/88)

In article <2523@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes:
> In article <558@naucse.UUCP> rrr@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}

daveb@geac.UUCP (David Collier-Brown) (02/12/88)

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@haddock.ISC.COM (Karl Heuer) (02/17/88)

In article <563@naucse.UUCP> sbw@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.)

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

sbw@naucse.UUCP (Steve Wampler) (02/17/88)

In article <2595@haddock.ISC.COM>, karl@haddock.ISC.COM (Karl Heuer) writes:
> In article <563@naucse.UUCP> sbw@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}

franka@mmintl.UUCP (Frank Adams) (02/19/88)

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@haddock.ISC.COM (Karl Heuer) (02/19/88)

In article <580@naucse.UUCP> sbw@naucse.UUCP (Steve Wampler) writes:
>In article <2595@haddock.ISC.COM>, karl@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.)

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

flaps@dgp.toronto.edu (Alan J Rosenthal) (02/19/88)

In article <558@naucse.UUCP> rrr@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 <2523@haddock.ISC.COM> karl@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"

bts@sas.UUCP (Brian T. Schellenberger) (02/19/88)

|> In article <558@naucse.UUCP> rrr@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 

gsarff@argus.UUCP (gary sarff) (02/20/88)

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@trantor.umd.edu (Chris Torek) (02/20/88)

In article <2718@mmintl.UUCP> franka@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: chris@mimsy.umd.edu		Path: not easily reachable

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/21/88)

In article <2327@umd5.umd.edu> chris@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..

edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (02/21/88)

> >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: edw@ius1.cs.cmu.edu

jbn@glacier.STANFORD.EDU (John B. Nagle) (02/21/88)

     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

cdaf@iuvax.UUCP (Charles Daffinger) (02/22/88)

In article <2718@mmintl.UUCP> franka@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 /  cdaf@iuvax.cs.indiana.edu
Bloomington, IN 47402-1662            {pur-ee,rutgers,pyramid,ihnp4}!iuvax!cdaf
Home of the Whitewater mailing list:    whitewater-request@iuvax.cs.indiana.edu

noise@eneevax.UUCP (Johnson Noise) (02/22/88)

In article <6306@iuvax.UUCP> cdaf@iuvax.UUCP (Charles Daffinger) writes:
>In article <2718@mmintl.UUCP> franka@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.

mcdonald@uxe.cso.uiuc.edu (02/22/88)

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.

yuval@taux01.UUCP (Gideon Yuval) (02/24/88)

> 	 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), yuval@taux02.nsc.com

franka@mmintl.UUCP (Frank Adams) (02/24/88)

In article <2327@umd5.umd.edu> chris@trantor.umd.edu (Chris Torek) writes:
|In article <2718@mmintl.UUCP> franka@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.
-- 

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

g-rh@cca.CCA.COM (Richard Harter) (02/25/88)

In article <2731@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>In article <2327@umd5.umd.edu> chris@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@aiva.ed.ac.uk (Richard Tobin) (02/26/88)

In article <915@PT.CS.CMU.EDU> edw@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.Tobin@uk.ac.ed             
AI Applications Institute,             ARPA:  R.Tobin%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University.                  UUCP:  ...!ukc!ed.ac.uk!R.Tobin

msb@sq.uucp (Mark Brader) (02/26/88)

> 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, msb@sq.com				-- Michael DeCorte

henry@utzoo.uucp (Henry Spencer) (02/26/88)

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

gordan@maccs.UUCP (gordan) (02/27/88)

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

jejones@mcrware.UUCP (James Jones) (02/27/88)

In article <1988Feb25.202237.8688@utzoo.uucp>, henry@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

ok@quintus.UUCP (Richard A. O'Keefe) (02/27/88)

In article <24935@cca.CCA.COM>, g-rh@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.)

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/28/88)

In article <1988Feb25.202237.8688@utzoo.uucp> henry@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?

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/28/88)

In article <1020@maccs.UUCP> gordan@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".

joe@logi-dc.UUCP (Joe Dzikiewicz) (03/01/88)

Here's an operator I would like to see.  It involves structure pointers...

	struct a
	{
		struct a *a_ptr;
		...
	} *ptr_to_a;

	...
	ptr_to_a => a_ptr;


This would be equivalent to:

	ptr_to_a = ptr_to_a->a_ptr;


This would not allow you to do anything you can't do anyway, but it
would reduce the needed keystrokes (and isn't that what 'C' is all
about anyway? :-).

			Joe Dzikiewicz
			joe@logi-dc

gamiddleton@watmath.waterloo.edu (Guy Middleton) (03/01/88)

In article <24996@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
> In article <703@cresswell.quintus.UUCP> ok@quintus.UUCP (Richard A. O'Keefe) writes:
> >In article <24935@cca.CCA.COM>, g-rh@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@riddle.UUCP (Jonathan Leffler) (03/01/88)

In article <6306@iuvax.UUCP> cdaf@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 (john@sphinx.co.uk)

franka@mmintl.UUCP (Frank Adams) (03/01/88)

In article <24935@cca.CCA.COM> g-rh@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                           ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate          52 Oakland Ave North         E. Hartford, CT 06108

franka@mmintl.UUCP (Frank Adams) (03/01/88)

In article <1988Feb25.202237.8688@utzoo.uucp> henry@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                           ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate          52 Oakland Ave North         E. Hartford, CT 06108

decot@hpisod2.HP.COM (Dave Decot) (03/01/88)

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;
{
    /* ... */
}

wes@obie.UUCP (Barnacle Wes) (03/01/88)

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

dsill@NSWC-OAS.arpa (Dave Sill) (03/02/88)

In article <225800007@uxe.cso.uiuc.edu> mcdonald@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

dsill@NSWC-OAS.arpa (Dave Sill) (03/02/88)

(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

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/02/88)

In article <12059@brl-adm.ARPA> dsill@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@haddock.ISC.COM (Karl Heuer) (03/02/88)

>In article <1988Feb25.202237.8688@utzoo.uucp> henry@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 <7359@brl-smoke.ARPA> gwyn@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 karl@haddock.isc.com), The Walking Lint

karl@haddock.ISC.COM (Karl Heuer) (03/02/88)

In article <7362@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <1020@maccs.UUCP> gordan@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".

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.

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

dsill@NSWC-OAS.arpa (Dave Sill) (03/02/88)

>In article <12059@brl-adm.ARPA> dsill@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@ghostwheel.UUCP (Ned Nowotny) (03/03/88)

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 (ned@ghostwheel.aca.mcc.com.UUCP)

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/03/88)

In article <2809@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>If sizeof were measured in bits ...
>In article <7359@brl-smoke.ARPA> gwyn@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?

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/03/88)

In article <2810@haddock.ISC.COM> karl@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.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/03/88)

In article <12073@brl-adm.ARPA> dsill@NSWC-OAS.arpa (Dave Sill) writes:
>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.

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.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/03/88)

In article <2737@mmintl.UUCP> franka@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.

flaps@dgp.toronto.edu (Alan J Rosenthal) (03/03/88)

In article <105@logi-dc.UUCP> joe@logi-dc.UUCP (Joe Dzikiewicz) writes:
>	ptr_to_a => a_ptr;
>
>This would be equivalent to:
>
>	ptr_to_a = ptr_to_a->a_ptr;

the correct operator is probably '->=' rather than '=>', by analogy with
'+=' and friends.  (this wouldn't even change the meaning of "a-->=b"...)
-- 
If you had eternal life, would you be able to say all the integers?

franka@mmintl.UUCP (Frank Adams) (03/03/88)

In article <264@aiva.ed.ac.uk> richard@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.
-- 

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

ok@quintus.UUCP (Richard A. O'Keefe) (03/03/88)

In article <12059@brl-adm.ARPA>, dsill@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.

g-rh@cca.CCA.COM (Richard Harter) (03/03/88)

In article <2736@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>In article <24935@cca.CCA.COM> g-rh@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.
-- 

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

dsill@NSWC-OAS.arpa (Dave Sill) (03/03/88)

(I'm risking beating a dead horse here, but I *do* want to make sure
it's dead.)

In article <7399@brl-smoke.ARPA> Doug Gwyn <gwyn@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.

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

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

henry@utzoo.uucp (Henry Spencer) (03/04/88)

> >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.
-- 
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@utzoo.uucp (Henry Spencer) (03/04/88)

>>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.
-- 
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@utzoo.uucp (Henry Spencer) (03/04/88)

> >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.
-- 
Those who do not understand Unix are |  Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly.    | {allegra,ihnp4,decvax,utai}!utzoo!henry

karl@haddock.ISC.COM (Karl Heuer) (03/04/88)

In article <7395@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn) writes:
>In article <2809@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>>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?

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

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

ok@quintus.UUCP (Richard A. O'Keefe) (03/04/88)

In article <25203@cca.CCA.COM>, g-rh@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?

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/04/88)

In article <1988Mar3.182645.703@utzoo.uucp> henry@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.

msb@sq.uucp (Mark Brader) (03/05/88)

Dave Decot (decot@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, msb@sq.com		C unions never strike!

g-rh@cca.CCA.COM (Richard Harter) (03/05/88)

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];
}


 
-- 

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

daveb@laidbak.UUCP (Dave Burton) (03/06/88)

In article <25284@cca.CCA.COM> g-rh@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

cik@l.cc.purdue.edu (Herman Rubin) (03/06/88)

In article <25284@cca.CCA.COM>, g-rh@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.

-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet

throopw@xyzzy.UUCP (Wayne A. Throop) (03/07/88)

> gwyn@brl-smoke.ARPA (Doug Gwyn )
>> henry@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

decot@hpisod2.HP.COM (Dave Decot) (03/07/88)

> Dave Decot (decot@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

mrd@sun.soe.clarkson.edu (Michael R. DeCorte) (03/07/88)

Posting-Front-End: GNU Emacs 18.47.2 of Thu Dec 10 1987 on sun.mcs.clarkson.edu (berkeley-unix)


In article <700@l.cc.purdue.edu> cik@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 mrd@clutx.clarkson.edu  // BIX        DMichael 
Bitnet   mrd@clutx.bitnet        // Compuserve 72220,3724

ok@quintus.UUCP (Richard A. O'Keefe) (03/08/88)

In article <700@l.cc.purdue.edu>, cik@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.

mark@applix.UUCP (Mark Fox) (03/08/88)

In article <670@xyzzy.UUCP> throopw@xyzzy.UUCP (Wayne A. Throop) writes:
+++henry@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.
 
+Wayne Throop      <the-known-world>!mcnc!rti!xyzzy!throopw

Come on Wayne, FHP was fast?
-- 
                                    Mark Fox
       Applix Inc., 112 Turnpike Road, Westboro, MA 01581, (617) 870-0300
                    uucp:  {ames,rutgers}!harvard!m2c!applix!mark

g-rh@cca.CCA.COM (Richard Harter) (03/08/88)

In article <1354@laidbak.UUCP> daveb@laidbak.UUCP (Dave Burton) writes:
>In article <25284@cca.CCA.COM> g-rh@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.

Er, Dave, may I suggest it is inadvisable to make remarks such as
"Please don't design D until you understand C".  I am not a C guru;
I read with respect the comments of people such as Chris Torek and
Henry Spencer.  I don't need to be a complete expert in the language.
None-the-less I have been programming for 27 years, writing C for six
of those years, have written ~100,000 lines of C, and have dealt with
the vagaries of C implementations on a variety of operating systems.  

>C has had pass by reference for a very long time (since its inception?).

Actually C has never had pass by reference -- what it has had is a facility
for simulating call by reference, which is a somewhat different matter.

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

And this is what I was alluding to when I referred to playing games with
pointers.  In the call statement you have to add an &; in each reference
in the routine you add a *.  You have to also select one item as a 
distinguished item which is returned by the function among those that
are returned.  Of course you can do this -- you don't have much option
about it.  But it is a kludge, and it is prone to error.  Throughout the
code you "mean" flag, but sometimes you write &flag, and sometimes you
write *flag, depending on where you are.  Fortunately, the effects of
ommitting an & or a * are so drastic that typographic bugs of this sort
are caught immediately.  But I've seen it come up a number of times.

A more subtle point is that there is a difference in semantics between
returning a list and passing things through the calling sequence.  A
returned value is private unless it is explictly declared as a global;
an item passed through a calling sequence may be a global and the called
routine does not know this.  For example,

FILE 1:

int x;
foo () {
  ....
  x = 2;
  baz(x,&x);
  }

FILE 2:

extern x;
baz(in,out)
  int in, *out;
{
  *out = 1;
  ...
  *out = *out + x;
  }

is quite different from the same code where baz is a function returning
a value which is declared internally.  Call by reference is subject to
unintended aliasing, whether it be real call by reference or simulated
call by reference.

Finally, there is one other annoying consequence of the pointer hack.
You can run into pointer to 0 dereferencing problems if you aren't
careful.  You shouldn't, but you can.
-- 

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

jbn@glacier.STANFORD.EDU (John B. Nagle) (03/09/88)

    If you want multiple values from functions, look at Mesa, which offers
an efficient approach.  In Mesa, all functions effectively take one argument
and return one result, but both are structures.  The normal function call
syntax is treated as a structure constructor which builds a structure out
of the arguments, then passes the structure as a unit.  The structure is usually
built on the stack, and thus this is equivalent in an implementation sense
to the passing of parameters on the stack.  In turn, a function returns a
result which is a structure.  The space for that structure is allocated by
the caller, on the stack, and its address is passed to the function, which
then fills it in.

    This approach seems to work.

rrr@naucse.UUCP (Bob Rose ) (03/09/88)

In article <1354@laidbak.UUCP>, daveb@laidbak.UUCP (Dave Burton) writes:
> In article <25284@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
> >I would like to be able to return several items from a function.
> 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?
Easy

	[int, int] foobar()		/* prototype */

	....
	[x, flag] = foobar();
	....

	[int, int] foobar()
	{
		return [0, 1];
	}

Yes I admit this looks a bit strange but look at some of the things
we can do with multi assignments

	[x, y] = [y, x]		/* swap */

The only question is should we be allowed to index this stuff so

	if (([x, flag] = foobar())[1]) {
		/* the flag was true */
		....
	}

Anyone for comp.lang.d

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

cik@l.cc.purdue.edu (Herman Rubin) (03/09/88)

In article <17351@glacier.STANFORD.EDU>, jbn@glacier.STANFORD.EDU (John B. Nagle) writes:
> 
>     If you want multiple values from functions, look at Mesa, which offers
> an efficient approach.  In Mesa, all functions effectively take one argument
> and return one result, but both are structures.  The normal function call
> syntax is treated as a structure constructor which builds a structure out
> of the arguments, then passes the structure as a unit.  The structure is usually
> built on the stack, and thus this is equivalent in an implementation sense
> to the passing of parameters on the stack.  In turn, a function returns a
> result which is a structure.  The space for that structure is allocated by
> the caller, on the stack, and its address is passed to the function, which
> then fills it in.
> 
>     This approach seems to work.

There are two problems with this.  While using stacks may be easy to program,
it involves lots of loads and stores.  I know of at least one machine on which
the normal subroutine call and return do not use stacks.  Furthermore, if the
called routine may make additional calls, it may be necessary to use a 
separate return stack, and this may require each such subroutine to maintain
its own return stack.  In some cases this should be the way to do things,
but not always.

Another problem comes with inline functions.  I believe that many function
calls, if not most, should be inline.  In this case, I think the result should
go to its destination at the time produced.  If the destinations involve
registers or register indirects, the expression of the algorithm must take
the busy set of registers into account.  This admittedly makes coding 
difficult, and is one reason why I believe DNA can optimize better than
silicon.  (The two should be used together, but I do not know of any compiler
which allows the programmer to even give it a hint as to how to optimize,
let alone improve the resulting product.)


-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (ARPA or UUCP) or hrubin@purccvm.bitnet

twb@hoqax.UUCP (BEATTIE) (03/09/88)

I have been trying to ignore this D discussion but it seems to be going on
forever.

Why is this D discussion in the C group?

daveb@laidbak.UUCP (Dave Burton) (03/10/88)

Sorry if this is a repost. The first one escaped while I wasn't looking :-).
-- (how fast is a cancel, anyway?) --

In article <25387@cca.CCA.COM> g-rh@CCA.CCA.COM.UUCP (Richard Harter) writes:
|In article <1354@laidbak.UUCP> daveb@laidbak.UUCP (Dave Burton) writes:
|>	int flag, foobar();
|>	x = foobar(&flag);
|>	...
|>	int foobar(arg)	int *arg;
|>	{ *arg = 1; return 0; }
|And this is what I was alluding to when I referred to playing games with
|pointers.  In the call statement you have to add an &; in each reference
|in the routine you add a *.  You have to also select one item as a 
|distinguished item which is returned by the function among those that
|are returned.

I don't think this would usually be a problem. Of the set of functions that
_must_ return more than one value, a healthy percentage are also modifying
a parameter, so the variable will be passed anyway. Of the remaining set,
the returned data is usually logically related, so arguably an aggregate of
some type should be used. In my opinion, this leaves only a small set of
functions which _must_ return more than one value. I do not deem this to
be of enough value to change a language (since D is supposedly a successor).

|But it is a kludge, and it is prone to error.  Throughout the
|code you "mean" flag, but sometimes you write &flag, and sometimes you
|write *flag, depending on where you are. 

When actually writing the code, I think the proper form would be clear
from the context. Of course, somebody will post a winner of the
obfuscated C contest to disprove this statement :-). Quite seriously,
I don't believe this to be a problem in _well structured code_. If
your functions are well defined, and they are presented clearly in your
code, neither the coder nor the maintenance programmer will have much
trouble understanding the differences. Such code will also use the power
of separate compilation, so there is a good chance these routines will
be in separate modules, further eliminating confusion.

|A more subtle point is that there is a difference in semantics between
|returning a list and passing things through the calling sequence.  A
|returned value is private unless it is explictly declared as a global;
|an item passed through a calling sequence may be a global and the called
|routine does not know this.  For example,
|FILE 1:
|	int x;
|	foo () { x = 2; baz(x,&x); }
|FILE 2:
|	extern x;
|	baz(in,out) int in, *out;
|	{ *out = 1; *out = *out + x; }
|is quite different from the same code where baz is a function returning
|a value which is declared internally.

Your point is well taken. I think the example is somewhat contrived, though.
Good program design would eliminate the need(?) for this type of construction.

|Call by reference is subject to
|unintended aliasing, whether it be real call by reference or simulated
|call by reference.

Aliasing is not limited to function calls (notice I didn't say unintended
aliasing). List return types could save a programmer from some unintentional
aliasing problems, and this is a Good Thing. But it doesn't really solve the
problem in the first place. Neither does noalias :-).

A further note on list returns:
Since there is no explicit return variable matching between caller and
callee, what would stop the programmer from committing a more serious error,
namely reversing or (for more than two returns), switching the returned values
around. I rather think this would open a whole new can of worms (how many
times have you put the parameters in improperly on a function call?). Think of
the additional time spent looking up references to functions, not only to get
the parameters right, but also the multiple return values (now, which order
did they come in?).

A win for passing pointers vs. aggregates: (this does relate - list returns
will usually not pass pointers around, but rather entire objects).
Then there is the issue of speed and efficiency. 
I resist the temptation to put structures on the stack when passing
parameters. The overhead involved in placing the thing on the stack,
operating on it there, then removing it upon return (after copying the
values back off the stack) can be large. A pointer to the aggregate works
very well, and it is much more likely the machine will have hardware support
for handling a pointer. This is both a time and a space win. Moreover, this
treatment (passing a pointer) of structs is in keeping with C's treatment
of another aggregate, arrays. Treating like classed objects similarly is
a win in the clarity and confusion department.

|Finally, there is one other annoying consequence of the pointer hack.
|You can run into pointer to 0 dereferencing problems if you aren't
|careful.  You shouldn't, but you can.

But this is present wherever pointers are, so in this context it does
not really add to your argument.
-- 
--------------------"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

stuart@bms-at.UUCP (Stuart D. Gathman) (03/11/88)

In article <700@l.cc.purdue.edu>, cik@l.cc.purdue.edu (Herman Rubin) writes:
> 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

Another example is string comparison.  I use a string compare function
that returns the index of the first different character.  I also
need the gt/lt/eq result.  Fortunately, in this case it is easily 
computed by recomparing the chars at the index.  This is another case
of a double valued hardware primitive.  (Available on all three
of the architectures we use: Series/1, 80286, 68020.)
-- 
Stuart D. Gathman	<stuart@bms-at.uucp>
			<..!{vrdxhq|daitc}!bms-at!stuart>

daniels@teklds.TEK.COM (Scott Daniels) (03/12/88)

In article <587@bms-at.UUCP> stuart@bms-at.UUCP (Stuart D. Gathman) writes:
>Another example is string comparison.  I use a string compare function
>that returns the index of the first different character.  I also
>need the gt/lt/eq result.  Fortunately, in this case it is easily 
>computed by recomparing the chars at the index. 

An alternative is the string comparison I normally use:

	cmpstr(s1,s2)
0: if equal
>0: if s1 > s2
<0: if s1 < s2

abs(cmpstr(s1,s2)) is the number of chars compared:
  s1[ abs(cmpstr(s1,s2))-1 ] != s2[ abs(cmpstr(s1,s2))-1 ]
  if cmpstr did not return 0.  Normally this function returns just
  about any information I need, and it is usually not very hard to
  make an extremely fast version in assembly.

-Scott Daniels (daniels@teklds.TEK.COM)

blu@hall.cray.com (Brian Utterback) (03/17/88)

In article <1354@laidbak.UUCP> daveb@laidbak.UUCP (Dave Burton) writes:
>In article <25284@cca.CCA.COM> g-rh@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?
> Verbal: Dave Burton                        Net: ...!ihnp4!laidbak!daveb

Well, of course that works, but I think the original poster had something else 
in mind.  I think the question was not so much how could you change things
passed to the function, but rather how do we pass more than one thing 
back without changing the original parameters.  He still wanted pass by
value, but with some mechanism for returning several values.  He even 
mentioned having "in", "out" , and "update" parameters, but rejected these as
being unused in current implementations, presumably because users don't
like them.

For instance, you might want to code a function that emulates a Turing Machine.
This function would take a state and an input symbol, and it would return
a new state and an output symbol.  You could pass 4 parameters, 2 by value
for input and 2 by address for the return values, but it would be more natural
to want the function to return the 2 values.  Personally, I prefer having the
extra parameters in the call.  I can see where it would be nice to have
some form of documenting the parametrs like in,out, and update, but that's
more ada than C.  

Boy, you guys should complain.  I used to program APL. We only had 2 input
parameters, and one output.  And I still liked it alot.

Nowadays, you can get APL2 which has multiple input parameters.  Feh.  The
syntax is impenetrable, even for APL.



-- 
Brian Utterback     |UUCP:{ihnp4!cray,sun!tundra}!hall!blu | Think of it as
Cray Research Inc.  |ARPA:blu%hall.cray.com@uc.msc.umn.edu |  evolution in
One Tara Blvd. #301 |                                      |     action
Nashua NH. 03062    |Tele:(603) 888-3083                   |

kishore@ms.uky.edu (Kishore K. Seshadri) (03/19/88)

> In article <7362@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
> >In article <1020@maccs.UUCP> gordan@maccs.UUCP (gordan) writes:
> >technical problems, it must continue to be tolerated.  Fix it in "D".
All you guys keep talking about "D". Since C came out of BCPL as did the
earlier B, the successor to C should really be named "P"...
I guess you could say I'm being picky...but this is just for the record.
So lets start working on L huh?