CVS difference for ais/ai-00303.txt

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

--- ais/ai-00303.txt	2002/07/23 01:05:25	1.1
+++ ais/ai-00303.txt	2002/12/04 23:43:39	1.2
@@ -175,3 +175,449 @@
 elaborated. Might be worse mentionning though...
 
 ****************************************************************
+
+From: Robert A. Duff
+Sent: Monday, October 14, 2002  5:25 PM
+
+I was directed at the ARG meeting to write up AI-303 in a much more
+general fashion.  The AI asks about a particular case (a protected type
+with pragma Interrupt_Handler being passed as a generic actual
+parameter).  The solution proposed at the meeting was to add pragma
+No_Deeper_Instances (on a generic, meaning instantiations can't be at a
+deeper accessibility level than the generic), and a pragma
+No_Deeper_Objects (on a type, meaning objects of the type cannot be at a
+deeper accessibility level than the type).
+
+I can understand the point of No_Deeper_Instances on a generic.
+It might allow some things in generic bodies that might not otherwise be
+allowed.
+
+However, I don't understand the point of No_Deeper_Objects on a type.
+When would a programmer put this on a type?  Sure, there are some
+language-defined types that have this special property.  (Like the CPU
+timer types in AI 297.)  But why have a pragma?  Why not just say that
+these types are special?  And why not fix the generic contract model by
+saying they can't be passed to generics?  (Nor can types derived from
+them, nor types containing them as components.)  It seems like these
+types are special because they have a special relationship with the
+run-time system -- I see no general purpose here.
+
+Furthermore, what would the generic thing allow?  I thought at first
+that it would allow type extensions in generic bodies, but
+AARM-3.9.1(4.c-4.k) disabused me of that notion (something to do with
+abstract procedures).
+
+I really can't get too excited about types derived from
+interrupt-handler types, or record types with components that are
+interrupt-handler types, and passing those to generics.  Or CPU timer
+types used likewise.
+
+Someone, please remind me why pragmas No_Deeper_... are of any use to
+Ada programmers.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, October 14, 2002  8:17 PM
+
+Both of these pragmas would change the rule about
+accessibility level in the corresponding declarative
+region, and perhaps eliminate various
+run-time checks on accessibility levels.
+This should allow the use of 'access rather than
+'unchecked_access when initializing self-referencing
+components, as an example, or when passing the
+"current instance" to initializing functions, etc.
+Presumably 'access on parameters of a limited tagged
+no-deeper-objects type could also be allowed.
+
+It would also seem that no-deeper-object types might
+only be passable to no-deeper-instance generics.
+One could presumably allow the pragma on a formal type
+to indicate that the actual *could* be a no-deeper-object
+type.
+
+
+In general, I am always suspicious if we find something
+useful twice in the standard (e.g. no-deeper-object timer
+handlers and no-deeper-object interrupt handlers), but
+decide it would never be of use to a "typical" end user.
+
+That's like Java deciding it is useful to have the type
+"boolean" with special literals true and false, but concluding
+that enumeration types in general aren't useful.
+
+Also, given how many Restrictions have been defined
+that talk about no nested this and no local that, I suspect
+that in real-time and safety-critical programming, ensuring
+that all instances of a type/generic are at library level
+might be quite valuable.
+
+****************************************************************
+
+From: Alan Burns
+Sent: Tuesday, October 15, 2002  2:55 AM
+
+> Someone, please remind me why pragmas No_Deeper_... are of any use to
+> Ada programmers.
+
+In the proposal on timing objects it is necessary for these to be
+only declared at library level. I have this as a rule. Meeting felt
+that the pragma would be clearer way of doing this. In general it
+is for objects that should not disappear in an inner scope.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Tuesday, October 15, 2002  9:02 AM
+
+> Both of these pragmas would change the rule about
+> accessibility level in the corresponding declarative
+> region, and perhaps eliminate various
+> run-time checks on accessibility levels.
+> This should allow the use of 'access rather than
+> 'unchecked_access when initializing self-referencing
+> components, as an example, or when passing the
+> "current instance" to initializing functions, etc.
+> Presumably 'access on parameters of a limited tagged
+> no-deeper-objects type could also be allowed.
+
+OK, this answers at least part of my question about what rules can be
+relaxed, but it doesn't answer my more important question, which is:
+
+    Why would an Ada programmer want a type all of whose objects
+    must be declared at the same level as the type?
+
+I understand that if the programmer *did* want that, then the above
+benefits acrue (you can be sure self-referential pointers don't dangle,
+and so forth).  But where is the compelling example showing that this
+"no deeper" property was wanted in the first place?
+
+> It would also seem that no-deeper-object types might
+> only be passable to no-deeper-instance generics.
+> One could presumably allow the pragma on a formal type
+> to indicate that the actual *could* be a no-deeper-object
+> type.
+
+OK.
+
+> In general, I am always suspicious if we find something
+> useful twice in the standard (e.g. no-deeper-object timer
+> handlers and no-deeper-object interrupt handlers), but
+> decide it would never be of use to a "typical" end user.
+
+Yes, you and I share the same philosophy here.  The amount of special
+"magic" reserved to the language designer should be minimized.
+
+(I learned this very early on in my programming career.
+I wrote a program in Pascal that printed lots of error messages using
+the built-in Writeln procedure (which allows all kinds of magic, like
+different types of parameters), and then when I wanted to do some
+special processing of the error messages before printing, I found that
+it was impossible to split in a compatible Writeln-like procedure.)
+
+But the two cases we're talking about (timer objects and interrupt
+handlers) are magical anyway -- they are closely tied to the run-time
+system.  IMHO, that weakens the above philosophical argument.
+
+> That's like Java deciding it is useful to have the type
+> "boolean" with special literals true and false, but concluding
+> that enumeration types in general aren't useful.
+
+Yeah, I'll buy that analogy, although I'll bet use of Boolean is
+slightly more common in Ada than use of interrupt handlers.  ;-)
+
+> Also, given how many Restrictions have been defined
+> that talk about no nested this and no local that, I suspect
+> that in real-time and safety-critical programming, ensuring
+> that all instances of a type/generic are at library level
+> might be quite valuable.
+
+Again -- it's all built-in stuff.  I'm looking for at least one example
+of where a programmer would want the pragma in normal code (not tied to
+the implementation).
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Tuesday, October 15, 2002  9:10 AM
+
+> In the proposal on timing objects it is necessary for these to be
+> only declared at library level. I have this as a rule. Meeting felt
+> that the pragma would be clearer way of doing this.
+
+Yes, I understand that, but the timing objects are part of the language.
+They are known to the run-time system.  I'm more looking for how an Ada
+programmer (other than a compiler vendor!) would use pragmas
+No_Deeper_...
+
+>... In general it
+> is for objects that should not disappear in an inner scope.
+
+To partly answer my own question, if the programmer is putting objects
+on a global queue of some sort, making them all library level ensures
+they don't disappear while still on the queue.  (In fact this is what
+timer objects do, and I can believe that regular programmers might want
+to do the same sort of thing.)
+
+However, I find that argument rather weak.  I've written such code, and
+I use finalization to make sure objects are removed from the global data
+structure just before disappearing.  In fact, that would be the clean
+way to do timer objects.  The only reason we don't do it that way for
+timers is efficiency (and perhaps predictability of efficiency) -- we
+don't want the overhead of finalization in those kinds of real-time
+systems.
+
+So is No_Deeper really restricted to those cases where objects are
+registered with a global data structure, AND the programmer finds
+finalization to be too costly?
+
+I'm not totally *against* the idea of the No_Deeper pragma,
+but if I thought it was "really important" I might do my homework
+sooner.  ;-)
+
+I must admit that the idea of searching the RM for all the
+accessibility-level-related rules fills me with fear and loathing.  ;-)
+Note that some such rules are not clearly labeled as level-related
+(e.g., you can't do thus-and-such in a generic body).
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, October 15, 2002  9:18 AM
+
+<<I understand that if the programmer *did* want that, then the above
+benefits acrue (you can be sure self-referential pointers don't dangle,
+and so forth).  But where is the compelling example showing that this
+"no deeper" property was wanted in the first place?>>
+
+Good question! This again seems in the category of "neat clever ideas"
+which do not emanate from real application program needs.
+
+I am very suspcisious of neat and clever :-)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 15, 2002  9:51 AM
+
+It seems no surpise to me that both cases needing no_nested_objects
+relate to systems-level programming.  I do believe these
+are for systems-level/real-time/safety-critical programming.
+The pragmas (or at least the no_nested_objects one)
+could be in the systems-programming annex, as far as I am concerned.
+
+Interrupt handlers and timer handlers are "magic" relative
+to the standard Ada run-time system, but many situations require
+run-time-like code to be application specific, with "handlers"
+of various sorts that don't map directly to hardware interrupts,
+but rather application-level "software" interrupts.  I remember
+that DEC's operating systems often used the concept of software
+interrupts.
+
+Saying that the answer is finalization is probably missing the
+point for small, safety-critical systems, exactly where the
+guarantees provided by this kind of pragma would be most useful.
+
+Note also that there really isn't anything terribly magic about the
+CPU timer proposal now, since it doesn't involve a new time type.
+It is a package or two that could be written by anyone, so
+long as we give them this pragma to prevent dangling references
+(and they can figure out some approach to do the mapping from
+Ada tasks to RTOS threads).
+
+I have definitely seen handler-like things defined in Ada-based
+embedded-system application-specific  "infrastructure"
+code before.
+
+****************************************************************
+
+From: Michael F. Yoder
+Sent: Tuesday, October 15, 2002  1:10 PM
+
+>However, I don't understand the point of No_Deeper_Objects on a type.
+>When would a programmer put this on a type?
+
+If a programmer wants a global data structure that incorporates all
+instances of the type--for example, a doubly linked list, or a hash
+table. And moreover, she doesn't want to pay the price of finalization
+overhead. This rule prevents putting an instance on the stack and then
+popping the frame, or allocating from a collection that then gets popped
+from the stack.
+
+Another case is where the global data structure supports deletion only
+with difficulty. (If using a vendor-supplied package, deletion might
+even be unavailable.) The programmer decides it's better to have the
+library-level restriction than to have to support deleting the objects
+(from the global data structure) when returning from subprograms.
+
+I suppose the canonical case is where the programmer says "Yes, I could
+supply a valid Finalize subprogram, Ada being a Turing-complete language
+and all, but I really don't want to."
+
+>Sure, there are some
+>language-defined types that have this special property.  (Like the CPU
+>timer types in AI 297.)  But why have a pragma?  Why not just say that
+>these types are special?  And why not fix the generic contract model by
+>saying they can't be passed to generics?
+
+I dislike rules of the form "This is a duck. Nevertheless it is
+forbidden to walk or quack." I also strongly shun unnecessarily adding
+magical things available to implementers but not users.
+
+>  (Nor can types derived from
+>them, nor types containing them as components.)  It seems like these
+>types are special because they have a special relationship with the
+>run-time system -- I see no general purpose here.
+
+I don't think this is so. This isn't inherently special to the run-time
+system, it's rather that the run-time system happens to want to do a
+thing requiring the restriction, namely, the objects need to be tied
+together in some kind of global relation.
+
+****************************************************************
+
+From: Robert A. Duff
+Sent: Tuesday, October 15, 2002  1:59 PM
+
+> If a programmer wants a global data structure that incorporates all
+> instances of the type--for example, a doubly linked list, or a hash
+> table. And moreover, she doesn't want to pay the price of finalization
+> overhead.
+
+This reminded me that I have at least one such case in the program I'm
+currently working on.  There is a general "statistics printing" package.
+The idea is that some packages in the system want to print some
+statistics from time to time.  For example, there are various
+storage-pool packages that can print out information about how many
+bytes have been allocated and deallocated so far, the high-water mark of
+allocation, and so forth.
+
+Any such package "registers" itself by declaring (in the package body) a
+type derived from the Statistics_Object type, and overriding the Print
+primitive, and declaring one object of the type.  The Initialize
+operation of Statistics_Object links all objects into a single
+singly-linked list.  Whenever statistics are desired, one can call
+Print_Statistics, which walks down the list and calls all the Print ops.
+
+The point of all this is that the caller of Print_Statistics knows
+*when* it might be interesting to print stuff out (namely, in the main
+loop, but only if the user has requested this verbosity), but it does
+not need to know about all the packages that have some interesting
+statistics to print.
+
+There is a comment saying that you have to declare all
+Statistics_Objects at library level, or else you'll get dangling
+pointers.  And if we want to relax that restriction, we'll need to
+implement a Finalize on Statistics_Object that removes the object from
+the list.
+
+It wasn't that I wanted to avoid the overhead of Finalize.  It was just
+that I didn't want to bother implementing the "remove from list"
+operation, since it is never needed.  Note that I would need a
+doubly-linked list to implement Finalize, since this is a multi-tasking
+system.
+
+So if pragma No_Deeper_Objects existed, I could get compile-time
+checking for this abstraction, as it is, without the capability of
+nested statistics-printing objects.  This is "merely" a debug/trace kind
+of facility -- but that doesn't make it any easier to debug dangling
+pointers.
+
+Anyway, I now agree that the capability of AI-303 is useful.
+But I still claim that it's not the highest-priority thing -- after all,
+if clients obey the comment in the statistics package, all is well.
+E.g., I claim that AI-287, allowing aggregates of limited type is *far*
+more important.  (To use the same example, there are *hundreds* of cases
+where AI-287 would make my program safer, whereas there are just a few
+cases where AI-303 would do so.  We're talking about a program of around
+50,000 lines of code, expected to grow to 3 times that by the time it's
+done.)
+
+****************************************************************
+
+From: Michael F. Yoder
+Sent: Tuesday, October 15, 2002  2:30 PM
+
+I'm not terribly excited about the feature either, but I have a strong
+preference for removing a wart over adding one, and the fact there's
+some real uses too is a nice bonus. (The existing wart being the special
+rule for interrupt-handler types.) I recognize that the priority level
+of this item is entirely inherited from CPU timer types.
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, October 15, 2002  4:22 PM
+
+Actually, I am coming to the conclusion that pragma No_Deeper_Objects is
+of general use.  At first I thought it belonged in the real-time Annex,
+but I am now realizing that the pragma, in addition to its legality
+effects, eliminates a lot of run-time checking.  This can either be in
+the form of user written or compiler generated code.
+
+Let me give the example that prompted this.  I have a set of packages
+that creates a  user-extensible message type, and manages the message
+passing between tasks.  To make the  message type both user extensible
+and robust, I have to use controlled types.  There is a compiler
+generated overhead for this, plus there is a lot of code that has to
+manage objects  that may disappear at any time.  It was Bob's mention of
+doubly-linked lists that triggered the memory.  (And the problem of
+making sure that finalizing a list of messages worked.  The data
+operations had to be done in first to last order, but the object
+finalizations were last to first.  The final code looked elegant, but
+was almost impossible to understand.)
+
+Most uses of the package only declare a few specific objects, and often
+the content, if any, of the message, is an enumeration type or an access
+value.  (The real message is the destination and the return "address" of
+the sender.)  For those that need more messages or big messages I can
+provide an other (generic) package that manages a user-sized pool of
+messages with a pointer (excuse my C) to the "real" contents.  Even with
+both packages, the overall simplicity of the code should be much better.
+And using a protected type instead of a controlled type and a protected
+type to manage concurency has to be a win in performance.
+
+>E.g., I claim that AI-287, allowing aggregates of limited type is *far*
+>more important.  (To use the same example, there are *hundreds* of cases
+>where AI-287 would make my program safer, whereas there are just a few
+>cases where AI-303 would do so.  We're talking about a program of around
+>50,000 lines of code, expected to grow to 3 times that by the time it's
+>done.)
+
+See above.  I think the big win has to come during design.  And I am not
+even sure that I need the ARG to add the pragma, since it should, if
+generally useful, find its way into all compilers.  What I really need
+is for users to understand the meaning of the pragma. So maybe the
+answer is to put it in the systems programming Annex after all.  It will
+get the documentation into the RM.
+
+****************************************************************
+
+From: Ted Baker
+Sent: Wednesday, October 16, 2002  6:41 AM
+
+> ... I also strongly shun unnecessarily adding
+> magical things available to implementers but not users.
+
+Yes. I hope everyone will keep this in mind.  I've found that
+an embeddeed systems application builder ends up needing all
+the basic tools that a language implementor needs.  It seems
+to me that one of the main ways Ada 83 improves over Ada 95
+is in moving away from the "closed system" viewpoint, in
+providing a more complete set of tools for user-defined
+extension using the language.   I hope the next revision of the
+language will continue in that direction.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 16, 2002  9:45 AM
+
+>... one of the main ways Ada 83 improves over Ada 95 ...
+>                         ^^^^^^               ^^^^^^
+
+I hope that wasn't a Freudian slip!
+
+****************************************************************
+

Questions? Ask the ACAA Technical Agent