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=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Niklas Holsti Newsgroups: comp.lang.ada Subject: Re: Quick question regarding limited type return syntax Date: Mon, 04 Aug 2014 12:24:19 +0300 Organization: Tidorum Ltd Message-ID: References: <166aaec5-5e9c-40e0-9b07-9b9c7d5f7f33@googlegroups.com> <16a6846f-2964-438a-ab9b-2029075f7924@googlegroups.com> <20m59uxjlygw$.2mpabkt469vp.dlg@40tude.net> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: individual.net HWkswTpMk1HlVsuA9w0cmAXb/S4HLEt4T+vM8ezzYMZ2xx13E7 Cancel-Lock: sha1:Sx+FGSUD3ELKLZ0uSkttL29qEqg= User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 In-Reply-To: Xref: news.eternal-september.org comp.lang.ada:21432 Date: 2014-08-04T12:24:19+03:00 List-Id: On 14-08-03 10:30 , Dmitry A. Kazakov wrote: > On Sat, 02 Aug 2014 23:35:34 +0300, Niklas Holsti wrote: > >> On 14-08-02 19:56 , Dmitry A. Kazakov wrote: >>> On Sat, 02 Aug 2014 10:34:53 -0400, Robert A Duff wrote: >>> >>>> "Dmitry A. Kazakov" writes: >>>> >>>>> On Sat, 02 Aug 2014 09:20:45 -0400, Robert A Duff wrote: >>>>> >>>>>> "Dmitry A. Kazakov" writes: >>>>>> >>>>>>> ...Dispatching calls >>>>>>> through class-wide access discriminants upon initialization/finalization. >>>>>> >>>>>> Can you please give an example of what you mean? >>>>> >>>>> Components not discriminants. I had Rosen's trick in mind: >>>>> >>>>> type T is ... >>>>> Self : not null access T := T'Unchecked_Access; >>>> >>>> Sorry, I still don't get it. I don't see any class-wide types or >>>> dispatching calls there. Also, it's illegal as written (the Rosen trick >>>> is only allowed for limited types.) Perhaps a complete compilable >>>> example would help illustrate the language anomaly you are talking >>>> about. >>> >>> with Ada.Finalization; >>> with Ada.Text_IO; >>> procedure Test is >>> package P is >>> type T is new Ada.Finalization.Limited_Controlled with record >>> Self : not null access T'Class := T'Unchecked_Access; >>> end record; >>> overriding procedure Initialize (X : in out T); >>> procedure Foo (X : in out T) is null; >>> end P; >>> >>> package body P is >>> procedure Initialize (X : in out T) is >>> begin >>> X.Self.Foo; >>> end Initialize; >>> end P; >>> >>> package Q is >>> use P; >>> type S is new T with record >>> I : Integer; >>> end record; >>> overriding procedure Initialize (X : in out S); >>> overriding procedure Foo (X : in out S); >>> end Q; >>> >>> package body Q is >>> procedure Initialize (X : in out S) is >>> begin >>> T (X).Initialize; >>> X.I := 1; >>> end Initialize; >>> procedure Foo (X : in out S) is >>> begin >>> X.I := X.I + 1; >>> end Foo; >>> end Q; >>> >>> Y : Q.S; >>> begin >>> Ada.Text_IO.Put_Line (Integer'Image (Y.I)); >>> end Test; >> >> (Dmitry, I find it quite annoying that you just dump this code on us >> without bothering to explain why you think it shows some problem in Ada.) > > Sorry, but the problem was self-evident to me. Robert asked for a working > example so I scraped together one without much thinking. Apology accepted, no hard feelings. >> The code indeed accesses an uninitialized datum: when Y is initialized, >> Initialize (S) calls Initialize (T), which makes a dispatching call to >> Foo (S), which accesses the component S.I, which is not yet initialized. > > The code prematurely dispatches on an not yet initialized object. Again, it > was evident that this would happen when having a class-wide accessible in > Initialize when the parent's Initialize is to be called at the beginning of > the derived type Initialize. I see what you mean, and I remember that you have often criticized Ada for lacking "proper constructors". Controlled types in Ada provide hooks (Initialize/Finalize/Adjust) that can be used as constructors and destructors, but it is up to the programmer to design the logic, for example to decide which object components are initialized in Initialize, and when. In this area, Ada is perhaps more liberal than languages which have a stricter object-oriented view. I don't agree that dispatching on a controlled object should be illegal until the Initialize operation on that object has been completed. I believe that such dispatching may be quite useful in some designs, just as re-dispatching is useful in some designs - IMO. Moreover, I think this question of constructor/destructor control flow is separate from the general question of preventing access to uninitialized data. As I understand it, even in the languages which do have specific constructor/destructor facilities, there is no requirement or check that a constructor must initialize all the components of the object (but I'm not sure how Java works in this case). > There is no safe way to do initialization in Ada because it is not properly > typed. You should not be able to dispatch until the class-wide instance is > fully initialized, I don't agree on that. > but you can because types are broken. If dispatching hurts you, don't do it :-) (I'll think more about the rest of the points you made, and perhaps reply later.) -- Niklas Holsti Tidorum Ltd niklas holsti tidorum fi . @ .