The D Programming Language: switches (longish)

Dave Hamaker dwh at twg-ap.UUCP
Thu Mar 24 12:40:33 AEST 1988


In article <941 at micomvax.UUCP>, ray at micomvax.UUCP (Ray Dunn) writes:
> Case statements should just be generalised into a "shorthand" way of
> stating if...elseif...elseif...else...

It seems to me that Ray's proposal doesn't go far enough; it's hard to accept
a construct which is just another way of writing an if...elseif...else...
(why clutter a language with two ways to say the same thing?).  Yet I also
feel that case constructs are always artificially so constrained that they
violate my sense of language asthetics.

In thinking about this a lot, I came up with the notion that the switch
expression and case labels can be viewed as textual pieces of a boolean
expression whose truth value chooses the specific case label.  You get
something like:

    switch [(expression)] {
        case expression1:
            ...
        case expression2:
            ...
        default:
            ...
    }

where the square brackets indicate that "(expression)" is optional.  The
switch expression is the "left-hand-side" of the boolean expression and
expression1/expression2 are the "right-hand-side."  As such these are not
true expressions; they are really substrings of a constructed expression,
although they *may* be complete expressions.  They can't be completely
arbitrary substrings, though; they must be parentheses-balanced because
the switch expression is enclosed in parenthesis, and delimited chars and
strings must be complete for a similar reason (how else do you distinguish
the closing parenthesis from a parenthesis contained in the constant?).

In compiling the construct, you need the ability to determine if expression,
expression1 and expression2 are "complete" or not.  This is just a matter
of whether you can parse them completely.  If the switch expression and
a case expression are both complete, then you presume a == operator goes
between them.  Otherwise, you just concatenate them.  You choose the first
true case, if there is any ambiguity, which amounts to qualifying each case
with the negations of all previous ones (the default label is the negation
of all the cases).

Thus, you get things like:

    switch (i) {
        case (<0):
            ...
            break;
        case (0):
            ...
            break;
        case (>0):
            ...
            break;
    }

or
        
    switch {
        case (i<0):
            ...
            break;
        case (i==0):
            ...
            break;
        case (i>0):
            ...
            break;
    }

or even
        
    switch (i==j) {
        case ([0]):
            ...
            break;
        case ([1]):
            ...
            break;
        case ([2]):
            ...
            break;
    }

(which is admittedly pretty weird but only an illustration).

If we require complete switch expressions to be evaluated only once, then
the current switch syntax is completely contained, and it can be determined
if the old conditions are met (and you can compile code which is just as
efficient or inefficient as you used to).  I wouldn't guarantee any order
of case expression evaluation nor that all case expressions would actually
be evaluated (lazy evaluation is allowed); otherwise expression evaluation
side effects can get in the way of optimization.

-Dave Hamaker
The Wollongong Group
...!sun!amdahl!twg-ap!dwh



More information about the Comp.lang.c mailing list