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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,fd96375b28b3103b X-Google-Attributes: gid103376,public X-Google-Thread: 1108a1,fd96375b28b3103b X-Google-Attributes: gid1108a1,public From: eachus@spectre.mitre.org (Robert I. Eachus) Subject: Re: "Classes" as packages in Ada Date: 1998/11/25 Message-ID: #1/1 X-Deja-AN: 415706425 References: <73f0p1$4iu8$1@prime.imagin.net> <1103_911962898@DZOG-CHEN> <3UU62.124$8X3.638914@news.rdc1.az.home.com> Organization: The Mitre Corp., Bedford, MA. Newsgroups: comp.lang.ada,comp.object Date: 1998-11-25T00:00:00+00:00 List-Id: In article <3UU62.124$8X3.638914@news.rdc1.az.home.com> "John Goodsen" writes: > So my conclusion is that Ada code for an interface is not even > close in simplicity (from the programmer's point of view) as > something like... About all I can say, is you are right, and you are wrong. As Ed pointed out, most of what requires interfaces in other languages is done with generic mix-ins in Ada 95. I'd say you were comparing apples and oranges, but it is more like comparing Waldorf salad and apples. I have a package (actually family of packages) that is simple to use for event notification which not only allows for all the bells and whistles Ed showed, but a few more besides. (You can have multiple delivery methods for the same class of messages, it is closely integrated with Ada tasking, etc., etc.) But if I wanted to simply implement the Ada equivalent to John's classes, I'd probably use an Ada protected object. (Note to Ada 95 programmers, this is a perfect case for using requeue to insure that each observer is notified once for each event.) protected type Observed_Object is procedure Set(Observed: in Object); function Value return Object; entry Modified(Observed: out Object); private entry Waiting(Observed: out Object); Current: Object; Reporting: Boolean := False; end Observed_Object; protected body Observed_Object is procedure Set (Observed: in Object) is begin Current := Observed; Reporting := True; end Set; function Value return Object is begin return Current; end Value; entry Modiified(Observed: out Object) when not Reporting is begin requeue Waiting; end; entry Waiting(Observed: out Object) when Reporting is begin Observed := Current; if Waiting'Count = 0 then Reporting := False; end if; end; end Observed_Object; Now I probably could spend pages describing why I made certain choices in this version, and how to modify it to deal with other cases, but I'll refrain. (Knowing the list though, I'm sure there will be a dozen variations posted by Monday ;-) Some other possibilities include a class of events, allowing callers to wait for more than one event, using access types to allow the object value to be limited, etc. I'll just say that this implementation deals naturally with concurrency, the protected declaration is of a size with John's interface, and the implementation is almost trivial. For those that don't know Ada too well, and this is a new and not to well explored corner of Ada 95, here is how it works. A thread wanting to be notified of the next event calls Modified usually in a loop: while Something loop Some_Object.Modified(Value); Do_Something_with(Value; end loop; If the protected object is not currently reporting to queued callers, the call is immediately requeued on Waiting. When someone modifies the current value, Reporting is set to true, all the tasks currently waiting on Waiting are given the new value to do with as they will, then any tasks that have already called Modified get moved to Waiting. -- Robert I. Eachus with Standard_Disclaimer; use Standard_Disclaimer; function Message (Text: in Clever_Ideas) return Better_Ideas is...