CVS difference for ais/ai-00366.txt

Differences between 1.2 and version 1.3
Log of other versions for file ais/ai-00366.txt

--- ais/ai-00366.txt	2004/02/04 00:51:14	1.2
+++ ais/ai-00366.txt	2004/02/06 05:01:49	1.3
@@ -159,3 +159,590 @@
 of correctness rather than optimization...)
 
 ****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, February 3, 2004  8:08 PM
+
+If we allow "pure" access types, then clearly the
+values of the variables accessible via an access value
+must be included in 10.2.1(18).  The variables accessible
+via an access-to-subprogram value include any variables
+visible to the designated subprogram.  The variables
+accessible via an access-to-object value include the
+designated object, and any variables that can be reached
+from there via following access values.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, February 4, 2004  7:12 AM
+
+I don't see that there is anything new here.  You can do the same
+currently if Random has an access parameter, because 10.2.1(16) only
+talks about named access types.
+
+I believe that the rules that 10.2.1(18) specifies for by-reference
+types should also apply to access types,.
+
+Actually I would be in favor of deleting 10.2.1(18) altogether, as it's
+one of these rules (like 11.6) which effectively says "forget the rest
+of this book, we don't really mean it".  But I guess that's a different
+discussion.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, February 4, 2004  7:16 AM
+
+Yes, that's a very different discussion ;-).
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, February 4, 2004  7:36 AM
+
+Remember that you can always do anything by doing raw import
+rather than WITH.
+
+It is really nothing to get worried about that this sort of
+thing can be done.
+
+Pure does NOT mean that a function is pure in the formal
+sense, just that the compiler can make assumptions about
+deleting identical calls, and deleting useless calls.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, February 4, 2004  7:41 AM
+
+Pascal Leroy wrote:
+
+> Actually I would be in favor of deleting 10.2.1(18) altogether, as it's
+> one of these rules (like 11.6) which effectively says "forget the rest
+> of this book, we don't really mean it".  But I guess that's a different
+> discussion.
+
+This would be an unacceptable change! The optimziation of pure functions
+can be quite critical to efficiency in some applications, and certainly
+other languages have this capability.
+
+Of course removing it from the language would merely mean we had to
+invent a new pragma for an implementation (actually GNAT already does
+that with Pure_Function, which allows a function to be declared pure
+for optimization purposes without the whole package being Pure --
+which carries so much irrelevant baggage along with it.
+
+Yes, you can worry from a theoretical point of view that 10.2.1(18)
+in conjunction with nasty stuff, e.g. calling unknown foreign
+language routines, can result in problems, but I don't think that's
+a major issue in practice.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, February 4, 2004  7:50 AM
+
+Randy Brukardt wrote:
+
+> 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...)
+
+Well of course you can do I/O, you just can't use the (somewhat dubious
+in any case) predefined Ada I/O packages. In GNAT, we provide GNAT.IO
+which is a useful simple subset of Text_IO, and the documentation in
+g-io.ads says:
+
+--  A simple text I/O package that can be used for simple I/O functions
+--  in user programs as required. This package is also preelaborated,
+--  unlike Text_IO, and can thus be with'ed by preelaborated library
+--  units.
+
+The implementation is quite straightforward, using pragma Import
+on standard C library functions.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Wednesday, February 4, 2004  8:32 AM
+
+> The problem is that once a preelaborated unit has that pragma applied, you
+> can no longer with any I/O.
+
+I do debugging/tracing output in pragma-Pure and pragma-Preelab packages
+all the time.  I have a debug package containing things like Put, and
+Put is declared ``pragma Import(Ada, Put, "Impure_Put");''.  Impure_Put
+does the dirty work -- it is not with'ed by the debug package.  The
+debug package has pragma Pure, so can be used anywhere.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, February 4, 2004  8:48 AM
+
+Pure seems wrong for that. If you have
+
+    while not EOF loop ... end loop;
+
+then the compiler can (and most likely will) pull the test for
+EOF out of the loop. It is even OK in:
+
+    put ("-----");
+    put ("-----");
+
+to eliminate the second call.
+
+It seems conceptually wrong to have an I/O package be pure, though
+of course it can be programmed and may be useful in practice. It
+seems fine for an I/O package to be preelaborable.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Wednesday, February 4, 2004  9:22 AM
+
+> It seems conceptually wrong to have an I/O package be pure, ...
+
+Yes, it is.  I do it anyway, because in some cases it's useful for
+debugging.  Of course, I have to keep in mind that the compiler can
+transform the code in various ways that might affect the actual
+printouts.
+
+>...though
+> of course it can be programmed and may be useful in practice.
+
+Interestingly, my previous message just happened to be number 666 in my
+mailbox -- maybe that's a sign of how evil that package is.  ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, February 4, 2004  9:49 PM
+
+Robert Dewar said:
+...
+> Remember that you can always do anything by doing raw import
+> rather than WITH.
+
+Of course. But the design of Pure seems to imply that if you just write
+straight Ada code, the optimizer won't do anything bad to you.
+
+> It is really nothing to get worried about that this sort of
+> thing can be done.
+>
+> Pure does NOT mean that a function is pure in the formal
+> sense, just that the compiler can make assumptions about
+> deleting identical calls, and deleting useless calls.
+
+If this is the case, then there is no need for all of the restrictions on
+Pure units. We should just make the restrictions the same as Preelaborate,
+and say user-beware. (That doesn't seem very much in keeping with the Ada
+philosophy to me, but this is a weird case.)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, February 4, 2004  10:01 PM
+
+Robert Dewar wrote:
+
+...
+> Well of course you can do I/O, you just can't use the (somewhat dubious
+> in any case) predefined Ada I/O packages. In GNAT, we provide GNAT.IO
+> which is a useful simple subset of Text_IO, and the documentation in
+> g-io.ads says:
+
+Well, I don't want to have to use implementation-defined stuff to make
+logging (which will remain in the application for its entire lifetime) work.
+That locks me into a specific compiler.
+
+If this is so easy to implement, then it seems that we should look at
+requiring some of the predefined IO to be preelaborated. Then there is no
+more problem. At least one implementer has objected to doing that, which is
+what led to the musings.
+
+Bob said:
+
+> I do debugging/tracing output in pragma-Pure and pragma-Preelab packages
+> all the time.  I have a debug package containing things like Put, and
+> Put is declared ``pragma Import(Ada, Put, "Impure_Put");''.  Impure_Put
+> does the dirty work -- it is not with'ed by the debug package.  The
+> debug package has pragma Pure, so can be used anywhere.
+
+That's also not portable (although more so); most Janus/Ada compilers
+standard mode is "no Import/Export". That allows "one button" program
+creation (no bizarre system linkers needed); everything is in the Ada
+program.
+
+Of course, we support Import/Export in "clunky program creation mode", but I
+use that only when access to actual foreign code is needed.
+
+Pragma Import should be prohibited in Pure units anyway (I realize that
+isn't going to happen, it would break too many existing kludges).
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Thursday, February 5, 2004  3:49 AM
+
+Randy replied to Robert:
+
+> > Remember that you can always do anything by doing raw import rather
+> > than WITH.
+>
+> Of course. But the design of Pure seems to imply that if you
+> just write straight Ada code, the optimizer won't do anything
+> bad to you.
+
+I agree with Randy.  You can do all sorts of nasty things with low-level
+programming and interfacing with other languages, but the rules in
+10.2.1 seem to be designed so that the načve programmer is not
+unwittingly bitten by the permission of 10.2.1(18).  It just happens
+that access types must be taken into account here.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 5, 2004  4:14 AM
+
+Randy Brukardt wrote:
+
+> If this is so easy to implement, then it seems that we should look at
+> requiring some of the predefined IO to be preelaborated. Then there is no
+> more problem. At least one implementer has objected to doing that, which is
+> what led to the musings.
+
+How about a subset of Text_IO that removes a lot of the junk (e.g. page
+marks, line counting etc), handles just strings and characters (can
+always use 'Image) and is Preelaborable.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Thursday, February 5, 2004  8:30 AM
+
+> How about a subset of Text_IO that removes a lot of the junk (e.g. page
+> marks, line counting etc), handles just strings and characters (can
+> always use 'Image) and is Preelaborable.
+
+Excellent idea.  Call it Simple_IO or something, include put for
+Integer, Float, and possibly Duration, plus Long_ and Short_ variants if
+supported by the compiler.  Hmmm.  No.  Feature creap. We could include
+the Short_ and Long_ types in the spec, and in Ada 0Y we should probably
+just bite the bullet and require that Short_Integer, Integer, and
+Long_Integer be supported along with Short_Float, Float, and Long_Float
+in standard.  (They can be renames for compilers that only support two
+(or one) type)  But that is a different AI.
+
+For Simple_IO. A better idea would be to have child generics for other
+integer, real, enumeration types, and non-Latin1 character types.  Yes
+that will require instantiation inside subprograms if you want to use
+them in pre-elaboratable units.  But I don't see that as a significant
+issue.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, February 5, 2004  7:29 PM
+
+Why burden it with all this junk. It is fine to use 'Image for numeric
+stuff, have Simple_IO just do string stuff (have a look at GNAT.IO), or
+better I will give the spec here. This has proved very useful:
+
+--  A simple preelaborable subset of Text_IO capabilities
+
+--  A simple text I/O package that can be used for simple I/O functions in
+--  user programs as required. This package is also preelaborated, unlike
+--  Text_IO, and can thus be with'ed by preelaborated library units.
+
+--  Note that Data_Error is not raised by these subprograms for bad data.
+--  If such checks are needed then the regular Text_IO package must be used.
+
+package GNAT.IO is
+pragma Preelaborate (IO);
+
+    type File_Type is limited private;
+    --  Specifies file to be used (the only possibilities are Standard_Output
+    --  and Standard_Error). There is no Create or Open facility that would
+    --  allow more general use of file names.
+
+    function Standard_Output return File_Type;
+    function Standard_Error  return File_Type;
+    --  These functions are the only way to get File_Type values
+
+    procedure Get (X : out Integer);
+    procedure Get (C : out Character);
+    procedure Get_Line (Item : out String; Last : out Natural);
+    --  These routines always read from Standard_Input
+
+    procedure Put (File : File_Type; X : Integer);
+    procedure Put (X : Integer);
+    --  Output integer to specified file, or to current output file, same
+    --  output as if Ada.Text_IO.Integer_IO had been instantiated for Integer.
+
+    procedure Put (File : File_Type; C : Character);
+    procedure Put (C : Character);
+    --  Output character to specified file, or to current output file
+
+    procedure Put (File : File_Type; S : String);
+    procedure Put (S : String);
+    --  Output string to specified file, or to current output file
+
+    procedure Put_Line (File : File_Type; S : String);
+    procedure Put_Line (S : String);
+    --  Output string followed by new line to specified file, or to
+    --  current output file.
+
+    procedure New_Line (File : File_Type; Spacing : Positive := 1);
+    procedure New_Line (Spacing : Positive := 1);
+    --  Output new line character to specified file, or to current output file
+
+    procedure Set_Output (File : File_Type);
+    --  Set current output file, default is Standard_Output if no call to
+    --  Set_Output is made.
+
+private
+    type File_Type is (Stdout, Stderr);
+    --  Stdout = Standard_Output, Stderr = Standard_Error
+
+    pragma Inline (Standard_Error);
+    pragma Inline (Standard_Output);
+
+end GNAT.IO;
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 5, 2004  6:29 PM
+
+Robert Dewar wrote, replying to me:
+
+> How about a subset of Text_IO that removes a lot of the junk (e.g. page
+> marks, line counting etc), handles just strings and characters (can
+> always use 'Image) and is Preelaborable.
+
+I have no objection to that, although it seems like a tough sell to me (why
+do we need yet another I/O library?).
+
+My preference would be to make Text_IO and Stream_IO preelaborated (because
+these have relatively simple dependence on the underlying system), leaving
+the rest alone.
+
+But I don't see that any library that allows file I/O (for logging) is going
+to easily go around the objections of existing implementers. All of our I/O
+is built on top of a single package (called System.Basic_IO), and if it is
+too hard to make that preelaborated, it seems unlikely that it would be much
+easier to implement a subset of it that is preelaborated. I believe that
+this is a common implementation (Pascal indicated that Rational's is
+organized the same way). And if you can make that preelaborated, making
+Stream_IO and Text_IO preelaborated is pretty simple.
+
+The only thing that causes trouble with making Text_IO preelaborated in
+Janus/Ada is handling Current/Standard_Input/Output. While we could dispense
+with redirection, we can hardly eliminate the concept of Standard_Output
+from Simple_IO.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Thursday, February 5, 2004  8:24 AM
+
+Randy said:
+
+> Robert Dewar wrote:
+> ...
+> > Well of course you can do I/O, you just can't use the (somewhat dubious
+> > in any case) predefined Ada I/O packages. In GNAT, we provide GNAT.IO
+> > which is a useful simple subset of Text_IO, and the documentation in
+> > g-io.ads says:
+>
+> Well, I don't want to have to use implementation-defined stuff to make
+> logging (which will remain in the application for its entire lifetime) work.
+> That locks me into a specific compiler.
+
+Agreed.
+
+> If this is so easy to implement, then it seems that we should look at
+> requiring some of the predefined IO to be preelaborated. Then there is no
+> more problem. At least one implementer has objected to doing that, which is
+> what led to the musings.
+>
+> Bob said:
+>
+> > I do debugging/tracing output in pragma-Pure and pragma-Preelab packages
+> > all the time.  I have a debug package containing things like Put, and
+> > Put is declared ``pragma Import(Ada, Put, "Impure_Put");''.  Impure_Put
+> > does the dirty work -- it is not with'ed by the debug package.  The
+> > debug package has pragma Pure, so can be used anywhere.
+>
+> That's also not portable (although more so); ...
+
+I think it *is* portable.  Convention "Ada" and the relevant pragmas are
+not optional features of the language.  You don't need any special
+linker options to get the impure part included -- just put a "with" of
+the impure version of the package somewhere in the program.
+
+By the way, although the semantics of my impure/pure cheat is somewhat
+dubious, as Robert Dewar pointed out, in practise it's no worse than
+what happens with an interactive debugger -- if the compiler has chosen
+to stir the code around, the debugger gets confused and sometimes lies.
+That's a pain, but getting a debugger to tell the truth about optimized
+code is a rather difficult trick.  Pragma-Pure-related optimizations are
+but one example.
+
+Another standard trick is to use Import(Ada) to suppress default
+initialization.  This is specified in RM-B.1(38), and mentioned in
+AARM-13.3(12.c) and B.1(38.a).
+
+>... most Janus/Ada compilers
+> standard mode is "no Import/Export".
+
+If you mean "pragma Import(Ada) is illegal in this mode, then you can
+make that the *default* mode if you like, but I don't think you can call
+it "standard". ;-)  If you're talking about extra linker options, then
+fine -- but my ugly hack needs no extra linker options.
+
+>... That allows "one button" program
+> creation (no bizarre system linkers needed); everything is in the Ada
+> program.
+>
+> Of course, we support Import/Export in "clunky program creation mode", but I
+> use that only when access to actual foreign code is needed.
+>
+> Pragma Import should be prohibited in Pure units anyway (I realize that
+> isn't going to happen, it would break too many existing kludges).
+
+Over My Dead Body.  It would break *my* kludge!  (I'm sure I'm not the
+only one who's thought of it.)
+
+Anyway, it could be useful to import a pure C function into a
+pragma-Pure package -- nothing wrong with that.  Of course, if the C
+function is impure, you might get a surprise, but that's no different
+than what happens if you get the parameter types and modes wrong.
+In general, import is a programmer-beware feature, and we should not
+place restrictions on it.  I say the same about machine code -- if your
+machine has a "cosine" instruction, there's nothing wrong with using it
+in a pragma-Pure place.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February 5, 2004  7:34 PM
+
+...
+> > Bob said:
+> >
+> > > I do debugging/tracing output in pragma-Pure and pragma-Preelab packages
+> > > all the time.  I have a debug package containing things like Put, and
+> > > Put is declared ``pragma Import(Ada, Put, "Impure_Put");''. Impure_Put
+> > > does the dirty work -- it is not with'ed by the debug package.  The
+> > > debug package has pragma Pure, so can be used anywhere.
+> >
+> > That's also not portable (although more so); ...
+>
+> I think it *is* portable.  Convention "Ada" and the relevant pragmas are
+> not optional features of the language.
+
+I agree with that. But...
+
+> You don't need any special
+> linker options to get the impure part included -- just put a "with" of
+> the impure version of the package somewhere in the program.
+
+I don't agree with this. Not the inclusion part, but the notion that it
+ought to work. You're declaring external code, and if your toolchain doesn't
+support external code, then it isn't going to work even if all of the code
+is actually in this program.
+
+Keep in mind that I'm only interested (for the purposes of this discussion)
+in what happens in an all-Ada program. Once you start bringing C and hardware
+into the equation, all bets are off anyway.
+
+...
+> Another standard trick is to use Import(Ada) to suppress default
+> initialization.  This is specified in RM-B.1(38), and mentioned in
+> AARM-13.3(12.c) and B.1(38.a).
+
+We support that, of course. I believe that there is special code to suppress
+the linker symbol in such a case - if there wasn't, the program could never
+link (because there is nothing that you are actually linking to).
+
+But note that in this case you're not really using Import at all, because the
+object still resides here, it's just not default initialized. (If you had the
+object reside somewhere else, you couldn't use the feature in an all-Ada
+program: how would you suppress default initialization at the location of
+the actual object? Well, you'd have to apply Import again, and you'd have an
+infinite regress.)
+
+> >... most Janus/Ada compilers
+> > standard mode is "no Import/Export".
+>
+> If you mean "pragma Import(Ada) is illegal in this mode, then you can
+> make that the *default* mode if you like, but I don't think you can call
+> it "standard". ;-)
+
+No. You just can't link the program; it contains external references, and
+the standard linker doesn't support external references.
+
+> If you're talking about extra linker options, then
+> fine -- but my ugly hack needs no extra linker options.
+
+No again; you have to use a different toolchain. That's the problem.
+
+Our compiler design is all-Ada top to bottom. The linker is of our own
+design, and creates a executable directly (no other programs run). This is
+the standard mode. That's not negotiable; we control the entire toolchain,
+and that's a requirement if you're staking your business on it.
+
+At a (much) later date, we added support for Import/Export. That was done
+using a special linker that outputs the entire Ada program as one giant
+system object file (complete with any Import/Export linker symbols), and
+then is given to the system linker.
+
+Now, the problem is you (Bob) are suggesting two uses for pragma Import:
+
+    * To link to code somewhere else within the Ada program; and
+    * To link to code external to the Ada program.
+
+The fact that the convention is "Ada" doesn't really change this; you still
+want to be to link to other, separate Ada (or assembler!) subsystems using
+the system linker.
+
+The problem is that there is no way to tell those apart; but they are using
+*different* linkers. The "solution" is simply to assume that you are linking
+to code external to the program (that works on internal code by accident);
+but that implies that you are using the "secondary" toolchain. And it also
+implies very substandard code (all imports call through thunks so that the
+actual external reference occurs in only one place).
+
+Even if, by some miracle, you could figure out which was which, it still
+would be impossible, because the Ada linker does not use link names. It
+simply uses address offsets, which of course change every time a change (or
+even recompile with different switches) occurs to a spec. You can't put them
+into "pragma Import" code because the only way to find out the right address
+is to with the appropriate package -- which defeats the purpose of the
+Import.
+
+The beauty of Ada is that you *don't* have to depend on unreliable
+code/tools from a whole bunch of unreliable vendors (just one unreliable Ada
+vendor!) - you can do it *all* in Ada. Now, it obvious that sometimes you
+need to access C, but (on Windows, at least) it's a lot rarer than people
+make out. (I believe that you can run any Claw GUI program and almost any
+Win32 program without any use of imported C code in the executable. Of
+course, you're using the C code that makes up the Windows kernel - AdaOS
+doesn't exist yet - but you need no Microsoft tools or code to create
+running programs.)
+
+We of course validated all of our compilers in the standard linker; we used
+the alternate chain only on C interface programs. (With the exception of
+Windows, for which the standard linker didn't exist when we validated.) I
+would be *very* upset if that did not remain true.
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent