Let me just comment on the basic motivation and goals of AOP. For more background I would refer people to the Aspectj.org website. You can also check aosd.net, where you will find the proceedings of more than ten workshops on AOP, and the larger goals of AOSD (aspect-oriented software development).
The basic goal has to do with separation of concerns at the design and code levels. Or, put another way, making the code look like the design. We all know how it feels to write good clean OO code. Each class represents a single tight concept, the methods within the class are similarly clear. The code is easy to understand and maintain.
We also know what it feels like to write messy, un-modular code. Things are scattered around, and its hard to change some things because they are not "in one place".
The idea behind AOP is that
-no matter how good your object (class) structure is, -in decent size programs, -there will be some design structures (concerns) that will be scattered around, -because they naturally crosscut the class structure
(The idea is actually more general than OO, but I'm giving the more specific OO form of it here.)
AOP addresses that problem by providing constructs that explicitly support crosscutting structure in code. These constructs make it possible to say in one place things that would otherwise be spread around.
There's a nice example of this in the CACM paper, the ECOOP paper, and on aspectj.org. But let me repeat it briefly here.
Suppose you have a figures package, including Point, Line and other classes. Suppose you want to update the display whenever a figure moves. In straight Java, you would add a line like this to the end of any method that moves the objects:
Display.needsRepaint();
In AspectJ, we can write this in one place as something like:
The key point being that the move declaration names "any time a figure element moves", even though the code that does that is scattered across two classes. We can say other kinds of things as well, consider for example:
This says that whenever any public method in the com.xerox package returns throwing an Error, we should log the error.
I won't say more now. But I will note that there is something new here, even though it is based on bits and pieces of old ideas. You can't implement concerns like this with this degree of locality in straight Java. (Or CLOS for that matter!)
I would very much like to see how you do this with Common Lisp macros.
Let me just comment on the basic motivation and goals of AOP. For more background I would refer people to the Aspectj.org website. You can also check aosd.net, where you will find the proceedings of more than ten workshops on AOP, and the larger goals of AOSD (aspect-oriented software development).
The basic goal has to do with separation of concerns at the design and code levels. Or, put another way, making the code look like the design. We all know how it feels to write good clean OO code. Each class represents a single tight concept, the methods within the class are similarly clear. The code is easy to understand and maintain.
We also know what it feels like to write messy, un-modular code. Things are scattered around, and its hard to change some things because they are not "in one place".
The idea behind AOP is that
-no matter how good your object (class) structure is,
-in decent size programs,
-there will be some design structures (concerns) that will be scattered around,
-because they naturally crosscut the class structure
(The idea is actually more general than OO, but I'm giving the more specific OO form of it here.)
AOP addresses that problem by providing constructs that explicitly support crosscutting structure in code. These constructs make it possible to say in one place things that would otherwise be spread around.
There's a nice example of this in the CACM paper, the ECOOP paper, and on aspectj.org. But let me repeat it briefly here.
Suppose you have a figures package, including Point, Line and other classes. Suppose you want to update the display whenever a figure moves. In straight Java, you would add a line like this to the end of any method that moves the objects:
Display.needsRepaint();
In AspectJ, we can write this in one place as something like:
aspect DisplayUpdating {
pointcut move():
call(void Point.setX(int)) ||
call(void Point.setY(int)) ||
call(void Line.setP1(Point)) ||
call(void Line.setP2(Point));
after() returning: move() {
Display.needsRepaint();
}
}
The key point being that the move declaration names "any time a figure
element moves", even though the code that does that is scattered
across two classes. We can say other kinds of things as well,
consider for example:
aspect PublicErrorLogging {
Log log = new Log();
pointcut publicCall():
call(public * com.xerox..*.*(..));
after() throwing (Error e): publicCall() {
log.write(e);
}
}
This says that whenever any public method in the com.xerox package returns throwing an Error, we should log the error.
I won't say more now. But I will note that there is something new here, even though it is based on bits and pieces of old ideas. You can't implement concerns like this with this degree of locality in straight Java. (Or CLOS for that matter!)