From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED.2uCIJahv+a4XEBqttj5Vkw.user.gioia.aioe.org!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Proposal: Auto-allocation of Indefinite Objects Date: Tue, 28 Jul 2020 16:59:09 +0200 Organization: Aioe.org NNTP Server Message-ID: References: <94a54092-a56f-4a99-aaec-08dd611c8fd8@googlegroups.com> <8a502b6c-4609-4cd8-b292-5797fe6421e1n@googlegroups.com> NNTP-Posting-Host: 2uCIJahv+a4XEBqttj5Vkw.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 Content-Language: en-US X-Notice: Filtered by postfilter v. 0.9.2 Xref: reader01.eternal-september.org comp.lang.ada:59572 List-Id: On 28/07/2020 16:28, Brian Drummond wrote: > On Mon, 27 Jul 2020 22:02:57 +0200, Dmitry A. Kazakov wrote: > >> On 27/07/2020 19:48, Brian Drummond wrote: >> >>> 2) can be implemented internally using pointers, but externally appears >>> to be a data object, just like Unbounded_String does, with similar >>> semantics. >> >> No, the point is that Unbounded_String is exactly opposite to what is >> required. In no case it should appear as an object of a different type! >> >> Compare access to string P with unbounded string U: >> >> for I in P'Range loop -- This is OK >> P(J) := 'a' -- This is OK >> >> Now would you do: >> >> To_String (U) (J) := 'a' -- Garbage! > > That wasn't the aspect of Unbounded I was getting at. I agree ... garbage. > > What I meant was that Unbounded doesn't load New, dereferencing, > deallocation etc onto the programmer, but hides the access details, and > our indefinite type should do the same (the compiler can probably to a > better job than the programmer anyway). > > I'm suggesting something more like the C++ reference, signalling (perhaps > by adding a reserved word "indefinite") that fixed size allocation won't > work; Equivalent of C++ reference in Ada is renaming. and implementation is more in line with a controlled type but with > system-provided Initialise,Adjust,Finalize providing the required > operations (no need for the programmer to provide them). > > A : String := "hello" -- a definite string > P : access String := new String'("hello"); > Q : indefinite String := "hello"; I think the keyword is misleading. Maybe this: Q : new String := "hello"; And I don't like initialization. It was a mistake to have limited return. The syntax must stress that all initialization is strictly in-place. No copies involved because the pool is fixed. > ... > begin > for I in P'Range loop -- This is OK > P(J) := 'a'; -- This is OK > Q(J) := 'a'; -- also OK. But index out of range would raise > Constraint Error > ... > Q := "hello_world"; -- deallocates, allocates with new bounds > ... > end; -- deallocate Q here. The rule could be "same pool" as of the container. In the case of a block, the pool is the stack. In the case of a record member, the pool is the pool of where the record itself is allocated. So that you could allocate all object in the same pool. > It follows that "indefinite" cannot also be "aliased" unless we want to > implement smart pointers. For simplicity I'd suggest disallowing "aliased > indefinite" on the grounds that "access" can (should) be used instead. It makes sense, but there are use cases for having it aliased: X : indefinite T; Y : indefinite S (X'Access); -- Access discriminant > Records (including tagged, class wide, discriminated) should work the > same, but probably with shallow copy on assignment if they contain access > types. > > If there is no re-allocation (no different size assignment) the compiler > is free to substitute direct (stack) storage instead of heap allocation > and implicit access types. So for example instead of > > A constant String := "done"; > ... > loop > declare > P : String := Get_Line; > begin > exit when P = A; > end; > end loop; > > A constant String := "done"; > Q : indefinite String; > ... > loop > Q := Get_Line; > exit when Q = A; > end loop; I am not comfortable with the semantics of this and with possible implications too. I would keep it simple. > the implementation can be either an implicit declare block or an implicit > access type. However, where Q has several reassignments within a block, > and the compiler can't determine the size, an implicit access type must > be used. (If it can, it can warn that "indefinite " is unnecessary). > >> What if the original object must be a class-wide object, task, protected >> object, limited object etc? >> >> Ada's access types delegate all operations to the target object, except >> assignment. This is the key property that the proposal in my view must >> retain. > > Indefinite can also be applied to records (discriminated, class wide, etc) > here the size is indeterminate and may vary on reassignment. Assignment > would always be shallow copy (where the record contained access types). That would be inconsistent. IMO, it should be a deep copy, provided such a component would not make the type limited, of which I am not sure. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de