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,2e26b805f6d341ba X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-09-29 15:56:42 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!pc-62-31-50-169-cr.blueyonder.co.UK!not-for-mail From: nickroberts@blueyonder.co.uk (Nick Roberts) Newsgroups: comp.lang.ada Subject: Re: Aspect-Oriented Programming Date: Sun, 29 Sep 2002 22:56:50 GMT Organization: AdaOS Message-ID: <3d977d7e.65439093@news.cis.dfn.de> References: <3D975896.CDB6CA2E@adaworks.com> NNTP-Posting-Host: pc-62-31-50-169-cr.blueyonder.co.uk (62.31.50.169) X-Trace: fu-berlin.de 1033340200 12285454 62.31.50.169 (16 [25716]) X-Newsreader: Forte Free Agent 1.21/32.243 Xref: archiver1.google.com comp.lang.ada:29422 Date: 2002-09-29T22:56:50+00:00 List-Id: On Sun, 29 Sep 2002 12:46:30 -0700, Richard Riehle strongly typed: >I was having a conversation last week with a colleague >and the topic turned to aspect-oriented programming. This >rather interesting approach to software design seems, at first, >to break encapsulation, but close inspection, offers some >powerful capabilities for reuse and corresponds to the reality >of a physical world architectures. > >As we talked, I realized that there was an opportunity to >consider the role of private child packages in the design of >aspect-oriented architectures. So I am wondering if anyone >in this forum has investigated the unique properties of Ada >that contribute to aspect-oriented software architectures. Forgive me for reposting an article I posted here in February, in a thread about refactoring, complete with brain-damage warning (which still applies). ========== [ *** WARNING: mind-numbing esoterica follows; no liability for brain damage can be accepted. *** ] If you would like me to throw in my own ideas, one fairly elaborate one occurs to me, to do with providing support for Aspect-Oriented Programming in Ada. It would work something like as follows. First, the user specifies a list A of aspects, each having a name N (which is a valid Ada name). One of these aspects is designated the default Nd. Each name would either be simple (an identifier) or compound (having a prefix). The operation is applied to a library package P, and does the following: (1) for each (N) of all the aspects in A, write a new private package specification named P.N, containing an inlined declaration for each subprogram S declared in the specification of P, each such declaration being a copy of the declaration of S but excluding out-mode parameters in the case of the default aspect, and a procedure in all other cases with the same parameters but excluding the out-mode (and return) parameters; (2) rewrite the existing body of P with the name P.Nd (but otherwise unchanged); (3) for each (N) of the other aspects in A, write a new body named P.N, which contains a null completion for each subprogram in the specification of P; (4) write a new body of P, with a completion for each subprogram in the specification of P, each such completion containing (only) a call to each member (N) of A (in the order given) in the form "P.N(parameters)" where the parameters are a repetition of the formal parameters of the subprogram, and the result of a function is held in a temporary and returned at the end, if necessary. In addition, for each member of the set formed by the closure of the ancestors of the (compound) names of A, write out an empty private package specification. An example might illuminate the idea. Suppose we have a package: with Customers; package Ice_Cream is type Cone is private; function Make return Cone; procedure Eat (Item: in out Cone; Person: in out Customers.Human); private ... private stuff end Ice_Cream; package body Ice_Cream is function Make return Cone is begin ... make a cone end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin ... eat a cone end; end Ice_Cream; Now, suppose we wished to divide this into the aspects: Debug.Before; Main; Debug.After. The refactoring would generate the following compilation units: private package Ice_Cream.Debug is end; private package Ice_Cream.Debug.Before is procedure Make; procedure Eat (Item: in out Cone; Person: in out Customers.Human); pragma Inline(Make,Eat); end Ice_Cream.Debug.Before; private package Ice_Cream.Main is function Make return Cone; procedure Eat (Item: in out Cone; Person: in out Customers.Human); pragma Inline(Make,Eat); end Ice_Cream.Main; private package body Ice_Cream.Debug.After is procedure Make; procedure Eat (Item: in out Cone; Person: in out Customers.Human); pragma Inline(Make,Eat); end Ice_Cream.Debug.After; package body Ice_Cream.Debug.Before is procedure Make is begin null; end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin null; end; end Ice_Cream.Debug.Before; package body Ice_Cream.Main is function Make return Cone is begin ... make a cone end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin ... eat a cone end; end Ice_Cream.Main; package body Ice_Cream.Debug.After is procedure Make is begin null; end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin null; end; end Ice_Cream.Debug.After; The following replacement compilation unit would be generated: package body Ice_Cream is function Make return Cone is Temp: Cone; begin Ice_Cream.Debug.Before.Make; Temp := Ice_Cream.Main.Make; Ice_Cream.Debug.After.Make; return Temp; end; procedure Eat (Item: in out Cone; Person: in out Customers.Human) is begin Ice_Cream.Debug.Before.Eat(Item,Person); Ice_Cream.Main.Eat(Item,Person); Ice_Cream.Debug.After.Eat(Item,Person); end; end Ice_Cream.Main; For any other compilation unit written, if the unit already exists, it is not replaced. Obviously, the idea is to automatically generate a skeleton that provides for the separation of the implementation of a library package into a set of different aspects. It also would be good to have operations that: added aspects to an implementation already divided; coalesced several aspects back into one; coalesced all the aspects back into one body. I'm sure that any number of similarly specialised and elaborate refactorings could be useful to some people. I'm also sure that useful manipulations would not be limited to those which preserve (external) semantics. ========== The thread got a bit sidetracked (it included some comments by Richard on a different topic). Hope you don't mind. As you get older you start repeating yourself. Never mind, as they say: as you get older you start ... um, did I just say that? -- Nick Roberts Per Ardua ad Disastra