Version 1.3 of ais/ai-00413.txt

Unformatted version of ais/ai-00413.txt version 1.3
Other versions for file ais/ai-00413.txt

!standard 4.3.1          05-02-07 AI95-00413/01
!class amendment 05-02-07
!status No Action (10-0-0) 05-02-12
!status work item 05-02-07
!status received 05-02-07
!priority Medium
!difficulty Medium
!subject Partial view, task, and protected aggregates
!summary
A distinct syntax is proposed for aggregates used to define the value of a task type, protected type, or partial view.
If "others => <>" is ultimately supported at all for non-array aggregates, it would only apply to visible non-discriminant components.
On a somewhat separate issue, in an aggregate with a task part, or a function call that returns an object with a task part, any task parts are not activated until after the outermost enclosing composite object is fully and successfully initialized.
!problem
AI 389 proposes that partial view aggregates be supported. It borrows the "others => <>" notation to cover hidden components. However, there are significant maintenance issues associated with using "others" in a non-array aggregate, and it seems unfortunate to tie support for partial view aggregates to the use of others. Furthermore, whether or not to require "others=>" for aggregates defining a value of a task or protected type is debatable.
On a separate issue, it is not clearly specified when a task that is part of an object defined by an aggregate or a function call is activated.
!proposal
A distinct syntax for aggregates is proposed which makes it clear when they are being used to define a value of a partial view, task, or protected type. Here are examples that illustrate the syntax:
(private and A, B, C=>D) (task and Disc => True) (protected) (private)
The syntax "(private)" may be used as the value for any partial view with no visible components, including those whose full type might be non-composite.
In a partial view aggregate, only nonlimited components may have a value specified by an expression; (visible) limited components shall be specified to have the value "<>". In the evaluation of a partial view aggregate for a controlled type with a non-null Initialize procedure, the discriminants, if any, are first assigned, then the remainder of the object is default initialized, the Initialize procedure is invoked, and finally the non-discriminant components with a specified value are assigned. This ensures that the Initialize procedure sees a value that it could normally see during default initialization.
for aggregates of a partial view without a non-null Initialize procedure, the components with specified values are assigned, and then the remainder of the components are default initialized.
We also propose private extension aggregates:
(X with private) (Y with private and B, C=>D)
The word "private" must appear in an extension aggregate if the type of the extension aggregate is derived from the type of the ancestor part through one or more extension parts and any of them are private. If the type of the ancestor part is limited, it shall be specified by a subtype_mark rather than an expression. Simlarly, if a visible component not inherited from the ancestor part is limited, it shall be specified as "<>".
In a private extension aggregate for a partial view of a controlled type with a non-null Initialize procedure, the discriminants are determined, the remainder of the object is default initialized, the Initialize procedure is invoked, and then the components or ancestor part specified by expressions (rather than "<>" or a subtype_mark) are assigned.
In a private extension aggregate for a partial view without a non-null Initialize procedure, the ancestor expression, if any, and the components with values specified by an expression, are assigned, and then the remainder of the object is default initialized.
The legality of an aggregate, and in particular whether it is for a partial view, and what components are visible, is determined at the point where the aggregate appears. The legality of the aggregate is not rechecked in an instance.
For tasks that are part of an aggregate, or that are part of an object defined by a function call, we propose to defer activating the task until the outermost composite object containing the task is fully and successfully initialized. This ensures that the task will not refer to potentially uninitialized parts of the enclosing object via a discriminant of an access type.
!wording
TBD, depending on whether intent of proposal is approved.
!discussion
By providing a distinct syntax for these non-record aggregates, we eliminate a number of unpleasant issues. For example, the syntax "(private)" has no implication that there are any components at all, whereas "(others => <>)" does imply that, which is jarring if the full type turns out to be non-composite. As mentioned in the !problem, by eliminating the need to use "others" simply to handle potentially hidden components, we allow it to be reserved for cases where the user intentionally wants to forego full coverage checking. Finally, because the syntax is specifically designed for partial views, it makes sense even in a generic, where in the instance a full view might be available. By not requiring that the legality of the aggregate be rechecked in the instance, we allow it to work in any generic with a (definite or discriminated) formal private type.
In general, the rules should be simpler, because we have no need to restrict a partial view aggregate to types which are certain to have a full/actual type that is composite.
Once we adopt the use of the term "private" for partial view aggregates, it is natural to adopt the use of "task" and "protected" for aggregates producing values of such types.
We chose to use "and" to separate the reserved word ("private", "task", or "protected") from the list of specified components, because "with" was already in use for specifying extension aggregates. Other possibilities considered and rejected were:
1) (task Disc=>True) -- drop the "and"
2) (private with A,B,C) -- use "with" instead of "and"
(private X with A,B,C) -- and sneak the ancestor part before
-- the "with" if an extension aggregate -- (but then it sounds like "X" is private -- rather than some or all other components, -- and "(private X with null record)" is a loser)
3) (Disk=>True and task) -- put the reserved word at the end
(X with A, B and private) -- (seems potentially harder to parse -- since "and" is a legal binary operator)
4) (Disk=>True in task) -- use "in" rather than "and"
(X with A, B in private) -- (also harder to parse since "in" is legal within an expression)
!example
(See discussion.)
--!corrigendum 02.09(2)
!ACATS test
!appendix

