Path: utzoo!mnetor!uunet!husc6!think!ames!amdahl!twg-ap!dwh From: dwh@twg-ap.UUCP (Dave Hamaker) Newsgroups: comp.lang.c Subject: Re: The D Programming Language: switches (longish) Message-ID: <238@twg-ap.UUCP> Date: 24 Mar 88 02:40:33 GMT References: <222965b9@ralf.home> <941@micomvax.UUCP> Organization: The Wollongong Group, Palo Alto, CA Lines: 98 Summary: My pet idea for generalizing switch In article <941@micomvax.UUCP>, ray@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