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: Robert A Duff Subject: Re: Array of Variant Records Question... Date: 1999/09/13 Message-ID: #1/1 X-Deja-AN: 524514807 Sender: bobduff@world.std.com (Robert A Duff) 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> <37dcf193@news1.prserv.net> Organization: The World Public Access UNIX, Brookline, MA Newsgroups: comp.lang.ada Date: 1999-09-13T00:00:00+00:00 List-Id: "Matthew Heaney" writes: > In article , > Brian Rogoff wrote: > > > Matt, can you give examples where you find that explicit conversions are > > painful, or damage readability? In my opinion, every conversion in the upward direction (toward the root of the hierarchy) damages readability, because it obscures the conversions in the other direction, which are somewhat dangerous (can raise an exception). It's like the boy who cried wolf. If you yell and scream when there's no danger, people won't pay attention when there *is* a danger. So I agree with Matt that upward conversions should be implicit. On the other hand, I think requiring downward conversions to be explicit serves a useful purpose. > 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; Have you considered: type And_Exp(L, R : access Bool_Exp'Class) is new Bool_Exp with null 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; Something's wrong with that. How can New_Exp know to allocate an And_Exp record? And the "Exp.L" and "Exp.R" are illegal, because there's (presumably) no such components? I'm confused. How about: return new Bool_Exp'(Bool_Exp_Access(L), Bool_Exp_Access(R)); which avoids the need for one of the conversions? - Bob -- Change robert to bob to get my real email address. Sorry.