From: Tucker Taft
Sent: Monday, February 7, 2005  4:32 PM

Here is my second-to-last AI before the meeting, on
issues relating to aggregates of a partial view,
task, or protected type.  I also suggest a rule
for when a task is activated that is part of an
object defined by an aggregate or a function call.

I did *not* propose wording for this, because it seems
so speculative, and deserves at least a vote on intent
in Paris to justify the effort.

[This is version /01 of the AI - ED]

*************************************************************

From: Erhard Ploedereder
Sent: Tuesday, February  8, 2005  12:10 PM

My comments on Tuck's as yet unnumbered AI:

1. The RM still lacks a rule for determining the master of the tasks
   created by partial view aggregates.

2. With the re-established coverage rules in this AI, why is it necessary
   at all to keyword the situation? I.e.,
   rather than
     (private and A,B,C => D)
   why not
     (A,B,C => D)   and a semantic rule that says that missing components
     are default initialized (presuming that the visible components all
     have been checked as present in the aggregate).

   This would do away with extra syntax (and discussions thereof). It has
   only one minor(?) flaw, if one considers it as a flaw:
     () becomes a valid aggregate. (I say, so what. Hardly worse than
           (private). Parsing issues? not really. Generics issues? possibly. )

   What am I missing?

3. Ceterum censeo in anticipation of actual wording:
   all this cannot possibly be presented under a
   syntax called record_aggregate. But we could globally rename
   to composite_aggregate. Not perfect because of the arrays, but
   definitely better than record_*.

4. We should air the issue on whether we want aggregates for non-private
   task and protected types.

*************************************************************

From: Tucker Taft
Sent: Tuesday, February  8, 2005  2:05 PM

> My comments on Tuck's as yet unnumbered AI:

I think Randy posted it as AI-416 [AI-413, actually - ED]

> 1. The RM still lacks a rule for determining the master of the tasks
>    created by partial view aggregates.

Are you implying that it would be different than that
for a "full view" aggregate?  I believe AI-162 was intended
to specify masters of all sorts of things.

> 2. With the re-established coverage rules in this AI, why is it necessary
>    at all to keyword the situation? I.e.,
>    rather than
>      (private and A,B,C => D)
>    why not
>      (A,B,C => D)   and a semantic rule that says that missing components
>      are default initialized (presuming that the visible components all
>      have been checked as present in the aggregate).

I think this could be quite misleading, and it introduces
the issue that you have more or fewer components depending
on where the aggregate is, which could create real
maintenance headaches or mysteries.  At least with "private"
you know that when you move the aggregate into a place that
has a full view, you need to replace "private" with the specification
of the previously hidden components.

>    This would do away with extra syntax (and discussions thereof). It has
>    only one minor(?) flaw, if one considers it as a flaw:
>      () becomes a valid aggregate. (I say, so what. Hardly worse than
>            (private). Parsing issues? not really. Generics issues? possibly. )
>
>    What am I missing?

I would rather not have partial view aggregates at all, than
to simply say you ignore the private components.

More importantly, there is some real subtlety about what
happens with controlled types, in particular, when and if
the "Initialize" procedure is invoked for an aggregate.
The AI I wrote indicates that if there is a "private,"
then Initialize will be invoked. We know that if there
is not private, as with current aggregates, Initialize is
*not* invoked for the aggregate. I think the presence of
"private" or something like it is important to make this
significant distinction.  (I realize I didn't emphasize
this in the AI, and I'm sorry.  But figuring out how
to handle the Initialize procedure was by far the
hardest part of getting the semantics right, and in fact
drove the decision to disallow specifying expressions
for limited components in a partial view aggregate.)

> 3. Ceterum censeo in anticipation of actual wording:
>    all this cannot possibly be presented under a
>    syntax called record_aggregate. But we could globally rename
>    to composite_aggregate. Not perfect because of the arrays, but
>    definitely better than record_*.

Perhaps "Other aggregates" as the name of the section,
and "other_aggregate" as the syntactic category.

> 4. We should air the issue on whether we want aggregates for non-private
>    task and protected types.

I think if we have partial view aggregates of a limited type,
then we should have task and protected type aggregates as well.
But I am willing to forego all three.

*************************************************************


Questions? Ask the ACAA Technical Agent