Expression Based Language

Karl Heuer karl at haddock.ima.isc.com
Fri Jan 6 10:32:21 AEST 1989


(I've added comp.lang.c to the distribution, since a lot of D-designers hang
out there, but I've redirected followups back to comp.lang.misc, since that's
where the discussion seems to belong.  c.l.c readers should subscribe to c.l.m
if they want to continue this thread.)

In article <9310 at ihlpb.ATT.COM> nevin1 at ihlpb.UUCP (55528-Liber,N.J.) writes:
>In article <2583 at ficc.uu.net> peter at ficc.uu.net (Peter da Silva) writes:
>>I once modified a version of the small-C compiler to make 'C' a completely
>>expression-based language. The changes are really very minor (at least for
>>that case... I don't know quite how full 'C' would take it).
>
>This won't work too well in (full) C.  The problem is that pure
>expression-based languages (like LISP) tend to be typeless as well.
>Having to return a specific data type severely limits the usefulness of making
>control-flow constructs (if, switch, for, etc.) expression-oriented.

Let's try to define EC, an extension of C with the property that every
statement is an expression, yet retaining the property that every expression
has a type.  All constructs with no reasonable value definition become void
expressions.  This includes else-less if, default-less switch, any if- or
switch-statement with branches of incompatible type, and any top-testing loop.
Do-while can be defined to return the value of the last iteration of the loop
body.

The restriction against test-at-top is annoying, but the language must be
prepared to have a value for a loop that executes zero times.  This suggests
that one ought to be able to attach an `else' clause to such a loop.  (I once
had a student who kept trying to do this in Pascal...)  Of course, since
`while (A) B;' is equivalent to `if (A) do B; while (A);', this functionality
is already available by explicitly writing `if (A) {do B; while (A);} else C;',
but a simple `while (A) B; else (C);' would be a more compact way to write it.
(Though it would break C compatibility.)

What about break statements?  We'd probably be better off with a syntax
change, writing `break (EXPR);' to specify the value to be returned by the
enclosing loop or switch.  If we use the current syntax, then in order for a
statement `switch (A) { case 0: B; break; default: C; break; }' to have the
obvious value (A==0?B:C), the rule must be that the value of a switch
statement is that of the statement *preceding* the break.  An analogous rule
could be applied to a break inside a do-while.  (As always, when the rules do
not apply or do not yield a compatible type, the entire expression would be
void-valued for all paths.)

I'm not sure what to do about continue.  If the `else' extension is added,
then a continue which causes the loop to exit (because the retested condition
is now false) could trigger the `else' clause.  (Which would mean that even a
do-while would have use for an else.)  Alternately, a continue could obtain a
value in the same way that a break does, but use it only if the loop test
fails.

Passing values through a goto doesn't seem to work well, since a label by
itself is not a valid statement.  Well, I guess we could say that a labeled
null statement has the value of the statement preceding the goto, but that's
stretching the idea a bit too far, I think.  (I did once suggest this for a
dialect of TECO: I wanted `5 Ofoo$ ... !foo! UX' to assign 5 to register X,
which TECO-10 didn't do.)

(Given that so many statements end up being void-valued expressions, is there
any point to this language extension?  Yes.  There are contexts where a
statement is not legal, but an expression is, even though its value is not
used.)

Of course, a simpler approach would be to add valof...resultis from BCPL, or
inline functions from C++, but it's not really the same as a true expression
language.  On the other hand, a language with expression/statement equivalence
probably shouldn't be based on C in the first place, since several constructs
become redundant (braces vs parens, semicolon vs the comma operator, if-then
vs the ternary operator).

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



More information about the Comp.lang.c mailing list