From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6009c73a58f787a0 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-01-17 17:41:38 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!fu-berlin.de!uni-berlin.de!ppp-1-9.cvx6.telinco.NET!not-for-mail From: "Nick Roberts" Newsgroups: comp.lang.ada Subject: Re: How to avoid unreferenced objects (mutexes etc) Date: Thu, 17 Jan 2002 19:05:08 -0000 Message-ID: References: <3c3ee8c8.105408250@News.CIS.DFN.DE> <3c429d1c.2624281@News.CIS.DFN.DE> <3c45865f.2709203@News.CIS.DFN.DE> NNTP-Posting-Host: ppp-1-9.cvx6.telinco.net (212.1.156.9) X-Trace: fu-berlin.de 1011318096 32824981 212.1.156.9 (16 [25716]) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Xref: archiver1.google.com comp.lang.ada:19033 Date: 2002-01-17T19:05:08+00:00 List-Id: "Dmitry A. Kazakov" wrote in message news:3c45865f.2709203@News.CIS.DFN.DE... > Well, you can derive from the base in the private part and expose > operations you want to keep visible using wrappers implemented via > renaming in the body. This suggests a less than ideal design, under normal circumstances (I gather yours are not). It sounds like each of your steps, from the lowest levels to the highest, is too small. Each step should, ideally, be a significant conceptual 'jump'. I do know that there exceptions to this idea (I have dealt with a few), but it is a good general rule. > However, I always wished Ada having an ability to disallow primitive > operations. Like: > > type Unordered is new Integer; > function ">" (Left, Right : Unordered) is abstract; -- Disallow ">" ... an advantage, of course, of using a completely new type (rather than a derived one). > Yes, and another problem as well. Finalize is called *after* all task > components has been terminated. So when the object is being destroyed > you cannot notify tasks about that. You must use pointers to tasks if > you need a "prepare-to-die" notification. I have never actually considered this problem, in practice, for the simple reason that I have always coded explicit Startup, Reset, and Shutdown operations into the interface, at every level. I simply don't - in my own mind - include this functionality in the duties of Finalize (but that's just my opinion, of course). Of course, my designs all stem from before 1995. > >> An untagged solution requires an increasing number of > >> wrapping subroutines [thus run-time penalty]. > > > >I really don't understand why there should be a greater time penalty for > >this solution. I think possibly this is a misunderstanding that lies at the > >heart of your problems. > > Maybe the penalty is not very high, but writting dozens of wrappers is > disgusting. I suggest you must 'bite the bullet' of re-implementing operations carried up from one level to the next. Each will tend to be of the form: procedure Flash_Big_Yellow_Light (Device: access Medium_Level_Device) is begin Flash_Big_Yellow_Light(Device.Low_Level_Part); end; This (3 lines) is instead of: procedure Flash_Big_Yellow_Light (Device: access Medium_Level_Device) renames Low_Level.Lights.Yellow.Flash; (1 or 2 lines), or inheritance (0 lines). I'm saying that, although 3 or 4 lines per subprogram is a bit of a pain (and I'm familiar with interfaces that have hundreds of operations), it's usually worth the effort in terms of getting a clean separation between the levels. This 'clean separation' typically pays dividends evetually, in terms of making things easier for the client (application) software, easing maintenance of the code at each level, and especially easing the exchanging of one implementation at a certain level with another (something important to you, do I gather?). >From an efficiency point of view, heavy use of Inline is sometimes feasible. > >I don't really see generics being directly relevant to the problem here. > > You can make package implementing some interface layer generic with a > lower level package as the formal parameter. Yes, but how is this of significance to synchronisation mechanisms? Anyway, it does sound like you need a dynamic way of switching implementations (either by dispatching or using access-to-subprogram types). > [ driver example snipped ] > > The difference is that with a driver you always know the interface: > Open/Read/Write/Close. The protocols we must implement are more > complex. Additionally one should have an ability to replace any part > of the hierarchy. For instance, low level: transport [like sockets vs. > RS323], middle level: time synchronization protocol, high level client > vs. server. Of course this ideal is reachless, so I am considering a > which "local optimum" to take. (:-)) Yes, that does sound like a very unusual requirement. Best of luck! -- Best wishes, Nick Roberts