======= LSN015.ImplConv2 ======= /* Written 12:33 pm Aug 11, 1991 by stt@inmet.camb.inmet.com in inmet:ada9x.mail */ /* ---------- "LSN on Implicit Conversion and Inhe" ---------- */ >From stt@inmet.camb.inmet.com Sun Aug 11 12:32:47 1991 id AA00138; Sun, 11 Aug 91 12:34:17 -0400 From: stt@inmet.camb.inmet.com (Tucker Taft) To: ada9x-drrt@ajpo.sei.cmu.edu, ui@ajpo.sei.cmu.edu Subject: LSN on Implicit Conversion and Inheritance !topic LSN on Implicit conversion and inheritance !reference MD-4.6 !reference MD-4.6.1 !from Tucker Taft 91-08-11 !discussion As noted before, there are two ways to make an operation available to every type in a class: via implicit conversion and via inheritance. We have adopted the term "class-wide operation" to refer to operations which are made available via implicit conversion. Let us call the operations which are inherited from the root type the "inherited operations." Examples of class-wide operations in Ada 83 are: 1) The integer/real literals (integer/real class wide on the "result") 2) The 'VAL operation (integer class wide on its parameter) 3) The 'POS and 'LENGTH operations (integer class wide on the result) 4) Named numbers (integer/real class wide on the "result") Examples of inherited operations in Ada 83 are: 1) The predefined arithmetic operators (inherited by all integer types) 2) "=", ":=" (inherited by all private types) 3) TRUE, FALSE (inherited by all boolean types) It seems to make sense that an "inherited operation" need not also provide implicit conversion. Otherwise, there would be many more possibilities for ambiguity. As it is, implicit conversion is only relevant for class-wide operations. Because these operations are not also overloaded, it is rare that ambiguity results. Therefore, given the above philosophy, we would propose the following rules: 1) Implicit conversion is only permitted on a class-wide operand, or a class-wide result, of some class-wide operation. 2) There are certain predefined class-wide operations (the "convertible operands" of RM-4.6(15), plus 'VAL). 3) A user-defined operation is only class-wide if it is explicitly declared with a result or operand of type T'CLASS. 4) The inherited operations of a universal type are never class-wide in their controlling operands or controlling result. Additional restrictions for tagged types only: 5) For a tagged type, implicit conversion is only permitted when converting an actual parameter *to* a universal type, from a type within its class. 6) Implicit or explicit conversion to a universal type is not permitted from a type declared in an inner scope relative to the universal type. 7) Implicit or explicit conversion to a universal type is not permitted from a type that has an abstract (or missing) operation which is dispatching for the universal type. (A "missing" operation corresponds to the case where the univ type is non-limited, and the operand type is limited -- it is missing ":="). These rules pretty much correspond to what we had proposed earlier, except for the additional limitation #5 above, namely allowing only implicit conversion *to* a univ tagged type. Mainly we are reiterating our position that the inherited operations of a universal type need not provide implicit conversion, since they are already available for all types within the class without implicit conversion. Note that the idea of using the root's operations for the universal type doesn't seem to really work on further examination. It seems better to continue to say that the universal type has a full set of inherited operations of its own, just like every other type in the class. So long as implicit conversion is not permitted on the controlling parameters/result of these inherited operations, there doesn't seem to be any problem. (Note we have to remember the odd case where the root type has a primitive operation with a formal parameter explicitly of T'CLASS. This would not be a controlling parameter, so implicit conversion would be permitted.) -Tuck /* End of text from inmet:ada9x.mail */