-
Notifications
You must be signed in to change notification settings - Fork 30
Description
Summary
TBD
Motivation
Aggregates and assignments share a few joint issues that make it worth combining into a single RFC. To understand, it's worth starting with the issues with the current semantics.
First, in Ada, aggregates are a way to completely workaround calls of initialization. To some respect, this makes sense, aggregates are ways to replace initialization. But the consequence is that there's no way to ensure that a given sequence of statement is putting an object in a consistent state at creation time (unlike traditional constructors).
Second, Adjust perform a post-copy update to a type. This causes a double issue, first in terms of performance, as assignment may not need all components to be modified. But this also limits the control over assignment logic, as the user has no way to know what was the initial state of the object or what object was initially copied from.
Third, Ada allows partial assignment of objects through parent views. To some respect, this is also an issue, as the resulting object may be inconsistent, with only part updated, and potentially no way in Adjust to understand which part was changed and which part was not.
A related issue is the so called "Aggregate by extension" where a root object is copied into a child one with specific values provided by the aggregate, again here with no control over the consistency of values (not even in Adjust in the case of initialization).
To solve these issues, we propose to introduce a two step object update mechanism through a value duplication ('Clone) and post update adjustment ('Adjust).
Note that this extra complexity is driven from the desire to support natively Ada constructs (aggregates, partial copies, etc) and improve compatibility between classes and tagged types. Users can leverage default implementation if such level of control is unecessary. Some language extension may also allow to forbid aggregates and partial update on specific types (although this introduces complexities in generics that now need to specify wether these restricted types are allowed or not).
Also keep in mind that Ada Flare aggregates also need to account for types that have both public and private components.
This RFC is about tagged record (and class records even if not explicitely mentionned). Simple records should also be studied when constructors are made available to them.
The additional capabilities need to be optimized as much as possible by the compiler. In particular - even if it's not a language mandate - the compiler should replace calls to Clone by binary copies and remove calls to Adjust when it knows there's no chance of calling an overriden subprogram.
Caveats and alternatives
The current Ada Finalize / Adjust sequence could be an alternative. However, it doesn't provide sufficient ability to control consistency of the objects. It forces the target object to be finalized, it never allows to look at both the source and target value in the same sequence of statement (finalize on the previous value, adjust on the new value) and it doesn't allow to control what is copied. On top of that, when doing assignment on partial objects, Finalize and Adjust are never dispatched to the real value, leaving potential inconsistencies.
Another approach would have been to introduce some kind of a new assignment overload similar to C++. See the RFC for further details.