Path: utzoo!attcan!uunet!lll-winken!ames!mailrus!csd4.milw.wisc.edu!uxc!uxc.cso.uiuc.edu!m.cs.uiuc.edu!p.cs.uiuc.edu!johnson From: johnson@p.cs.uiuc.edu Newsgroups: comp.lang.c++ Subject: Re: Improved switch statement (was Re: Message-ID: <77300019@p.cs.uiuc.edu> Date: 4 Jan 89 16:58:00 GMT References: <574@redsox.UUCP> Lines: 72 Nf-ID: #R:redsox.UUCP:574:p.cs.uiuc.edu:77300019:000:4115 Nf-From: p.cs.uiuc.edu!johnson Jan 4 10:58:00 1989 I love a good fight. Thanks, Mark! When I say that virtual functions are "better" than switch statements, I mean that they result in programs that are easier to understand and maintain. I also argued that they were just as fast, as least with the computers and compilers we are using. There are certainly reasons why one might want to use tags and switches: space efficiency (as Mark suggested), compatibility with other programs (my "outside world" comment). If it turns out that a parser generator needs to generate switch statements and gotos, I don't mind at all, unless you are going to force me to read the program that gets produced. >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. I disagree that elegant and tricksy are at all similar. In my book, elegant means "simple and easy to understand". It does not mean fast, small, or anything else. My experience is that if you work long enough you can usually get a simple solution to a problem that is also fast and small, though there are certainly an infinite number of exceptions. One of the "laws of computing" that I saw once was "All non-trivial programs have bugs in them." A corollary is "If your program has no bugs, it is trivial." There is certainly a lot of truth to this. I want to write bug-free programs, which means that they must be trivial. If it is possible to write a bug-free operating system, elegance is a prerequisite. There are certainly non-OOP paradigms that work better than OOP in many cases, but 90% of programmers never use them, either. My experience is that OO solutions are almost always better than traditional "structured" methods, which is what most programmers use. Functional and logic programming are better solutions for many problems, but they have always had small followings. >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. The only reason not to make state constants objects in C++ is space. If you are only checking the state once then it is probably not worth the trouble of making separate classes for each state. (But then you are probably doing something else wrong, or you are talking to the outside world (see below) or this is a rare case.) However, let us suppose that we have an enumerated type with 7 cases and we check for a tag of that type 11 times. In my book, there should be an abstract class that defines 11 virtual functions and 7 concrete subclasses. If you want to add a new case in the C-like version then you will have to go find all 11 places you had a switch statement and fix them up. This code might not even belong to you (i.e. it might be object code that the vender provided). However, in the OO version you just create a new subclass. If it is a minor variation on an existing class then you can subclass one of the concrete classes and so do little work. One of the advantages of this style of programming is that it helps you to discover objects. People always ask "how do you find the objects?" I don't know what your objects should be, but I know how to find them, and building lots of little classes like this is one of the important steps. Some times I overdo it, in which case I will back up and merge classes. However, most of the time this leads to new class hierarchies. >False again in that a system which admits to input and output must at some >point acknowledge things like characters, which are NOT objects. I said that in my first message. There are lots of examples like this: network protocols, robotics, disk drivers. This just shows that the world is not as object-oriented as some people claim. I always encapsulate the I/O in an object, hide the switch statements there, and from then on have a consitent OO view of the world.