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,189a28164788ed2e X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-10-30 09:49:45 PST Path: archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-01!supernews.com!newshub2.rdc1.sfba.home.com!news.home.com!news1.sttln1.wa.home.com.POSTED!not-for-mail From: "Mark Lundquist" Newsgroups: comp.lang.ada References: Subject: Re: Using "with function" X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Message-ID: Date: Tue, 30 Oct 2001 17:49:44 GMT NNTP-Posting-Host: 24.248.56.237 X-Complaints-To: abuse@home.net X-Trace: news1.sttln1.wa.home.com 1004464184 24.248.56.237 (Tue, 30 Oct 2001 09:49:44 PST) NNTP-Posting-Date: Tue, 30 Oct 2001 09:49:44 PST Organization: Excite@Home - The Leader in Broadband http://home.com/faster Xref: archiver1.google.com comp.lang.ada:15427 Date: 2001-10-30T17:49:44+00:00 List-Id: "Matthew Heaney" wrote in message news:ttr5ves1r0m76@corp.supernews.com... > Actually, this is an interesting question because the generic formal type is > nonlimited -- which means it already comes with a predefined equality > operator. > > A rule of thumb for generics is that even for nonlimited types, it's still a > good idea to import the equality operator explicitly. > > Also, in general, you should use default notation for generic formal > subprograms, like this: > > generic > type Element_Type is private; > with function "=" (L, R : Elemenet_Type) return Boolean is <>; --say "is > box" > package GP is > > This simplifies the instantiation, because you don't have to specify the > operation(s) explicitly. Right, this is a good idiom. Import "=" explicitly, but use the "box" :-) > > Another thing to think about is that if the equality operator is used only > to implement a single operation (say, this is a container object, with its > own equality operator), then you could defer implementation of the > operation, by moving it to a child: > > generic > type Element_Type is private; > package GP is ... > > generic > with function "=" (L, R : Element_Type) return Boolean is <>; > function GP.Generic_Equality (L, R : Container_Type) return Boolean; I don't see that this buys you anything... *unless* you make the formal type limited (see below)... But I could be wrong...(?) > > Another question to ask is whether you need assignment of elements. If not, > then you could declare the generic formal type as limited: > > generic > type Element_Type is limited private; > package GP is ... > > This would have the effect of also removing default equality (limited types > don't have predefined equality). Now you can combine this with the child package idea above, right? So you have a parent package that can be instantiated on any type, without requiring the instantiator to supply "=" in the case of a limited type, and then the child package provides functionality that can be had for a limited type only if "=" is supplied. The style question is whether the functionality requiring equality is sort of "core", fundamental stuff that the user will almost always want -- in which case doing this just makes the user have to instantiate one more thing -- or whether it's sort of ancillary, add-on kind of functionality or whatever ("optimize for the expected case"). > > The idea is that for generic formals, you want to require as little from > your client as possible. I call this (after Deitel) the "principle of least > committment." I don't know who Deitel is (who is Deitel, BTW?), but it is an excellent principle and now I have a name for it too... thanks :-) This is one of the things about Ada generics that might be a little counterintuitive until one gets the hang of it, don't you think? A generic formal type is like a type declaration to the generic body, so words like "limited" and "abstract" have their normal meaning to the body (and technically, to the rest of the spec), which is that there are certain things you're not allowed to do there -- e.g. assigning to objects of a limited type, creating an object of an abstract type, etc. But for the instantiator, it's the flip side, and these words mean that the actual type is not required to have the corresponding properties. So the user of a generic should read "limited" as "allowed to be limited" (but can be limited); and while "tagged" indeed means "must be tagged", "abstract" means "is allowed to be abstract" (but can be non-abstract). The same goes for unknown discriminants in the generic formal type. For maximum flexibility, the rules of thumb for formal private types are: 1) Declare as limited, if possible. 2) Declare with unknown discriminants, if possible 3) For tagged formals, declare as abstract if possible -- mark