Version 1.1 of acs/ac-00046.txt

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

!standard 3.09.03(4-6)          02-08-28 AC95-00046/01
!standard 3.09.02(2)
!class confirmation 02-08-21
!status received no action 02-08-28
!subject
!summary
!appendix

!topic Function on untagged partial view must be overridden?
!reference RM95-3.9.3(4-6), AI95-00183, 3.9.2(2)
!from Adam Beneschan 08-21-02
!discussion

I believe this code fragment is illegal; is my analysis correct?

   package Pak1 is
      type T1 is private;
      function Func return T1;
   private
      type T1 is tagged record
         Some_Component : Integer;
      end record;
   end Pak1;

   with Pak1;
   package Pak2 is
      type T2 is new Pak1.T1;
   end Pak2;

AI95-00183 makes it clear that Func is a dispatching operation of T1,
and therefore Func is a primitive function with a controlling result
(3.9.2(2)).  Since T2 is a derived type and T2's parent has a
primitive function with a controlling result, 3.9.3(4-6) applies, and
therefore Func is required to be overridden.

However, I'm not sure that it should be illegal.

The motivation behind requiring a function that returns a tagged type
to be overridden for a type extension is that it makes no sense for a
function to be inherited for a type extension, since the function
wouldn't know how to fill in the components in the extension.  In the
above case, though, T2 is not a type extension, and thus I can see no
reason why Func couldn't be inherited.  A problem with the rule in
this case is that, ideally, when you're using a private type declared
in another (non-ancestor) package, you shouldn't have to know anything
about the full declaration of the type; but here, you do have to know
about the full type declaration in order to avoid an error.

So I think the rule in 3.9.3(4) should be changed so that it does not
apply to a type derived from an untagged partial view.  Unless, of
course, there's something I'm missing that already makes the above
example legal.

(Off-topic nitpick: When I was looking into this, I noticed that
3.9.3(4) refers to a "primitive function with a controlling result";
however, as far as I can tell, the RM does not define what it means
for a primitive function to have a controlling result.  It does define
what it means for a *call* to have a controlling result (3.9.2(2)),
but a function is not a call.  I think it's obvious what is meant, but
the RM shouldn't be using undefined terms like this.)

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

From: Adam Beneschan
Sent: Thursday, August 22, 2002  11:05 AM

I wrote:

> I believe this code fragment is illegal; is my analysis correct?
>
>    package Pak1 is
>       type T1 is private;
>       function Func return T1;
>    private
>       type T1 is tagged record
>          Some_Component : Integer;
>       end record;
>    end Pak1;
>
>    with Pak1;
>    package Pak2 is
>       type T2 is new Pak1.T1;
>    end Pak2;
>
> AI95-00183 makes it clear that Func is a dispatching operation of T1,
> and therefore Func is a primitive function with a controlling result
> (3.9.2(2)).  Since T2 is a derived type and T2's parent has a
> primitive function with a controlling result, 3.9.3(4-6) applies, and
> therefore Func is required to be overridden.

On rereading AI95-00183, I noticed that I has missed something, due
either to an unfulfilled need for bifocals or to not noticing the
importance of the last phrase of this sentence:

"A primitive subprogram declared for the partial view is a dispatching
subprogram of the full view."

I assume that the last phrase, "of the full view", means that Func is
considered a dispatching operation (and thus a function with a
controlling result) *only* in places where the full view of the type
is visible, and thus is not considered to be a dispatching operation
(or a function with a controlling result) in places where only the
partial view is visible, including in Pak2.  Thus, in Pak2, 3.9.3(4)
doesn't apply, and the code is legal.

Did I get it right this time?

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

From: Pascal Leroy
Sent: Thursday, August 22, 2002  9:08 AM

The way I read the manual, the example is legal, albeit a bit weird.

The derived type T2 is untagged, so it would seem that 3.9.3(5) would apply,
and the inherited Func is abstract, and doesn't have to be overridden.  It
cannot be used to do anything useful, of course, but it probably doesn't
harm.

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

From: Adam Beneschan
Sent: Thursday, August 22, 2002  3:33 PM

It may not be as weird as you think.  If Ada.Strings.Unbounded.-
Unbounded_String (defined as untagged private) is implemented as a
child of Ada.Finalization.Controlled (which is tagged), as suggested
by the Rationale, then any package that tries to derive from
Unbounded_String will run into this situation.  (We've seen real-life
Ada code that does define types derived from Unbounded_String.)

However, as I said in my follow-up post, it probably isn't really a
problem, since I missed a couple words in AI-183.

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

From: Bob Duff
Sent: Saturday, August 24, 2002  5:22 PM

> Did I get it right this time?

Yes, I think so.  The *view* of the type is what matters.

One "meta rule" is that the legality of Pak2 can't depend on the private
part of Pak1.  (This is Pascal's favorite meta rule, by the way.  ;-))

Pascal replied:

> The way I read the manual, the example is legal, albeit a bit weird.

Well, it *should* be legal, I think.

> The derived type T2 is untagged, so it would seem that 3.9.3(5) would apply,
> and the inherited Func is abstract, and doesn't have to be overridden.  It
> cannot be used to do anything useful, of course, but it probably doesn't
> harm.

But I don't see why the inherited Func should be abstract.
Type T2 does not introduce a new tag, so why can't one call Func?
I think the "view" is what matters -- Func does not have a controlling
result when viewed from outside Pak1.

If it were Pak1.Pak2 (a child), the story would be different.

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


Questions? Ask the ACAA Technical Agent