Path: utzoo!utgpu!watmath!clyde!att!mtuxo!rolls!westmark!mole-end!mat From: mat@mole-end.UUCP (Mark A Terribile) Newsgroups: comp.lang.c++ Subject: Re: Improved switch statement Summary: Love dat funky switch() Message-ID: <137@mole-end.UUCP> Date: 2 Jan 89 04:46:00 GMT References: <1031@uqvax.decnet.uq.oz>, <77300018@p.cs.uiuc.edu>, <574@redsox.UUCP> Organization: mole-end--private system. admin: mole-end!newtnews Lines: 106 (Warning: Herein I shamelessly mix quotes from two authors. Don't bother trying to make me feel guilty about it; I won't.) There's been some discussion on the switch() statement in C++. Should we redefine it? Do away with it? Pillory and scourge it? > ... why bother to keep the switch statement at all? Must C++ be chained to > its ancestry if it is better that it fly free? ... Yes, C++ is most certainly chained to its ancestry. ``Clearly some problems could be avoided if some of the C heritage was rejected .... This was not done because (1) there are millions of lines of C code that might benefit from C++, provided that a complete rewrite ... were unnecessary; ... '' --Stroustrup, *The C++ Programming Language, in the ``Notes to the Reader'' (This is known as proof by Appeal To Authority.) At this point, all the rest of the discussion becomes, in one sense, irrelevant. Or does it? Most of us agree that using the goto statement is usually bad practice, but C has it and I would not suggest removing it. Is it possible that the switch() statement could be relegated to ``bad practice almost all the time''? > ... Surely if the 'if' is better then any program would be more > 'self-documenting' if all such selections were treated using 'if' constructs. Well, is a Ferrari better than a pickup truck? Answer: ``Better FOR WHAT?'' The author also presumes that ``self-documenting'' and ``better'' are the same. Perhaps they are and perhaps they are not. Perhaps if all other things were equal, self-documenting would always be better than non-self documenting. But all things being equal, all things are never equal and there may be good reasons for choosing the second-of-N-most-self-documenting methods when that method brings other big advantages. Or, as Chesterton said, ``We must first establish what we mean by the word `Good.' If a man were to shoot his grandmother with a rifle at a range of five hundred yards, I should call him a good shot, but not necessarily a good man.'' >There are certainly places where one should use switch statements, mainly >when you are converting from a non-object-oriented part of the system >to the clean, elegant part. However, I put switch statements in the same >category with goto statements: sometimes necessary but never elegant. This too makes some presumptions: that OOP is necessarily more elegant than non-OOP and that more-elegant is better than not-more-elegant. The latter is dangerous; ``elegant'' and ``tricksy'' are too easily confused. That non-OOP paradigms sometimes work better than OOP is pretty well established. Arithmetic types certainly seem to require less motion when their implementation mixes the OOP and data abstraction paradigms. Bjarne has given a paper called *What Is Object Oriented Programming?* that addresses some of this. (Now where's my copy ...?) >... Case statements are bad programming style in object-oriented programs. >Instead, you should use virtual functions. Don't say that you want to >distinguish the values of integers and virtual functions won't work in that >context. That just reveals that you are using integers where you should be >using something else. > There is no reason to use switch statements when you can use virtual > functions. False. It is sometimes ``better'' to store an explicit type field. If the type field can be stored in a byte or in two or three bits, and if there are several thousand of the object and you are short on memory, the explicit type field may be better. False again in that the switch() nicely complements enumerated types. Unless you wish to go through the rhetoric of making state constants, etc., into objects (and there is sometimes good reason) the switch-on-enumerated- type offers at least the protection that the compiler can (and *should*) warn if a case is left uncovered by a change. Also, when implementing one object type, it is not always terrible to leave the object paradigm internally. Again, sometimes the rhetoric of the object paradigm outweighs the benefits of the paradigm. False again in that a system which admits to input and output must at some point acknowledge things like characters, which are NOT objects. > |... C++ allows you to define an operator just about any way you want. The > |only useful way to use the proposed change to the switch statement requires > |statement requires that I know exactly how it gets rewritten as an if-then- > |else chain, in which case I would rather use the ... chain ... I'm inclined to agree, simply because the switch() is an at-most-1-of-N branch which depends on--and guarantees--the cases being mutually exclusive. The if-then-else chain neither requires it nor guarantees it. Where the switch() can be used, it immediately tells the reader something that the if-then-else chain only reveals upon close examination of each test. > It comes down to this - either have a 'switch' that uses '==', or get rid of > 'switch' all together. You can't stand with one foot on either side of a > barbed-wire fence. I disagree. The switch() guarantees exclusivity and it works because of the property of the sets (integer types, enumerated types) which are its domain: the compiler can check exclusivity and can guarantee, based on the properties of sets and numbers, that only one case *could* fire, no matter in what order the test was done. -- (This man's opinions are his own.) From mole-end Mark Terribile