Rationale for Ada 2012
4.6 Extended return statements
The final topic in this chapter is the extended return
statement. This was introduced in Ada 2005 largely to solve problems
with limited types. However, some glitches have come to light and these
are corrected in Ada 2012.
A description of the reasons for and general properties
of the extended return statement will be found in
15.
The syntax for extended return statement in Ada 2005
as found in
5 is
extended_return_statement ::=
return defining_identifier: [aliased] return_subtype_indication [:= expression] [do
handled_sequence_of_statements
end return];
Before going further, it should be mentioned that
there was some confusion regarding limited types and so the term immutably
limited was introduced in the course of the maintenance of Ada 2005.
There were various problems. Basically, limitedness
is a property of a view of a type. Thus even in Ada 83 a private type
might be limited but the full view found in the private part would not
be limited. Ada 95 introduced explicitly limited types. Ada 2005 introduced
coextensions and these could even include such obviously limited things
as task types thus adding a limited part to what was otherwise a seemingly
nonlimited type. It became clear that it was necessary to introduce a
term which meant that a type was really and truly limited and could not
subsequently become nonlimited for example in a private part or in a
child unit. So a type is immutably limited if
it is an explicitly limited record type,
it is a task type, protected type or synchronized
interface,
it is a non-formal limited private type that is
tagged or has an access discriminant with a default expression,
it is derived from an immutably limited type.
It was then realised that there were problems with
extended return statements containing an explicit
aliased. Consequently,
it was decided that there was really no need for
aliased if there
was a rule that immutably limited return objects were implicitly aliased.
So
aliased was removed from the syntax. However, some users had
already written
aliased and this would have introduced an irritating
incompatibility. So finally it was decided that
aliased could
be written but only if the type were immutably limited.
Another small problem
concerned constants. Thus we might write
return X: T do
... -- compute X
end return;
However, especially
in the case of a limited type LT, we might
also give the return object an initial value, thus
return X: LT := (A, B, C) do
... -- other stuff
end return;
Now it might be that although the type as a whole
is limited one or more of its components might not be and so could be
manipulated in the sequence of statements. But if we want to ensure that
this does not happen, it would be appropriate to indicate that
X
was constant. But, almost surely by an oversight, we cannot do that since
it is not permitted by the syntax. So the syntax needed changing to permit
the addition of constant.
To aid the description
the syntax in Ada 2012 is actually written as two productions as follows
extended_return_object_declaration ::=
defining_identifier: [aliased] [constant] return_subtype_indication [:= expression]
extended_return_statement ::=
return extended_return_object_declaration [do
handled_sequence_of_statements
end return;
The other small change to the extended return statement
concerns the subtype given in the profile of the function and that in
the extended return statement itself. The result type of the function
can be constrained or unconstrained but that given in the extended return
statement must be constrained.
This can be illustrated
by considering array types. (These examples are from
15.)
Suppose we have
type UA is array (Integer range <>) of Float;
subtype CA is UA(1 .. 10);
then we can write
function Make( ... ) return CA is
begin
...
return R: UA(1 .. 10) do -- statically matches
...
end return;
end Make;
This is allowed because the subtypes statically match.
If the subtype in the function profile is unconstrained
then the result must be constrained either by its subtype or by its initial
value. For example
function Make( ... ) return UA is
begin
...
return R: UA(1 .. N) do
...
end return;
end Make;
and here the result
R is constrained by its subtype. A similar
situation can arise with records with discriminants. Thus we can have
type Person(Sex: Gender) is ... ;
function F( ... ) return Person is
begin
if ... then
return R: Person(Sex => Male) do
...
end return;
else
return R: Person(Sex => Female) do
...
end return;
end if;
end F;
which shows that we have the possibility of returning
a person of either gender.
However, what is missing from Ada 2005 is that we
can have analogous situations with tagged types in that a function might
wish to return a value of some type in a class.
So we would like to
write things such as
function F( ... ) return Object'Class is
begin
if ... then
return C: Circle do
...
end return;
elsif ... then
return S: Square do
...
end return;
end if;
end F;
This is not permitted
in Ada 2005 which required the types to be the same. This can be overcome
by writing
return C: Object'Class := Circle_Func do
...
end return;
where Circle_Func is some
local function that returns the required object of type Circle.
This is all rather irksome so the wording is changed
in Ada 2012 to say that in this situation the subtype in the extended
return statement need not be the same as that in the profile but simply
must be covered by it. There are also related slight changes to the accessibility
rules.
© 2011, 2012, 2013 John Barnes Informatics.
Sponsored in part by: