Version 1.3 of ais/ai-00390.txt

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

!standard 08.05.04 (02)          04-11-14 AI95-00390/02
!standard 08.05.04 (03)
!class amendment 04-11-13
!status No Action (9-0-1) 04-11-20
!status work item 04-11-13
!status received 04-11-13
!priority Low
!difficulty Easy
!subject Defining by renaming an inherited subprogram
!summary
The notation "<>" in a subprogram_renaming_declaration may be used to define a primitive subprogram in terms of a same-named inherited subprogram.
!problem
When defining a private type, it is often the case that one or more of the operations of the full type want to be exposed. Ada provides no easy way to do that without having the programmer explicitly write wrappers. This is a nuisance and a potential source of errors due to cut-and-paste mistakes or other mistakes that occur when programmers are forced to due repetitive menial tasks.
!proposal
A renaming-as-body may be given in the private part of a package where the renamed subprogram is identified simply with a "<>". What this notation means is that the inherited subprogram of the same name as the subprogram being defined is to be renamed.
!wording
Add after 8.5.4(2):
subprogram_renaming_as_body ::= subprogram_renaming_declaration | subprogram_specification renames <>
Add after 8.5.4(3):
In a subprogram_renaming_as_body with "RENAMES <>", the renamed callable entity is the inherited subprogram or predefined operator that is overridden by the subprogram_declaration completed by the renaming.
!discussion
This AI attempts to fix a long-standing difficulty with private types, where one wants to expose some but not all of the operations of the full type. To do so currently, one must go through a tedious and hence error-prone process of creating wrappers for all operations of the full type to be exposed. The proposed notation seems a natural solution, given the renaming-as-body capability, and it has been proposed several times in the past. A potential justification for doing this now is that we have added a number of containers that provide large numbers of operations, of which only a subset might be appropriate for a private type implemented using one of these container abstractions.
!example
-- Here is an example where we define an integer set type -- and then implement it using an instantiation of a set generic. -- Many, but not all of the operations from the generic -- are to be reexported for the private integer set type.
generic with type Element is private; package Sets is -- A typical "set" generic type Set is private; function Union(Set1, Set2 : Set) return Set; function Intersection(Set1, Set2 : Set) return Set; ... end Sets;
...
type Int_Set is private; -- A private integer "set" type. function Union(L, R : Int_Set) return Int_Set; function Intersection(L, R : Int_Set) return Int_Set; ...
private package Int_Sets is new Sets(Integer); type Int_Set is new Int_Sets.Set; -- Union and Intersection inherited from Int_Sets.Set, -- and then immediately overridden by the explicitly declared -- operations from the visible part
function Union(L, R : Int_Set) return Int_Set renames <>; function Intersection(L, R : Int_Set) return Int_Set renames <>; -- Define visible operations by renaming the ones they override
--------
-- Here is an example where we provide a string reference -- type, which makes it more convenient to deal with strings -- by using a level of indirection. The "=" turns out -- to be able to use the predefined operation, although that -- is only because we plan to store all the strings in a hash -- table so that the string_ref is one-to-one with distinct -- strings.
type String_Ref is private; function To_Ref(S : String) return String_Ref; function To_Str(R : String_Ref) return String; function "="(R1, R2 : String_Ref) return Boolean; -- Return True if R1 and R2 designate equal strings function "&"(R1, R2 : String_Ref) return String_Ref; ...
private type String_Rec(Len: Natural) is record Text : String(1..Len); Next_Same_Hash : String_Ref; end record;
type String_Ref is access String_Rec; -- predefined "=" declared here and then immediately overridden -- by explicitly declared one from visible part function "="(R1, R2 : String_Ref) return Boolean renames <>; -- define "=" in terms of predefined operator it overrode -- because unique hashing will ensure the predefined -- operator works correctly
--!corrigendum
!ACATS test
ACATS tests need to be constructed to test this feature.
!appendix

From: Tucker Taft
Sent: Saturday, November 13, 2004  5:34 PM

Here is an AI [This is version /01 - ED] attempting to address a
long-standing annoyance with private types, where one wants to expose
some but not all of the operations of the full type.
This seems more important now that we have a number of
container abstractions which provide large numbers of
operations, only some of which would typically be
exposed for a private type implemented in terms of
one of these containers.

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



Questions? Ask the ACAA Technical Agent