Version 1.1 of acs/ac-00165.txt

Unformatted version of acs/ac-00165.txt version 1.1
Other versions for file acs/ac-00165.txt

!standard 3.2.3(1)          08-07-12 AC95-00165/01
!class confirmation 08-07-12
!status received no action 08-07-12
!status received 08-05-14
!subject Definition of primitive subprogram
!summary
!appendix

!topic Definition of "primitive subprogram"
!reference 3.2.3
!from Adam Beneschan 08-05-14
!discussion

On April 28, Randy wrote:

> P.S. I think we may need to rename this list to "Adam-Comment"! ;-)

Since the entire discussion on this list since that point has consisted of Randy
posting a "Testing" message, maybe the above quote means that it's up to me to
keep things interesting?

Anyway, I was looking over the definition of "primitive subprogram" closely, and
something suddenly seemed rather bizarre about it.  It is certainly necessary to
know whether a subprogram is a primitive subprogram of a type, since this
affects a programmer's understanding of dispatching and of other rules (I
happened to be looking into 3.10.1(9.3) at the time).  3.2.3(6) says that these
are primitive subprograms:

    For a specific type declared immediately within a
    package_specification, any subprograms (in addition to the
    enumeration literals) that are explicitly declared immediately
    within the same package_specification and that operate on the
    type;

So to figure out what "operate on a type" means, we look at 3.2.3(1):

    An operation operates on a type T if it yields a value of type T,
    if it has an operand whose expected type (see 8.6) is T, or if it
    has an access parameter or access result type (see 6.1)
    designating T.

This is what I suddenly realized is somewhat strange.  I suppose we can assume
that "operations" includes "subprograms" (both procedures and functions),
although I don't think this is explicitly stated anywhere in the RM, and
"operation" doesn't appear in the index (RM83 3.3.3(1) was better about this, I
think, but I'm sure that definition led to other problems in Ada 95).

What's strange is the inconsistent wording of that definition.  First it talks
about an operation yielding a value, and the expected type of the operands, and
then it suddenly switches to talking about parameter and result types (albeit
only for anonymous access types).  The latter is what makes sense when talking
about a subprogram.  But the first part of the sentence seems to be talking more
about a *call* to a subprogram, rather than to a subprogram itself (i.e. a
subprogram declaration).  In particular, there are no "expected types" in a
subprogram declaration (except for parameter defaults), so speaking about the
"expected type of an operand" doesn't seem to fit at all, if you're looking at a
subprogram declaration and trying to determine whether it's a primitive
operation of some type.  The reference to 8.6 seems to be out of place here.

This isn't a big deal, since I doubt that anyone (even me) has failed to
understand how to apply 3.2.3(1) correctly.  It probably isn't worth fixing.
But it just occurred to me that this is quite a strange way to word things, as
opposed to saying simply that a subprogram operates on a type T if it has a
parameter or result type that is T or an access parameter or access result type
designating T.

An aside: It appears that the terms "primitive operation" and "predefined
operation" aren't used consistently, at least in the AARM. 3.2.3(1) implies that
assignment and membership tests are considered "predefined operation" and
"primitive operations"; but AARM 3.9(1.a) suggests that tagged type descriptors
are intended to contain the address of the code for "each primitive operation"
of the type, and B.2(9.a) says it's a language design principle that all
predefined operations should be operators.  So some places seem to assume that
primitive or predefined "operations" include things other than subprograms, and
other places seem to assume that they are subprograms.

Oh, well... I just thought I'd mention this; please feel free to dump this
directly into the Ada Commentaries.....

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

From: Randy Brukardt
Date: Thursday, May 15, 2008  1:54 AM

...
> This is what I suddenly realized is somewhat strange.  I suppose we
> can assume that "operations" includes "subprograms" (both procedures
> and functions), although I don't think this is explicitly
> stated anywhere in the RM, and "operation" doesn't appear in the index ...

I'm not sure it matters much. Since 3.2.3(6) discusses subprograms that "operate
on the type" and 3.2.3(1/2) defines the phrase "operates on the type" [by the
italics], it's obvious that 3.2.3(6) is using the definition of 3.2.3(1/2).
"operation" here is just a placeholder word used to make this read OK; it has no
formal meaning (it's essentially a variable to be replaced by the actual entity
in this case). It could have been anything: "entity", "item", or "muggywump"
;-). Note that "primitive operation" and "predefined operation" is formally
defined, but not operation by itself.

> What's strange is the inconsistent wording of that definition.  First it
> talks about an operation yielding a value, and the expected type of the
> operands, and then it suddenly switches to talking about parameter and
> result types (albeit only for anonymous access types). The latter is what
> makes sense when talking about a subprogram.  But the first part of the
> sentence seems to be talking more about a *call* to a subprogram, rather
> than to a subprogram itself (i.e. a subprogram declaration).  In particular,
> there are no "expected types" in a subprogram declaration (except for
> parameter defaults), so speaking about the "expected type of an operand"
> doesn't seem to fit at all, if you're looking at a subprogram declaration
> and trying to determine whether it's a primitive operation of some type.
> The reference to 8.6 seems to be out of place here.

I agree that the reference to "expected type" is mysterious here. It probably
should just say that it has a parameter or result that is a subtype of type T.
I'm not sure why it doesn't say that, and the AARM is no help. OTOH, any
confusion is momentary.

...
> Oh, well... I just thought I'd mention this; please feel free to dump
> this directly into the Ada Commentaries.....

I'll be happy to take you up on this request presuming no one else wants to
change this wording. If they do, they ought to speak up now...

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

From: Christoph Grein
Date: Thursday, May 15, 2008  4:25 AM

> I agree that the reference to "expected type" is mysterious here. It
> probably should just say that it has a parameter or result that is a
> subtype of type T.

If the fix is really that simple, it should be done IMHO.

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

From: Randy Brukardt
Date: Thursday, May 15, 2008  2:25 PM

> > I agree that the reference to "expected type" is mysterious here. It
> > probably should just say that it has a parameter or result that is a
> > subtype of type T.
>
> If the fix is really that simple, it should be done IMHO.

Ah, but you've forgetten the critical rule: "If it ain't broke, don't fix it!!".

Without a clear understanding of why "expected type" is used in this wording,
removing it could introduce subtle incompatibilies or simply break something.

The effect is that this "simple" change would require a lot of study to ensure
that it is OK. There are probably better uses of our time (such as fixing things
that are actually broken - there seem to be plenty of those, we're up to 100
AI05s already).

OTOH, if someone can think of a way that this current wording is actually
broken, then we'd have to go through this effort. Or if someone (Tucker?)
remembers why this is worded the way it is (thus reducing the risk of a change).

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

Questions? Ask the ACAA Technical Agent