From: nickroberts@blueyonder.co.uk (Nick Roberts)
Subject: Re: Aspect-Oriented Programming
Date: Sun, 29 Sep 2002 22:56:50 GMT
Date: 2002-09-29T22:56:50+00:00 [thread overview]
Message-ID: <3d977d7e.65439093@news.cis.dfn.de> (raw)
In-Reply-To: 3D975896.CDB6CA2E@adaworks.com
On Sun, 29 Sep 2002 12:46:30 -0700, Richard Riehle <richard@adaworks.com>
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
next prev parent reply other threads:[~2002-09-29 22:56 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-09-29 19:46 Aspect-Oriented Programming Richard Riehle
2002-09-29 22:56 ` Nick Roberts [this message]
2002-09-29 23:27 ` Pat Rogers
2002-10-01 23:45 ` Richard Riehle
2002-10-03 0:11 ` Nick Roberts
2002-10-10 20:38 ` Programmer Dude
2002-10-10 21:09 ` Jim Rogers
2002-10-15 16:13 ` Programmer Dude
2002-09-30 6:02 ` Caffeine Junky
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox