From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,47def5aa7b3182bd X-Google-Attributes: gid103376,public From: Samuel Mize Subject: Re: How to write TYPECASE in Ada 95? Date: 1999/02/23 Message-ID: <7av52o$62g@news3.newsguy.com> X-Deja-AN: 447641831 References: <79fct8$9k3$1@murdoch.acc.Virginia.EDU> <1103_918264881@DZOG-CHEN> <36cdb012.580716@news.pacbell.net> Organization: ImagiNet Communications, Ltd. User-Agent: tin/pre-1.4-981002 ("Phobia") (UNIX) (AIX/3-2) Newsgroups: comp.lang.ada Date: 1999-02-23T00:00:00+00:00 List-Id: Tom Moran wrote: > But in the situation at hand, the only thing apparently available is > the original poster's original if-elsif list, with the usual hazards > of left out or overlapping cases. Was something like Modula 3's > "Typecase" considered for Ada 95? Are there problems with it? I've waited a couple of days, and more knowledgeable people haven't replied. Hopefully they'll correct any errors in the following. (Often the best way to get info on the net is not to post a question, but to post a wrong answer...) Anyway, here's my understanding. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A "typecase" type of semantic was indeed considered for Ada 95. There are four problems with a "typecase" capability, from an Ada point of view. The first three consider the meaning of the constructs involved; the last considers the efficiency and optimization of these constructs. 1. Since you cannot check for complete and non-overlapping coverage, the "typecase" statement adds no advantage over an "if-elsif" cascade. It's appealing to think that you could check coverage of the class hierarchy, but you couldn't. Since a class can be added by the later compilation of a library package, you cannot check for complete coverage of all tags in the hierarchy. Nor can you usefully check for non-overlapping coverage in most cases. If the root type of the hierarchy is not abstract, it must be covered. Non-overlapping coverage would then keep you from adding any other tags, and you'd have a block instead of a case statement. Even if your class hierarchy is abstract down to some level, it greatly reduces the utility of a "typecase" construct to prevent overlapping classes. If one type is a special case, you must call it out. You then cannot handle its parent type's (overlapping) class as a general case. So, if a library package later extends that parent type, your typecase will consider the extended type to be an "others" case, not a member of the parent class. So a "typecase" construct can add no semantic value over an "if-elsif" cascade. It would just be "syntactic sugar" -- a convenience, but no real addition to the expressive power of the language. And, it would give the unsophisticated user a deceptive appearance of checking class coverage. 2. Adding a "typecase" meaning to "case" would alter the underlying meaning of "case". A "case" statement enumerates all the possible options that it covers -- it lists them out explicitly, so a later programmer can see what they are. "Others" is allowed only because you can enumerate out what it means if you need to. This is not possible for a typecase statement. A new type can be added by any arbitrary package, later. So, an extended "case" for tags would have a different basic meaning than any other "case" statement. This would be confusing. Of course, this point only argues against extending "case," not against adding a new construct. 3. A "typecase" would encourage dangerous usage in the face of programming by extension. Remember, tagged types are NOT a facility for object-oriented programming. Together with other facilities in the language, they support that idiom. However, tagged types are a facility for programming by extension, in a much more general form than many object-oriented languages provide. Ideally, whenever a tagged type is extended, you could add whatever code changes are needed to accomodate it at the location of the extension. No changes in the pre-existing system would be needed. If there are class-wide operations that may be applied to the new type, this is not the case. These must be checked to ensure that they are still correct. If, internally, such an operation branches on a tag value, the pre-existing system may need to be altered -- and the attempt to program by extension has, to some extent, failed. This is especially a problem if the body of the class-wide operation is hidden from the programmer, for instance as part of a proprietary package for which only the spec is provided. So branching on tag values is dangerous -- although not dangerous enough to merit an "Unchecked_" prefix. Adding a "typecase" would implicitly condone widespread use of this idiom, which should only be used after careful consideration of other alternatives, and of the risk involved. (Which is not to say it shouldn't be used.) 4. It would take sophisticated compiler support to make a "typecase" efficient. Since both the "case" statement and tagged types are intended to be very efficient, this could be a damaging surprise to the user. "Case" should just compute the expression and do an indirect jump. Tagged types should dispatch very fast with a jump table. But the combination of these two would require an arbitrarily-long search of the class hierarchy. If this occurs in a tight "heartbeat" loop, it may be a significant performance issue. Now it seems to me (without deep analysis, I admit) that a clever compiler suite could build up a static jump table for each case statement at build time, once it knew what tags would have to be considered. This could run pretty efficiently, and shouldn't take up *too* much space. But, the Ada 95 team was weighing a lot of alternatives, many of which require quite clever compilers. I assume that this was not considered important enough to merit such a requirement for cleverness. In particular, I doubt that they wanted to add a requirement for the binder to generate code, and without such fancy-and-late code generation a "typecase" would be surprisingly slow. Worse, its slowness would vary radically between these two classes of compiler. Use of a separate keyword like "typecase" might reduce the surprise issue. On the other hand, many programmers would expect such a construct to be similar to "case" and would not delve deeply into the language design issues. And, the Ada 95 language designers tried to keep new keywords to a minimum, so they had to add something really important to be considered. Best, Sam Mize -- Samuel Mize -- smize@imagin.net (home email) -- Team Ada Fight Spam: see http://www.cauce.org/ \\\ Smert Spamonam