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=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,a5f2330cf94935a0,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1993-03-18 03:34:41 PST Path: sparky!uunet!pipex!zaphod.crihan.fr!univ-lyon1.fr!scsing.switch.ch!sicsun!disuns2.epfl.ch!lglsun!nebbe From: nebbe@lglsun.epfl.ch (Robb Nebbe) Newsgroups: comp.lang.ada Subject: tagged vs class Message-ID: <1993Mar18.113757@lglsun.epfl.ch> Date: 18 Mar 93 10:41:29 GMT Organization: Ecole Polytechnique Federale de Lausanne NNTP-Posting-Host: lglsun7.epfl.ch Date: 1993-03-18T10:41:29+00:00 List-Id: Looking at all the posts about tagged and class it seems that a lot of people don't really understand the role of tagged in the language. They want to draw a comparison with concepts that are found in other OO languages but aren't appropriate. So, just what is the purpose of tagged in the language? Tagged more or less tells the compiler that this type will be used for class-wide programming and subsequently the compiler must generate type information and a tag. Is tagged strictly necessary in the language? The answer is no; we could imagine a language that has very much the same syntax and is not in any sense ambiguous, but without tagged. Type extension and class-wide features would be restricted to record types. Why didn't they choose this approach for Ada 9X? PROBLEMS The first problem: Every tagged object has a tag and thus there is a distributed overhead. Due to the fact that static typing is possible if an object is of a specific type this overhead may be eliminated for all objects that are not class-wide by a clever implementation. (A tag is only necessary if dynamic typing is required which is the case for the class-wide features.) To require this of every implementation is probably unrealistic. This distributed overhead may be acceptable in other OO languages but is not acceptable in a language that will be used for embedded systems programming. Either we signal the overhead in Ada or we require implementations to avoid it (the latter would be a lot to ask). The second problem: We would need a way to say in the generic formal part that a type is a record type to establish if type extension and the class-wide features may be used in the spec and the body. This problem isn't serious and there are a number of possibilities. The third problem: If type extension was valid for all record types then we would probably have to allow representation clauses. Would we allow a clause just for the extension or would a new representation be needed for the whole type? What about visibility? This would be quite a bit of work and the number of times it would be needed is probably minimal. The fourth problem: In Ada 83 a type may be declared in the declarative part of a block statement or a subprogram. This is by far the worse problem for the following reason. Suppose we declare a new type local_window which is an extension of some window type declared at library level. Now if we have a list of windows of different types (a heterogeneous list of windows using class-wide access types) we could pass an object of local_window outside the scope in which it is defined. Furthermore if we redefine one of the primitive operations of the window type for local_window the the situation could arise in which a subprogram is called from outside the scope in which it is defined. Conceptually this is a mess. The problem stems from the fact that in Ada 83 when a new type was declared or derived the only operations available were those that are automatically available or those that were defined as primitive operations for the parent type. Under these conditions there aren't any problems. If we add class-wide types then an object may be passed out of its scope as an actual parameter to a class-wide parameter. SUMMARY Tagged points out a possible distributed overhead (a tag), is used to in the generic formal part of a generic package, allows us to avoid solving the problems posed by representation clauses for extensions and lets us easily restrict type extension and class-wide features to the library level. ------- The addition of tagged to the language is a rather pragmatic solution to these problems. Once you understand why tagged was added I don't see how class could be preferred to tagged. Substituting class for tagged would be like calling a fish a bird. There are some advantages to using tagged in the language. It helps make it clear in the source code when a class of types is being constructed. This adds to the readability of the code and helps make the design clearer. This, however, does not change the fact that tagged is in a sense an implementation detail. There is an interesting comparison to be made with Oberon (which also has type extension and class-wide pointers but which aren't called class-wide pointers) Niklaus Wirth avoids ever mentioning tagged in his book "Programming in Oberon". He views it as an implementation detail to be hidden. In support of Ada I should mention that Oberon is much simpler and in many respects less powerful than Ada; It doesn't have representation clauses and types can't be declared in subprograms. Admittedly adding the reserved word class would also solve these problems but it wouldn't change the fact that it is an implementation detail. We would just be disguising it as something more abstract even though it isn't. Moreover, we would be using class inconsistently in the language which seems like a bad idea to me. WHAT WE SHOULD BE DOING We should be promoting class wide types and type extension. This approach has some real advantages over other approaches to OOP. If we market these differences we should do pretty well. If we try to market tagged types (or class types) we will just be beating our heads against the wall. Robb Nebbe nebbe@lglsun.epfl.ch