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.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,72c34c66b38e0e05 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-12-31 05:02:01 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed.icl.net!newsfeed.fjserv.net!feed.news.nacamar.de!fu-berlin.de!uni-berlin.de!dialin-145-254-044-220.arcor-ip.NET!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Proposal: Constructors, Assignment [LONG] Date: Tue, 31 Dec 2002 14:02:19 +0100 Organization: At home Message-ID: References: Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: dialin-145-254-044-220.arcor-ip.net (145.254.44.220) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7Bit X-Trace: fu-berlin.de 1041339720 10458195 145.254.44.220 (16 [77047]) User-Agent: KNode/0.7.1 Xref: archiver1.google.com comp.lang.ada:32407 Date: 2002-12-31T14:02:19+01:00 List-Id: Robert A Duff wrote: > "Dmitry A. Kazakov" writes: > > [various stuff about constructors] > > I don't see any reason to add a new feature. It seems to me that the > problem is that you can't write a constructor function for a limited > type (i.e., a function that creates a new object local to itself, and > returns it), and you can't initialize limited objects. So the solution > is simply to remove these restrictions. To build on your example: > > type Internet_Session is > abstract new Ada.Finalization.Limited_Controlled with > record > Count: Integer; > Previous : Internet_Session_Ptr; -- In the global list > Next : Internet_Session_Ptr; -- of sessions > end record; > > type Session_Ptr is access Internet_Session; > > function Make_Session(Count: Integer) return Internet_Session is > Result: Internet_Session > := (Count => Count, > Previous | Next => <>); -- use default "null" > begin > Result.Previous := ...; > ... > return Result; > end Make_Session; > > Then clients could initialize stack and heap objects by calling the > constructor function: > > This_Session: Internet_Session := Make_Session(Count => 123); > That_Session: Session_Ptr := new Internet_Session'(Make_Session(123)); > > The above aggregate is currently illegal, and the "return Result" won't > work because it violates accessibility rules. And the two initial > values are currently illegal. The two AI's would allow the above. I do not understand how could this work. According to Nick Roberts the result of Make_Session is copied as-is. But the object returned by Make_Session has to be pointed from OUTSIDE: function Make_Session (Count: Integer) return Internet_Session is Result : Internet_Session (Count); begin -- -- Place the new object in front of the list -- Result.Previous := Global_List_Header'Unchecked_Access; Result.Next := Global_List_Header.Next; Global_List_Header.Next := Result'Unchecked_Access; Global_List_Header.Next.Previous := Result'Unchecked_Access; return Result; end Make_Session; How to fix this? > I'm glossing over some details that are probably documented either in > the AI's, or in the minutes of some ARG meeting. > > The main point is that limited types are *too* limited. Their purpose > is to prevent *copying* (assignment statements). But initialization is > *not* like an assignment, it need not involve a copy, and it should be > allowed for limited types. Absolutely. The rest is easy, it is just to explain why "not-copying" have to be spelled as copying: X : Obj := Func (); Isn't it misleading? We already have functions that are not functions. Now we will have even more non-functions, and also non-results of non-assignments. I wonder why all this is not counted as a "new feature"? >> The problem is not only the limited types. The problem is more general. >> It is user-construction/destruction for ALL user-defined types. > > I don't understand that. Functions work fine as constructors for > non-limited types. The problem is for limited types. There should be a regular way to construct/destruct ANY user-defined type including class-wides. There should be a way to ensure that only the user-defined constructors are applied. The proposal does not respond this. (<>) as the discriminants does not work for arrays, simple types. It also has nasty consequences. Class-wide objects cannot be constructed. Destruction is impossible as before if the type was not derived from a controlled type. If I derive from Root_Stream_Type then I cannot define neither initialization nor finalization for my stream object. > As for destructors, well Ada.Finalization works OK, although it has some > flaws. Those flaws seem unrelated to the constructor-for-limited-type > issue. > >>...It is >> user-assignment for ALL non-limited user-defined types. > > That seems like a totally unrelated issue. My proposal was to provide true constructors. If you have constructors, assignment comes for free. Limited types was just an example. >> 1. Your proposal is based on a bitwise copy[-constructor]... > > The whole point of limited types is that they *cannot* be copied. > Access discriminants don't work if copies are made. Locks in protected > objects don't work. Various data structures involving pointers don't > work, as your example showed. Etc. > > It is important that the Result object of Make_Session above be built in > place, in its final destination. It cannot be built on the local stack > frame and then moved elsewhere. This requires that the compiler pass in > a Storage_Pool object telling it where to allocate. A special > Storage_Pool could mean "on the stack", but in the That_Session > initialization above, the object must be allocated in the storage pool > belonging to Session_Ptr, which could be user defined. So it seems that your view differs from Nick's one. OK. 1. How will the complier solve this puzzle: function Make_Session (Count: Integer) return Internet_Session is Result1 : Internet_Session (Count); Result2 : Internet_Session (Count); begin ... -- construct both -- now drop one of them if then return Result1; else return Result2; end if; end Make_Session; Then from your description follows that functions returning limited objects will be generated in some special way. All of them? What if I rename the result of such Pickwickean function? Where will it be allocated? 2. How a task type will be constructed? 3. Let Internet_Session is a component of another limited type with another construction function. How do I call Make_Session from that function? -- Happy New Year, Dmitry A. Kazakov www.dmitry-kazakov.de