Version 1.2 of ai05s/ai05-0283-1.txt

Unformatted version of ai05s/ai05-0283-1.txt version 1.2
Other versions for file ai05s/ai05-0283-1.txt

!standard A.12.1(3)          11-12-30 AI05-0283-1/02
!class Amendment 11-11-08
!status work item 11-11-08
!status received 11-09-28
!priority Low
!difficulty Easy
!subject Stream_IO should be preelaborated
!summary
Ada.Stream_IO is be preelaborated.
!proposal
Ada.Stream_IO should be preelaborated, so that logging, persistence, and the like can be programmed for packages that support Annex E.
!wording
Add pragma Preelaborate (Stream_IO) to A.12.1(3).
!discussion
We polled Ada implementers, and none of the implementers responding noted any significant problems with this change. Respondents were: AdaCore (GNAT), Sofcheck (AdaMagic), RR Software (Janus/Ada), DDCI (SCORE Ada), and Irvine.
!ACATS test
An ACATS C-Test should be constructed to check that Stream_IO can be withed in a Preelaborated package.
!ASIS
No ASIS impact.
!appendix

!topic IO packages should have preelaborate aspect
!reference Ada 2005 RM A.10.1 (2)
!from /Brad Moore 11-09-27/
!keywords Preelaborate Remote_Types Text_IO
!discussion

It would be nice if the IO packages (Ada.Text_IO, etc)
had the Preelaborate aspect. This would
facilitate use for Remote_Types. This would make it easier to
create RACW types that have persistence, provide remote file
access, and database access for direct IO, for example.
One cannot currently with IO packages from a Remote_Types package,
because the IO packages are not preelaborable.

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

From: Randy Brukardt
Sent: Wednesday, September 28, 2011  7:33 PM

This problem was extensively discussed during the Ada 2005 work -- see
AI95-0362-1. Note that the problem statement in that AI specifically
mentions IO.

The discussion section of that AI gives a very detailed look at the results
of that discussion. It should be noted that the original version of the AI
proposed making Direct_IO, Sequential_IO and Stream_IO preelaborable
(Text_IO is not reasonable for reasons discussed in the AI). We circulated
that to implementers to get feedback, and various objections were recorded.
In the end, those proposals were dropped in order to get consensus on the
remainder of the AI.

Calendar and Text_IO are the biggest impediment to making most packages
Preelaborable, but it does not appear reasonable for either to be
Preelaborable. (And probably Calendar shouldn't be a Remote_Types package
even if it was Preelaborable.) There was a brief amount of discussion of
having a Preelaborable "Simple_Text_IO", but that appeared like a long
argument over exactly what to include (the original proposal not having any
file I/O, just StdOut, making it useless for logging, my #1 need).

A case can be made for the other I/O packages, but that case would have to
be stronger than the one I made in 2003. (Wow, was it really that long ago?)
I'm pretty sure "It would be nice" is not a strong case. :-) So if you have
more examples of places where I/O was needed in preelaborated units, it
would help consideration of your proposal.

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

From: Brad Moore
Sent: Thursday, September 29, 2011  12:58 AM

> The discussion section of that AI gives a very detailed look at the results
> of that discussion. It should be noted that the original version of the AI
> proposed making Direct_IO, Sequential_IO and Stream_IO preelaborable
> (Text_IO is not reasonable for reasons discussed in the AI). We circulated
> that to implementers to get feedback, and various objections were recorded.
> In the end, those proposals were dropped in order to get consensus on the
> remainder of the AI.

In my particular case, I was looking for Direct_IO to have the
preelaborate pragma. I was implementing
a suite of buffer generics (essentially a deque container), including
persistent buffers where the storage for the buffer is
entirely in a file. The buffers were designed to support remote access
via Remote Access to Class Wide
types (RACW types). I ended up having to create my own IO package,
called Preelaborated_IO.
Note using GNAT_IO was not a possibility because;
    1) I needed the package to be generic, where the element type is a
