In my job I get to look at lots of Ada, written in many styles across a variety of large programs. Despite this diversity, I have noticed the following common pattern that is consistently implemented using a risky Ada construct. Please excuse this rather long email; but I'm hoping this prestigious group can offer some enlightening comments. The common pattern is "publish and subscribe", which is not surprising in the event-driven systems that I see. Typically, there is a package whose job it is to maintain some state with respect to some sequence of incoming events. Other parts of the application that need to know about the state-changes can "subscribe" to the event handler; when a state-change occurs, the handler will "publish" the fact to all the current subscribers. The normal implementation of this is to encapsulate the code that needs to know about the state-changes into a "callback" procedure, and then subscribe to the event handler by giving it a pointer to that procedure. The event handler adds the pointer to a list, and later publishes events by calling each procedure on the list. So far, so good. In fact, this implementation matches those described in public literature (in Ada books as well as books about patterns), and even the Ada95 Rationale advocates such an approach. However, large real-world systems are not as static as this: they usually include requirements for dynamic reconfiguration. The "publish and subscribe" pattern can support this quite well: all that is needed is capability to edit the callback list. The "subscribe" operation -adds- to the list; and an "unsubscribe" operation can be provided to -remove- from the list. For generality, we can even provide a boolean query such as "is_subscribed" to assure, for example, that a subscriber doesn't add itself more than once. These latter two operations are -not- described anywhere that I have seen -- but the implementation is intuitive enough: simply traverse the list looking for a matching pointer, and if found, act accordingly. But that's where the risky Ada construct comes in: Ada95 does not guarantee comparisons of subprogram 'Access values. As explained in [RM 3.10.2(39)], [RM 4.5.2(13)], and other places, a compiler "implementation may consider two access-to-subprogram values to be unequal, even though they designate the same subprogram. This might be because one points directly to the subprogram, while the other points to a special prologue that performs an Elaboration_Check and then jumps to the subprogram." Thus, each 'Access attribute reference for a given subprogram is allowed to designate a distinct wrapper if needed, to support an indirect call. So: given this context, please comment on the following, preferably -not- at the level of detail I'm providing. What I'm looking for is overall conceptual insights: forest-level wisdom derived from the tree-level observations I'm describing. 1) Alternative Implementations ------------------------------ Invariably, when I point out the above issue to developers, they react with surprise. It is not common knowledge that Ada95 lacks this guarantee, and the bugs it can manifest are elusive, since dynamic reconfiguration is typically a massive operation (akin to startup) with a combinatorial explosion that consequently sees little testing. So it's quite disappointing that the above straightforward implementation cannot be retained; yet all the alternatives I've seen are more complex and/or cumbersome. Some examples include: a) single 'Access: The "proper" thing to do is a technical tweak, as described at <http://www.adaic.org/docs/95style/html/sec_7/7-3-2.html> Define a single 'Access constant along with each callback subprogram declaration, and use that constant for all references. This isn't a bad solution, but it presumes the subscribers know how the publisher is implemented (or will evolve). Maybe such a rule should be added to program coding standards -- as a cliche. b) use 'Address: The System.Address of the callback could be used instead of its 'Access value. This would require a system service for performing the call (usually provided by the OS), but it defeats the type checking that 'Access enjoys. And besides, it's not clear that 'Address has any more guarantee for matching than 'Access does. c) subscriber id: This approach assigns a unique identifier to each subscriber and uses that instead of the 'Access value for matching in the callback list. This adds complexity and maintenance concerns, and resists the introduction of a new subscriber into the system -- although I've heard it argued that that is a -good- thing: only "authorized" subscribers will be able to subscribe, by virtue of having been assigned an id. d) sockets: A variation of this is that every possible subscriber is allocated a "socket" and the socket table replaces the callback list: no search (involving a match) is needed, since each subscriber has its own socket. The table is statically maximal, the equivalent of every subscriber having been added at system startup. Dynamic reconfiguration is achieved via a boolean flag in each socket, indicating whether a given subscriber participates in the current configuration (ie, whether or not the event handler should call that subscriber's callback). This may be efficient but can consume a great deal of memory, much of it wasted on non-configured subscribers. e) dispatching: This is a more sophisticated approach, wherein the callbacks are mediated via tagged type dispatching rather than by 'Access subprogram values. ...and there are certainly other designs. But the point I'm making is that there seems to be no equivalent for the simplicity of the original implementation, which alas, Ada95 precludes. And worse, we are misled by the public literature, which encourages us to -expect- that the original implementation is advised. 2) Language Revision -------------------- This issue naturally leads to the question: can the next language revision for Ada provide the missing guarantee, assuring a match in comparisons of subprogram access values that designate the same subprogram? C. Daniel Cooper ==========v=======================. Adv Computing Technologist | All opinions are mine | 206-655-3519 | and may not represent | [log in to unmask] | those of my employer. | ---------------------------^-----------------------< The question is not "What is the answer?"; rather, | the question is "What is the question?" --Poincare | ==================================================='