Version 1.2 of ais/ai-00366.txt

Unformatted version of ais/ai-00366.txt version 1.2
Other versions for file ais/ai-00366.txt

!standard 10.2.1          03-12-14 AI95-00366/01
!class amendment 03-12-14
!status work item 03-12-14
!status received 03-12-14
!priority Medium
!difficulty Easy
!subject More liberal rule for Pure units
!summary
Pure units allow access-to-subprogram tyes and access-to-object types, for which no storage pool is created.
!problem
In pure units access-to-subprogram types and access-to-object types, for which no storage pool is created, are presently prohibited. There is no technical reason for the restriction and many packages that should be pure can not be declared pure.
!proposal
(see wording)
!wording
Replace 10.2.1(16) A pure library_item is a preelaborable library_item that does not contain the declaration of any variable or named access type, except within a subprogram, generic subprogram, task unit, or protected unit. by: A pure library_item is a preelaborable library_item that does not contain the declaration of any variable or named access-to-object type, for which the Storage_Size has not been specified to be 0, excepting declarations within a subprogram, generic subprogram, task unit, or protected unit.
!discussion
Pure implies that a unit has no state. Access-to-object types are associated with storage pools, which constitute state. However, access-to-subprogram types have no such implications. Hence they should not be excluded. A corresponding correction of 10.2.1(16) would read: A pure library_item is a preelaborable library_item that does not contain the declaration of any variable or named access-to-object type, except within a subprogram, generic subprogram, task unit, or protected unit.
Beyond access-to-subprogram types, some packages have a need for an access-to-object type, without a need for a storage pool for the type, however. Setting the Storage_size of the type to zero implies that no storage pool (and hence no state) needs to be created.
The proposed !wording reflects these observations and removes the restriction on the presence of such access types.
!example
--!corrigendum
!ACATS test
An ACATS test checking that such types are allowed in Pure units should be constructed.
!appendix

From: Randy Brukardt
Sent: Tuesday, February 3, 2004  5:16 PM

In the context of AI-362, I was thinking about how to get any sort of
logging/debugging into a Preelaborated unit.

The problem is that once a preelaborated unit has that pragma applied, you can
no longer with any I/O. Without I/O, you can't have any logging for faults in a
fielded system (if the system dies, it probably won't get to dump an in-memory
log, making it useless for field debugging - you probably can't run a debugger
on the target system - think about NASA's rovers...)

I realized that something that my spam filter's code does provides a solution
(assuming some up-front work):

  package Something is
    pragma Preelaborate (Something);
    type Logger_Access is access procedure (Text : in String);

    procedure Do_Something (....; Logger : Logger_Access := null);
  end Something;

Then, a call to Do_Something can include a logger, even if the logger couldn't
be withed by the Preelaborated unit:
    Do_Something (...., Logger => Ada.Text_IO.Put_Line'Access);

If you do this consistently, with each preelaborated routine passing the logger
on through any calls, you can pretty much log anything you need in a
preelaborated unit. At the cost of an extra parameter to everything, of course.
(You could use a global variable as well, but that's UGLY!)

That's OK for preelaborated units, since that is mainly about library-level
elaboration: which necessarily has been completed before any call can be made.

However, AI-366 proposes to allow access-to-subprogram and
access-to-object-with-empty-pool in pure units. This means that it would be
trivial to pass an impure function to a Pure function, and thus make the
results vary even if the parameters are the same (as per the permission of
10.2.1(18)):

     package Impure is
          pragma Pure (Impure);
          type Random_Access is function return Float;

          function Use_Random (Random : in Random_Access) return Natural;

     end Impure;

     A := Use_Random (Random'Access);
     B := Use_Random (Random'Access);

Clearly, the calls to Use_Random have the same values for a by-copy parameter,
but A and B are unlikely to have the same values. Yet the compiler can omit the
second call.

Indeed, this permission allows me to write a "Pure" random number generator:

    package Pure_Random is
         pragma Pure (Pure_Random);
         type Generator is private;
         type Generator_Access is access all Generator;
         for Generator_Access'Storage_Size use 0;

         function Random (Gen : in Generator_Access) return Float;
    end Pure_Random;

    Gen : aliased Pure_Random.Generator;

    A := Pure_Random.Random (Gen'Access);
    B := Pure_Random.Random (Gen'Access);

Clearly, the permission of 10.2.1(18) applies to these calls, and yet it
clearly must not!

So it appears that AI-366 is incomplete, in that it should address this issue
somehow.

We'd really rather not allow such functions as Pure -- but that's the current
state; we could vote this AI No Action, but that's hardly responsive to the
problem.

One possibility is to do as the GNAT Pure_Function pragma, which is to say that
pragma Pure is an assertion that any functions always return the (logically)
same results and have no significant side-effects (without checking those
assertions). In which case, we can leave the permission alone.

But others have suggested that the permission of 10.2.1(18) is flawed anywhy
(that discussion was filed in AI-290 about pragma Pure_Function). Perhaps the
permission can be 'patched up' by including the values of access-to-object
parameters, and excluding the permission if there are any access-to-subprogram
parameters. (That's probably a bit too strong, but I'd rather err on the side
of correctness rather than optimization...)

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

Questions? Ask the ACAA Technical Agent