generic formal parameter. GNAT_IO is non-generic and only
        deals with integers, and strings.
    2) I wanted the buffers to be portable to other compiler vendors.

> Calendar and Text_IO are the biggest impediment to making most packages
> Preelaborable, but it does not appear reasonable for either to be
> Preelaborable. (And probably Calendar shouldn't be a Remote_Types package
> even if it was Preelaborable.) There was a brief amount of discussion of
> having a Preelaborable "Simple_Text_IO", but that appeared like a long
> argument over exactly what to include (the original proposal not having any
> file I/O, just StdOut, making it useless for logging, my #1 need).

I think I'm OK with Text_IO not being preelaborable. I'm more interested
in Sequential_IO and Direct_IO.

> A case can be made for the other I/O packages, but that case would have to
> be stronger than the one I made in 2003. (Wow, was it really that long ago?)
> I'm pretty sure "It would be nice" is not a strong case. :-) So if you have
> more examples of places where I/O was needed in preelaborated units, it
> would help consideration of your proposal.

If I was asked before I had implemented my own package, my response
would have been  a lot stronger,
possibly, "It would be bleeping awesome!"

Also, all the buffer containers (including non-persistent ones) have a
Save and a Restore primitive that
can load or save the container to a file, which is another case where I
needed to use Preelaborated_IO.

Maybe such primitives might be worth considering some day for the
Standard Ada containers?
While a container can be streamed to a file, it is not as convenient,
nor likely as efficient, as having a Save and Restore primitive.

It seems a shame that every time someone wants to do something similar
with Remote_Types packages, they would have to end up
writing their own Preelaborated_IO package. (Or possibly use mine)

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

From: Randy Brukardt
Sent: Thursday, September 29, 2011  1:18 AM

...
> If I was asked before I had implemented my own package, my
> response would have been  a lot stronger, possibly, "It would
> be bleeping awesome!"

<Grin>

> Also, all the buffer containers (including non-persistent
> ones) have a Save and a Restore primitive that can load or
> save the container to a file, which is another case where I
> needed to use Preelaborated_IO.

That sounds like a job for a (Preelaborated version of) Stream_IO.

> Maybe such primitives might be worth considering some day for
> the Standard Ada containers?
> While a container can be streamed to a file, it is not as
> convenient, nor likely as efficient, as having a Save and
> Restore primitive.

No, you just need a memory stream. Claw has such a stream (I think we called
it a marshalling stream); we use it for writing to/from the clipboard and
registry (but we also made it generally available). It's better to do that
than reinvent the wheel (for streaming).

I think the Standard should have something similar. Ada has Storage_IO for
this purpose, but that isn't likely to work with user-defined types
(certainly not if there is any indirection in the types).

> It seems a shame that every time someone wants to do
> something similar with Remote_Types packages, they would have
> to end up writing their own Preelaborated_IO package. (Or
> possibly use mine)

Probably we should bite the bullet and make Stream_IO preelaborated (you can
write all of the others using it, and most of the time you would be better
off using it anyway -- almost all non-text files are heterogeneous in
practice). Otherwise, we should create a preelaborated version of it, but
there doesn't seem to be much point in having two packages with the same
contents.

If we left the others alone, the pain would be fairly localized. And a
motivated user could write their own Sequential_IO and Direct_IO analogs.

Anyway, something to consider.

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

From: Brad Moore
Sent: Saturday, October  1, 2011  10:39 AM

I agree with your suggestion. That sounds like the best way forward.

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

Editor's note: The following was in the original Ada 2012 version of the
AI, but it is not appropriate in the Ada 2005 AI (because we're not likely
to add significant packages at this point).

---

The e-mail thread also touches on the need to be able to
serialize containers into memory-based structures. The best way to
do this is with a memory stream. Claw defines one to use for writing
to the registry and clipboard (and also makes it available to users).
Ada probably ought to have one. Claw's version looks like:

with Ada.Streams;
package Claw.Marshalling is

  -- Writes to a buffer will allocate additional memory from the
  -- heap as needed.  If you know reasonably accurately how much
  -- you'll need, it will be more efficient to make the
  -- Initial_Length big enough and thus avoid heap allocation.
  --
  -- Any heap allocation will be freed automatically when a Buffer
  -- ceases to exist.

  type Buffer_Type(Initial_Length : Ada.Streams.Stream_Element_Count)
    is new Ada.Streams.Root_Stream_Type with private;

  procedure Read(
    Stream : in out Buffer_Type;
    Item   :    out Ada.Streams.Stream_Element_Array;
    Last   :    out Ada.Streams.Stream_Element_Offset);

  procedure Write(
    Stream : in out Buffer_Type;
    Item   : in     Ada.Streams.Stream_Element_Array);

  function Length(Stream : in Buffer_Type)
      return Ada.Streams.Stream_Element_Count;
	-- Return the total length of data written into the buffer.

  procedure Clear(Stream : in out Buffer_Type);
	-- Empty the buffer.

private
  ...
end Claw.Marshalling;

Should we consider something on this line for Ada??

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

From: Randy Brukardt
Sent: Tuesday, November 15, 2011  12:41 PM

The ARG would like input from implementers on the following topic:

What would the effect of declaring that Ada.Streams.Stream_IO is preelaborated
be on your implementation?

Background:

Currently, no I/O packages in the Ada Standard are considered preelaborated.
This means that tricks (using pragma Import to break the rules, or passing in
access-to-subprogram parameters to do the I/O) are necessary to use any I/O in
preelaborated packages. This makes common tasks such as logging and persistent
objects harder and much more obscure than otherwise would be required. This is
especially a problem in distributed (Annex E) programs, where large parts of
each partition is required to be Preelaborated to support distribution.

We considered making such a change to all of the I/O packages in Ada 2005, but
some of the features of the packages (especially Text_IO) made it difficult to
implement. There also was quite a bit of disruption to some existing Ada
implementations. In the end, we did not make any change in Ada 2005.

But of course the problem has not gone away. Therefore, the ARG is now
considering only changing Stream_IO (on top of which any needed I/O can be
constructed, and which typically would be used directly to implement
persistence) to be preelaborated, as it supports simple, (potentially)
hetrogenous I/O.

Investigations done during the recent ARG meeting showed that the change is not
significant for two widely-used implementations (AdaMagic and GNAT) --
essentially, the pragma needed to be applied to the Stream_IO package and a few
units that it uses. As such, the ARG would like to make this change in Ada 2012
(as it is only a one-line change to the Ada Standard) -- but it doesn't want to
do that if it causes hardships to many other Ada implementations.

Please note that we are *not* considering making Stream_IO a Remote_Types
package, as transporting file values (especially in a hetrogenous system) does
not make much sense. The only change contemplated is adding pragma
Preelaborate(Stream_IO) to the package Ada.Streams.Stream_IO.

Thank you for your help.

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

From: Tucker Taft (SofCheck)
Sent: Tuesday, November 15, 2011  1:17 PM

As I mentioned during the ARG meeting,
this is no problem for SofCheck's AdaMagic product.

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

From: Randy Brukardt (RRSoftware)
Sent: Tuesday, November 15, 2011  1:45 PM

Which was mentioned in the body of the message. But it doesn't hurt to repeat
it.

As for new information, (changing hats here), I just made this change in the
working version of Janus/Ada. I needed to make a small change to our core I/O
unit (Basic_IO) to only check the search path upon the first Open that needs it
rather than when Basic_IO elaborates. I don't expect that to have much impact
(it will increase the memory use of Open somewhat, but any program with tight
stack memory requirements that is doing file I/O is probably going to have
problems anyway). Otherwise, the change just required adding the pragma to the
two units (Stream_IO and the previously mentioned Basic_IO).

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

From: Gary Dismukes (AdaCore)
Sent: Tuesday, November 15, 2011  2:18 PM

> Investigations done during the recent ARG meeting showed that the
> change is not significant for two widely-used implementations
> (AdaMagic and GNAT) -- essentially, the pragma needed to be applied to
> the Stream_IO package and a few units that it uses. ...

It turns out that there's a little more change than that required for GNAT.
Mostly its adding Preelaborate to a few packages, but there's a reference to an
imported max_path_len variable in one of the support packages (in a record
type's string component range) and one place where a warning needs to be
suppressed.  The string bound violation is an issue that can probably be
addressed in some way, so it still looks feasible for GNAT.

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

From: Johan O. Nielsen (DDCI)
Sent: Wednesday, November 16, 2011  4:29 PM

The really short answer is No effect. SCORE Ada already has added a pragma
Preelaborate to Ada.Streams.Stream_Io.

SCORE Ada is still mostly Ada 95 but I don't see any changes in Ada 2005 or
proposed changes in Ada 2012 that would make it more difficult for our
Ada.Streams.Stream_Io to be preelaborated. The statements here are based on the
understanding that no other Stream_Io changes are introduced compared to Draft
14. I agree with the general desire to make as much of the language available in
preelaborated units so this change is welcomed.

It would be unproblematic for SCORE Ada to go a little further in this area and
add the pragma for Ada.Direct_Io and Ada.Sequential_Io as well. On the other
hand, I don't think we can hope to ever make the Text_Io packages preelaborated.

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

From: Adam Beneschan (Irvine)
Sent: Wednesday, November 16, 2011  5:24 PM

I just tried this and adding this pragma isn't significant for us at all.  (In
fact, I added the pragma to the Stream_IO package and it compiled without any
other changes being needed.)

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

From: Dan Eilers (Irvine)
Sent: Friday, November 18, 2011  10:37 AM

> The ARG would like input from implementers on the following topic:
>
> What would the effect of declaring that Ada.Streams.Stream_IO is
> preelaborated be on your implementation?

Adam responded directly to Randy that this works fine for us with no other
changes.

I notice that this issue is currently categorized as:
> AI12-0010-1/01   2011-11-08 --  Stream_IO should be preelaborated

under the heading in the Denver ARG agenda:
> Ada 2012 AIs (to fix issues in the Ada 2012 Standard, most likely
> after the Standard is issued):

I would strongly recommend changing this from an Ada 2012 AI to an Ada 2005 AI,
so it makes it into the Ada 2012 standard, since it provides a very simple
solution to an important problem that has no other good solutions available.
Perhaps it should even be a binding interpretation, so it can be implemented in
Ada 2005 compilers and used in Ada 2005 code.

The reason I think this is important is that I personally spent a considerable
amount of time debugging a very complicated piece of Ada 2005 software that
tried to work aound this problem by supplying a custom pre-elaborable version of
text_io, which turned out to be non-portable because it relied on the layout of
the Unix stat record.

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

From: Randy Brukardt
Sent: Friday, November 18, 2011  1:13 PM

...
> I would strongly recommend changing this from an Ada 2012 AI to an Ada
> 2005 AI, so it makes it into the Ada 2005 standard, since it provides
> a very simple solution to an important problem that has no other good
> solutions available.  Perhaps it should even be a binding
> interpretation, so it can be implemented in Ada 2005 compilers and
> used in Ada 2005 code.

As noted in my original message, including it in Ada 2012 is our intent of
asking about it now. This is only a one-line change in the Standard, much
smaller than many editorial fixes, and it adds a lot of capability. It might be
a bit much for a BI (it changes the memory use of Open substantially in
Janus/Ada, for instance - I could easily imagine that breaking programs).

BTW, I've also heard from DDCI that this would not cause any problems for them.
So, so far, we've heard from 5 implementers with no reports of any serious
problems. Looks like a GO so far.

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


Questions? Ask the ACAA Technical Agent