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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,bd40601768eaf8fd X-Google-Attributes: gid103376,public From: "Matthew Heaney" Subject: Re: Array of Variant Records Question... Date: 1999/09/13 Message-ID: <37dcf193@news1.prserv.net>#1/1 X-Deja-AN: 524440518 Content-transfer-encoding: 7bit References: <7r5vh3$imu1@svlss.lmms.lmco.com> <37d6a45c@news1.prserv.net> <37d6ccb6@news1.prserv.net> <7r77i8$i08$1@nnrp1.deja.com> <37d7c116@news1.prserv.net> <7r8t21$ov5$1@nnrp1.deja.com> Content-Type: text/plain; charset="US-ASCII" X-Complaints-To: abuse@prserv.net X-Trace: 13 Sep 1999 12:44:03 GMT, 129.37.213.233 Organization: Global Network Services - Remote Access Mail & News Services Mime-version: 1.0 Newsgroups: comp.lang.ada Date: 1999-09-13T00:00:00+00:00 List-Id: In article , Brian Rogoff wrote: > Matt, can you give examples where you find that explicit conversions are > painful, or damage readability? Consider the Interpreter pattern. An And_Exp is a Bool_Exp object with two components, a left exp and a right exp. The spec looks like this: package Bool_Exps.And_Exps is type And_Exp is new Bool_Exp with private; function New_And (L, R : access Bool_Exp'Class) return Bool_Exp_Access; ... private type And_Exp is new Bool_Exp with record L, R : Bool_Exp_Access; end record; end Bool_Exps.And_Exps; As you can see above, the constructor for the type accepts two access parameters, and returns a pointer to the class-wide root type, which is defined as type Bool_Exp_Access is access all Bool_Exp'Class; Here's the implementation of the constructor: function New_And (L, R : access Bool_Exp'Class) return Bool_Exp_Access is use And_Exp_Storage; Exp : constant Exp_Access := New_Exp; -- type Exp_Access is access all And_Exp; begin Exp.L := Bool_Exp_Access (L); -- (1) Exp.R := Bool_Exp_Access (R); -- (2) return Bool_Exp_Access (Exp); -- (3) end New_And; Observe the following: (1) L is an access parameter. I have to manually convert L : access Bool_Exp'Class to an access value of type type Bool_Exp_Access is access all Bool_Exp'Class; What's the point? (2) Same for R as for L in (1). (3) Exp is an access object designating an And_Exp value. I have to manually convert an access value from type Exp_Access is access all And_Exp; to an access value of type Bool_Exp_Access is access all Bool_Exp'Class; But what's the point? An And_Exp value is in And_Exp, but it's also in Bool_Exp'Class. The issue is that a tagged object kinda sorta has potentially many types: it's own specific type, and the class-wide type of each of its ancestors. I would prefer that all these manually conversions be done implicitly, so I could just write: function New_And (L, R : access Bool_Exp'Class) return Bool_Exp_Access is use And_Exp_Storage; Exp : constant Exp_Access := New_Exp; begin Exp.L := L; Exp.R := R; return Exp; end New_And; It's not a show-stopper though...