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,c83a22003c320b45 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-11-14 19:24:35 PST Path: nntp.gmd.de!xlink.net!howland.reston.ans.net!spool.mu.edu!bloom-beacon.mit.edu!uhog.mit.edu!news.mathworks.com!news.duke.edu!eff!blanket.mitre.org!linus.mitre.org!linus!mbunix!eachus From: eachus@spectre.mitre.org (Robert I. Eachus) Newsgroups: comp.lang.ada Subject: Re: Initialization Params for Controlled Types Date: 14 Nov 94 18:35:13 Organization: The Mitre Corp., Bedford, MA. Distribution: world Message-ID: References: <1994Nov4.134412.10010@unix.brighton.ac.uk> <39ebsa$129i@watnews1.watson.ibm.com> <1994Nov10.152352.27015@unix.brighton.ac.uk> <3a8k92$10rk@watnews1.watson.ibm.com> NNTP-Posting-Host: spectre.mitre.org In-reply-to: ncohen@watson.ibm.com's message of 14 Nov 1994 21:19:30 GMT Date: 1994-11-14T18:35:13+00:00 List-Id: Norm said something which is true, but accidently misleading: > As others have pointed out, a function with a classwide result subtype, > function Open_Current_Account (...) return Account'Class; > will not be inherited. However, calls on functions are not intrinsically > associated with objects. Your remark about exactly one call on open per > object sounds like an initialization PROCEDURE. This can be provided by > controlled types... The more natural way to write this: function Open_Current_Account (...) return Account; ...will be inherited as an abstract operation which must be explicitly overridden. However, this is also almost (but not quite in Ada 9X) useless for most types of objects, including accounts, where objects should not be assignable. Better would be: type Account is abstract tagged limited private; type Account_Kind is String(1..8); -- allow extension. type Account_Ref is access Account'CLASS; ... function Open_Account (Kind: Account_Kind;...) return Account_Ref; -- and probably in a child package: type Checking_Account is new Account with private; ... Now the operation Open_Account will be derived if you derive a type from Account_Ref for some reason, but it will need a to explicitly dispatch for each type of account: ... if Kind = "CHECKING" then return Open_Checking_Account(...); If you are clever and lazy ;-), you will define other operations on accounts--which may or may not be an abstract type, as procedures or functions with an operand of type Account. If, these are intended as operations on all Account types, the templates (abstract or otherwise) should be defined in the same package as Account, so they are inherited, potentially dispatching, operations. Now in the parent package add, for instance: function Balance(AR: Account_Ref) return Money; pragma Inline(Balance); with the full definition: function Balance(AR: Account_Ref) return Money is begin return Balance(AR.all); end Balance; -- This function raises Constraint_Error not Program_Error if the -- pointer is null... And with a good optimizing compiler all the magic dispatching glue will disappear during inlining. Where does this leave us with respect to the original "problem"? The code naturally works the way it is supposed to. Account type is either a parameter to the open function or is implicit in the name, you can chose the one that is appropriate. Non-constructor functions and procedures are derived and dispatching unless overridden, and the distinction between objects and their names only matters where it matters, possibly only when creating an account. -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is...