Version 1.1 of ai05s/ai05-0140-1.txt

Unformatted version of ai05s/ai05-0140-1.txt version 1.1
Other versions for file ai05s/ai05-0140-1.txt

!standard 5.5          09-02-13 AI05-0140-1/01
!class Amendment 09-02-13
!status work item 09-02-13
!status received 09-01-19
!priority Medium
!difficulty Medium
!subject Identity functions
!summary
(See proposal.)
!problem
When creating an interface, procedures can be given a default interface that does nothing. However, there is no corresponding capability for functions, which means its always necessary to override a function declared in an interface, even when the function does nothing other than return a parameter.
!proposal
Add identity functions with new syntax:
function Dereference (Pool : in out Root_Storage_Pool; Access_Value : in Address) return Address is identity (2);
where "identity" is a new keyword and the number identifies the parameter to return.
[Editor's note: This was originally intended to be random musings in another proposal, but enough people were interested that we've elevated it to a real discussion item.]
!wording
** TBD **
!discussion
A way to think of identity functions (and null procedures for that matter) is that they provide a default implementation for an interface.
Note that the parameter returned can't be of the interface type (it doesn't have any information to be returnable). We might need a rule to that effect.
An alternative to the specifying the parameter number would be to specify the name. That is:
function Dereference (Pool : in out Root_Storage_Pool; Access_Value : in Address) return Address is identity (Access_Value);
That might be clearer as to what is meant.
One could even make this a regular simple return statement:
function Dereference (Pool : in out Root_Storage_Pool; Access_Value : in Address) return Address is return Access_Value;
allowing an expression of the parameters (thus allowing type conversions and the like). But that seems like it would be opening a can of worms.
!examples
!ACATS test
!appendix

From: Randy Brukardt
Date: Monday, January 19, 2009  9:20 PM

Following is one of a number of "trial-balloon" proposals for future
enhancements to Ada.

[This is version /01 of the AI - ED.]

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

From: Niklas Holsti
Date: Tuesday, January 20, 2009  2:19 AM

A small comment on Randy's syntax for identity functions:

> The closest analog to null procedures is identity functions...
>
> Thus, one could imagine defining a way to define identity functions.
> These are unfortunately more complex than null procedures, because of
> the need to identify the parameter that is the one returned. So, we've
> have to add something like:
>
> function Dereference (Pool : in out Root_Storage_Pool;
>                       Access_Value : in Address) return Address is
> identity (2);
>
> which means that the function is an identity function on the second
> parameter.

Rather than giving the parameter number, I would prefer to give the name of the
parameter to be returned, and even omit the new "identity" keyword:

    function Dereference (Pool : in out Root_Storage_Pool;
                          Access_Value : in Address)
    return Address is Access_Value;

This seems both more readable and more robust towards changes in the parameter
list.

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

From: Dmitry A. Kazakov
Date: Tuesday, January 20, 2009  2:00 PM

> This seems both more readable and more robust towards changes in the
> parameter list.

I think it would be wrong as well as the Randy proposal, though for different
reasons.

   function Foo (...) return ... is <implementation>;

in fact provides an implementation for Foo. Presently we have special
implementations:

1." is abstract" denotes no implementation 2. "is null" denotes null body 3.
"renames <Name>" denotes the body of <Name>

Apart for that renames obviously should be "is <Name>", first two are
inconsistent with:

1. Separation of specification and implementation. They shall not be allowed in
the package specification.

2. "is null" is inconsistent with the notion of interface. Interface may not
have implementations. From this point of view the thing Randy proposes breaks it
further. I don't care much about it, because the notion of interface type is
rubbish, but introducing rubbish in the first place one should try to uphold it.
(:-))

Returning to your proposal, it is wrong because <parameter-name> does not look
like a body. A body is a literal of some procedural type. From this point of
view Randy's identity is a function-valued function, that takes an argument and
produces a body. Granted, it should better be

   Lambda (Access_Value)

or better

   Access_Value'Lambda

and Identity (X) should better mean

   begin return X; end

so, for example:

   type Group is ...
   function Zero (X : Group) return Element is Identity (0);
   function One (X : Group)  return Element is Identity (1);

or

   type Linked_List_Element is ...;
   function Next (L : Linked_List_Element)
      return access Linked_List_Element is Identity (null);

Surely once you introduce this stuff you should also allow type conversion:

   type Linked_List_Element is ...;
   function Foo (X :String) return Unbounded_String is
      To_Unbounded_String (X'Lambda);

Which is technically a composition:

   To_Unbounded_String o X'Lambda

And also allow it as closures:

   procedure Inverse (A : in out Vector) is
   begin
      Update (A, -X'Lambda);
   end Inverse;

Instead of

   procedure Inverse (A : in out Vector) is
      function Update_Element (X :Element) return Element is
      begin
          return -X;
      end Update_Element;
   begin
      Update (A, Update_Element'Access);
   end Inverse;

I hope it is clear where it goes...

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


Questions? Ask the ACAA Technical Agent