Version 1.3 of 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