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-30 04:23:13 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news.tele.dk!news.tele.dk!small.news.tele.dk!fu-berlin.de!uni-berlin.de!dialin-145-254-037-154.arcor-ip.NET!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Proposal: Constructors, Assignment [LONG] Date: Mon, 30 Dec 2002 13:23:30 +0100 Organization: At home Message-ID: References: Reply-To: mailbox@dmitry-kazakov.de NNTP-Posting-Host: dialin-145-254-037-154.arcor-ip.net (145.254.37.154) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7Bit X-Trace: fu-berlin.de 1041250989 9396437 145.254.37.154 (16 [77047]) User-Agent: KNode/0.7.1 Xref: archiver1.google.com comp.lang.ada:32386 Date: 2002-12-30T13:23:30+01:00 List-Id: Nick Roberts wrote: > "Dmitry A. Kazakov" wrote in message > news:aumu4o$76buu$1@ID-77047.news.dfncis.de... > >> > -- You'd need to carefully explain why solutions based on functions (as >> > Nick Roberts described) are not sufficient; >> >> They cannot work when no assignment exists. Otherwise one should invent a >> sort of pickwickian assignment. > > Yes, Dmitry, but it is this Pickwickian assignment that has been mooted, > and it is necessary for you to demonstrate that your proposal is superior. That's what I am trying to do. (:-)) The problem is not only the limited types. The problem is more general. It is user-construction/destruction for ALL user-defined types. It is user-assignment for ALL non-limited user-defined types. I do not think that people are very happy with Ada.Finalization. It looks like a hack. However, it is an excellent hack because it lets almost everything open for any better solution, should we find it, of course. (:-)) > To be precise, interpreting Randy's suggestion, my suggestion would be for > (Ada be changed in the next revision so that) an object declaration which > includes a subtype indication that denotes a class-wide type whose root > type is limited (tagged) to be permitted to include an (explicit) > initialisation expression, in which case special rules would apply to the > dynamic semantics for the elaboration of the declaration: (1) the subtype > inidication is elaborated; (2) the expression is evaluated and converted > to the nominal subtype; (3) the object is created (constrained according > to the result from (2)); (4) the value of the result of (2) is copied > (bitwise) into the object (no call to Initialize or Adjust will be made). 1. Your proposal is based on a bitwise copy[-constructor] (4). This means that you have to ensure that ANY [limited tagged] object CAN be copied this way. What will you do with the following: type Internet_Session is abstract tagged limited private; type Internet_Session_Ptr is access all Internet_Session'Class; private type Internet_Session is abstract new Ada.Finalization.Limited_Controlled with record Previous : Internet_Session_Ptr; -- In the global list Next : Internet_Session_Ptr; -- of sessions end record; The construction of an Internet_Session inserts it in a global double-linked list of all sessions. Such an object cannot be copied bitwise. To solve this and similar cases you have either to construct objects in-place (my proposal) or to provide Adjust, i.e. a full-sized assignment. 2. Why is it allowed for class-wide types only? What should I do to initialize a specific limited type? 3. Should specific types be allowed to be initialized, what will you do with composite types of them? For instance, let an array of limited types be initialized? It is limited, but alas untagged, so any kind of initialization is impossible, right? > The advantages of this idea, I think, are: it is a relatively simple > change to the Ada standard (although it is still not entirely simple); a > function such as 'Open' (call it a 'constructor function' if you wish, but > it is really a normal function) can be used to create temporary objects > (that are a part of a bigger expression) as well as for intialising > objects; it seems to me to be a natural and readily understood way of > solving the problem (the only twist being the change in the rules for a > limited tagged type); (in common with your propoal) all existing legal Ada > source text will remain totally unaffected. > It seems to bear some similarility to the new rule for aggregates. Is there an AI for the rule? > My example above also demonstrates the use of an abstract type, which has > the advantage that the implementation (of the 'Open' function) can return > any type it likes (derived from Internet_Session). The user is happily > oblivious to which actual type is returned; the implementation can be > changed to return (further) different types according to new requirements > without disturbing the user (recompilation or relinking will be required, > but no changes to the user's source text). The type could be made > concrete, and more details about the type could then be revealed to the > user (e.g. the discriminants, the other record components), should that be > considered more appropriate. > >> > I'd prefer making the function solution work. There is a proposal to >> > make it possible to initialize limited objects with a function call, >> > which would eliminate that objection. >> >> Yes it definitely would, because a function which result initialises an >> unconstructed object is just another name for constructor. However there >> would be also questions: >> >> 1. Will you use ":=" for limited types within a declaration with a >> problem to explain what is that, or just "rename"? > > The use of ":=" would be my preference, since it does not require any > change to the syntax of object declarations (RM95 3.3.1). > >> 2. What to do with "new" for limited types, when a constructor have to be >> called? > > There was never any problem with allocator initialisation, because the > result is of an access type (which is always definite). The problem is that either T'Class'Input or your construction-function creates a stack allocated object. So to allow heap objects as well, the developer of a limited type have to provide two different construction-functions: one to return T, another to return access T. This definitely breaks Ada's symmetry in object allocation models and is a burden for developers. >> 3. I suppose that constructors will be allowed for Limited_Controlled > only? >> So arrays, untagged types, tasks and protected object will remain out of >> reach. > > My suggestion is that the new rules should only apply to object > declarations for limited class-wide (tagged) subtypes, because they are > illegal now, so we can be certain that existing legal Ada source text will > not be affected by the new rules. > > It may be convenient, but it is not really necessary for protected or task > types to be included, because a tagged (record) type can always include a > component of the requisite protected or task type. It is arguable. Access discriminats are very frequent for tasks and protected objects. A construction/destruction of tasks and protected objects could provide a nice way to create the objects referenced by a task during task construction and delete them upon destruction. This would be much more better design than to pack the task into a record. Another advantage would be that the entry points of a task could be exposed as entry points, not as proxy subroutine calls, so a user of a task might directly use timed entry calls etc on them. > The question does not > arise for array types, because they are not (able to be) limited (and so > always have assignment defined). Array of limited components is limited. > Any definite type can be initialised by a > procedure to which it is passed as an 'in out' parameter. I think there > may be a case for the inclusion of indefinite limited untagged types. You also can view it another way: we can initialize by either a function [+copying] or a procedure [in-place]. For functions we have a way to do it within a declaration: X : My_Type := expression (); For procedures we have nothing (except the predefined constructor with the values of the discriminants as the parameters). You can consider my proposal as an attempt to close this gap: X : My_Type (); -- Happy New Year, Dmitry A. Kazakov www.dmitry-kazakov.de