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,7f2ce8bda9cae4ab X-Google-Attributes: gid103376,public Path: controlnews3.google.com!news1.google.com!news.glorb.com!npeer.de.kpn-eurorings.net!eusc.inter.net!cs.tu-berlin.de!uni-duisburg.de!not-for-mail From: Georg Bauhaus Newsgroups: comp.lang.ada Subject: Re: "Must instantiate controlled types at library level." Why? Date: Mon, 24 May 2004 14:40:33 +0000 (UTC) Organization: GMUGHDU Message-ID: References: <2h77beF9tvamU1@uni-berlin.de> <2hb77mFabusrU1@uni-berlin.de> NNTP-Posting-Host: l1-hrz.uni-duisburg.de X-Trace: a1-hrz.uni-duisburg.de 1085409633 8500 134.91.1.34 (24 May 2004 14:40:33 GMT) X-Complaints-To: usenet@news.uni-duisburg.de NNTP-Posting-Date: Mon, 24 May 2004 14:40:33 +0000 (UTC) User-Agent: tin/1.5.8-20010221 ("Blue Water") (UNIX) (HP-UX/B.11.00 (9000/800)) Xref: controlnews3.google.com comp.lang.ada:802 Date: 2004-05-24T14:40:33+00:00 List-Id: Dmitry A. Kazakov wrote: : On Mon, 24 May 2004 11:38:38 +0000 (UTC), Georg Bauhaus : wrote: : :>Dmitry A. Kazakov wrote: :>: Georg Bauhaus wrote: :> :>: That's no problem. The type tag could be an index in a multidimensional :>: dispatch table. :> :>With fallback entries, so you don't have to provide entries for :>all m x n x k for a function of (Tm, Tn) -> Tk, I guess, where :>m, n, and k the number of types in the respective type trees? : : No, there is only one more level of indirection needed as compared to : single dispatch. OK but to what do the pointers refer? Say I write a two argument procedure expecing it to be dispatching in both. proc drive (v: in out Vehicle; d: Steering_Device); I get drive.Impl (v'tag) -> i drive.Impl (d'tag) -> j OK. Now what if later during development some programmer adds a module that calls drive(vv, ddd); The program then would have to have entries in the dense dispatching maps for i', j', wouldn't it? So in general you will need n x m implementations, unique or not. And prior to whole program analysis you will need fallback mechanisms. : So to disptach to Foo the compiler should resolve: : : Foo.Impl (Foo.A (First'Tag), Foo.B (Second'Tag), Foo.A (Third'Tag)) : : All arrays here are dense. Still before complete analysis of the linked program you might have to provide for the possibility of an argument that is not yet in A's or B's map. How does this remove the conceptual need for an m x n x k dispatch matrix, independent of how you implement it, along with the need to actually think of m x n x k cases? Is it worth the trouble? :>: How it differs from what we have now: [...] :>: You have to implement ">" before you instantiate. :> :>You won't have to add a type with an implementation of a :>comparison interface. All that is needed is a comparison function, :>inheritance/implementation is not involved. : When you write in a generic interface something like "type X is <>", : you in fact specify an interface to be implemented. During : instantiation the actual type is checked against the interface. If : check is OK the implementation is accepted. One can do same for : non-generic interfaces. Yes certainly, but why? There is a cost. And Ada offers you the two ways to specify the requirements, either explicitly, or using a generic formal tagged type. : I see no technical reason why generic instantiations should be more : flexible in that respect. AFAIK ARG is going to relax some : restrictions anyway. Consider a simple untagged user defined type that by itself is not ordered. For some reasons you want to store objects of the type in sorted containers (yes, there may be reasons to do so.) So you have to provide "<", consistent with "=". But "<" does not belong to the simple user defined type because that by itself is not ordered. Solution 1: Add it to the type no matter what and explain that "<" is there because some remote part of the program has good reasons to store objects in a sorted container. Solution 2: Turn the simple user defined type into a tagged type and derive a new one from it adding "<" to the derived type (possibly implementing a Less_Than interface in Ada 200Y). Solution 3: Add "<" locally in the remote part of the program, implement it using operations of the simple user defined type. Solution 3 leaves the simple unordered user defined type completely as is, untagged. At the same time it hides "<" locally, as does solution 2. But 2 achieves this effect only at the cost of making the simple UDT tagged, and adding the possibility of dispaching, prior to a full investigation by the compiler/linker. :>Is it impossible to have a generic function that operates on :>reals as well as on complex numbers? : : for I in A'Range loop : A (I) := 0; A(I) := neutral_element_of_addition; -- of course : end loop; : Is it impossible to write : : A(A'First) := 0; : A(A'First + 1) := 0; : A(A'First + 2) := 0; : A(A'First + 3) := 0; : ... : ? I don't understand. It is possible... :>What's wrong with generic units that work like this, with either formal :>tagged types or explicit requirements listing with defaults? ;) : : I do not see how they could help. Consider a program (say parser) that : should work with both String and Unbounded_String. When the type is a : generic parameter, then the whole compiler will be generic too. I have a generic in a program for turning Wide_String values into external representations. This requires either String or Wide_STring, so I'm using either String or Wide_String in the respective instantiations... If I had a need to inject string polymorphism in all parts of the program I'd do the usual thing: create a user defined type, as for every other predefined type that isn't polymorphic. :>(In Ada200Y you can even have multiple interfaces, IIRC.) :> :>Maybe you want take Eiffel into account, as it has a lot of what you :>seem to want, including full multiple inheritance? : : C++ has MI. I did say Eiffel not because it has MI. It is no alone there. But a lot of what you have said has reminded me not only of C++ templates and compiling/linking, but also of problems that Eiffel has solved. It might be interesting to look at the solution and the consequences it has. Eiffel libraries use MI a lot to express a component's dependence on the presence of methods specified in interfaces like COMPARABLE, HASHABLE, etc.