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,c9629eba26884d78 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-08-08 01:26:28 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!headwall.stanford.edu!fu-berlin.de!uni-berlin.de!tar-alcarin.cbb-automation.DE!not-for-mail From: Dmitry A. Kazakov Newsgroups: comp.lang.ada Subject: Re: signature like constructions Date: Fri, 08 Aug 2003 10:31:45 +0200 Message-ID: References: <3F2BA9C8.9030700@noplace.com> NNTP-Posting-Host: tar-alcarin.cbb-automation.de (212.79.194.111) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de 1060331186 12793657 212.79.194.111 (16 [77047]) X-Newsreader: Forte Agent 1.8/32.548 Xref: archiver1.google.com comp.lang.ada:41242 Date: 2003-08-08T10:31:45+02:00 List-Id: On Thu, 7 Aug 2003 16:22:34 +0000 (UTC), Georg Bauhaus wrote: >Dmitry A. Kazakov wrote: >Newsgroups: comp.lang.ada >References: <3F2BA9C8.9030700@noplace.com> >Organization: GMUGHDU >User-Agent: tin/1.5.8-20010221 ("Blue Water") (UNIX) (HP-UX/B.11.00 (9000/831)) > >Dmitry A. Kazakov wrote: >:>:>You don't need to know about them during the design process, >:> >:>: Really? >:> >:>Yes. See below. >: >: Iiterally read - no interfaces needed in a design process! Maybe, you >: meant a hacking process. (:-)) > >Why should I add hash(x: Point) to the interface of a 2D point? You should not. >In the generics case, the "interface of the type", and the "interface >of the package instance" need not be too closely coupled. >Hashing can be provided elsewhere. No you create a *new* interface derived from one of 2D point. It is absolutely same as you do with instantiations: A. Declaration of an interface: 1a. Generics: generic type X is private; procedure Hash (Item : X); -- X has Hash procedure Foo (Item : X); -- Foo uses Hash This describes an interface or a class of types having Hash. It also declares a class-wide (works for all class) procedure Foo. 2a. Tagged: type X is abstract tagged ...; procedure Hash (Item : X) is abstract; -- X has Hash procedure Foo (Item : X'Class); -- Foo uses Hash This also describes an interface. X'Class is a closure of a class of types having Hash. Foo is a class-wide procedure. B. Use of an interface: type Point_2D is ...; 1b. Generics: procedure Hash (Item : Point_2D); procedure NewFoo is new Foo (X, Hash); This makes Point2D an element of the class and instantiates Foo. 2b. Tagged (non-Ada!) type Hashed_Point_2D is new subtype X and supertype Point_2D; procedure Hash (Item : Hashed_Point_2D); This creates a new interface from two interfaces of Point_2D and of X. Hashed_Point_2D is both a subtype of X and a supertype of Point_2D, so Point_2D in effect becomes a subtype of X in the scope of Hashed_Point_2D. And thus Foo can be called on Point_2D in that scope. >(Matthew Heaney has explained that you might anticipate possible >uses of your types, but do I have to expect and design my (x, y) pairs >so that they can become part of a data structure that requires a >hash value for them? Just to stay in inheritance land?) Of course no, it should be dynamic, see above. >:>generic >:> type X is private; >:> with function count(thing: X) return Natural; >:>package Foo is >:> >:> type Y is record >:> nfrob: Natural; >:> wrapped: X; >:> end record; >:> >:> -- ... >:> function calculate_mythical_number(item: Y) return Float; >:> -- this is the interesting measure of all the incompatible >:> -- X items in the world >:>end Foo; >:> >:>Then when you instantiate, this package will offer an interface >:>to Y, in a general sense, because it is a natural thing for a >:>package to have one ;-). But ... >: >: How this is better than (if were possible) > >: type X is abstract ...; >: function count (thing: X) return Natural is abstract; > >It is better because it is possible :-) Hey, I have already said that STL is presently impossible with tagged types! Stepanov's point quoted by Matthew was that ADT is *inherently* flawed and unsuitable for generic (class-wide) programming. My point is that generic programming could and should be done without generics using class-wide types instead. >: You claim that different X are incompatible, but have you asked >: yourself, to what they are? The interface tells nothing about it. On >: the contrary it tells how they *are* compatible, they all are >: copyable, have "count" etc. > >No. Count need not be an operation of X. It might as well be implemented >elsewhere, for example using two inquiry functions from the "interface" >of the actual for X, or three from another, unrelated actual. Count is an operation of X if it takes an argument of X. >Also, > >generic > type X is private; > type Y is private; > with function between(this_one: X; that_one: Y) return Float; >package ... > >How do I do this using your next example, and do it in Ada, that is, >not in CLOS, Smalltalk, or Haskell, with MI of interfaces? That is multiple dispatch, it has to be supported. >: type Y is new X with record >: nfrob : Natural; >: end record; > >:>Uhm, against that interface is not what I've had in mind, I think >:>I have failed to explain. So, instead, the interface is the "result" >:>of the "signature package" instantiation. >: >: I hope you do not propose "write-first" approach. (:-)) Interface is >: not a result, it is the starting point when we are thinking about a >: program. > >I design the "signature package", which has the interface >I want (mostly after the keyword "package"). The focus is not >necessarily on the formal type's restrictions. But you have to have some picture in mind, which types should work with the package. The set of all those types is a type class. Its closure is a class-wide type. Description of its root type is an interface. >:>Anything that can be used as actual for X (and count) can >:>be used without having to fit in some inheritance tree (or graph). >: >: If you use it, then it fits. > >It need not even be of a tagged type, so why will it fit? Every specific type has to be a tagged type, even Boolean. Tagged here means that Boolean'Class has a tag, Boolean itself has no tag. Embedded tags was a mistake. >And if you consider X and Y above, they need not be part of the same >type tree. With multiple dispatch you can dispatch on type tuples. >Say we had full MI. Would you prefer to to have > > type T is new X and Y with private; -- not Ada > function between(combined: T) return Float; > >and then name clash resolution all over the place? Generics have more problems with that, because they rely on overloading, which is far less controllable than overriding [could be]. >:>:>Actually, you can pass operations of a tagged type as actuals. >:>: >:>: Yes, this is a great disadvantage of generics. You have to explicitly >:>: specify everything you need. >:> >:>In view of the above, how is this a disadvantage? >: >: My generic package implementing fuzzy numbers has about 30 formal >: parameters. > >Your type will have about 30 things delcared, too, won't it? No, the number comes from a geometric explosion of signatures when several interfaces are mixed: 1. plain number 2. interval 3. fuzzy set With proper ADT I could just use that interfaces which exist anyway. The problem is that generic interfaces cannot be reused in new interfaces. >(I'm not advocating the replacement of OO with generics BTW, >just trying to point out that you can, conceptually, escape the >type hierarchy using generics, and then use the instance's >subprograms, thinking of them as an interface.) This is a traditional vew, which I disagree. Sets of subprograms constitute type interfaces no matter whether you declare it explicitly. A type hierarchy also exists independently on our wishes. Types are related, and a binary relation is a graph. >: My point is, "to provide a function to compare" = "to make >: comparable". It is SAME. >: >: You might object, that one should foresee whether a type should be >: comparable or that making comparable is "global". > >Indeed I will will be forced to foresee this in Ada. > >: This all are just >: limitations of ADT implementations we presently have. For example, >: with supertyping and multiple inheritance you can always make one >: given type a subtype of another given type. > >Some Questions: > >AFAICS, there might be multiple inheritance of interfaces, but not MI >in Ada 200X? It is difficult to believe in. See below. >If I don't want to see but three operation of type X, and two of Y, >how can I limit the visibility of the others? Operation disallowing. >Use export lists like in Eiffel? > >How about libraries without the possibility of changing the base types? One could specify that a particular operation cannot be overriden. --- The actual problem is that we know very little about future ADT. Before we start to implement MI, MD, supertyping, op-disallowing etc in Ada, we should clearly understand how it supposed to work. We cannot just make Ada++ and leave programmers with that. It should be consistent, easy to understand and efficient. --- Regards, Dmitry Kazakov www.dmitry-kazakov.de