A place to be (re)educated in Newspeak

Sunday, December 03, 2006

Foozle Wars

I saw this piece about Foozles on Phil Wadler’s blog. It’s been there for a while, but I missed it until now. It’s great satire, covering many, er, infirmities of our field, from Aspectitis through Theorititis.


Since Foozles are a category theoretic dual of Aspects, I might as well mention that one of the most interesting things at OOPSLA was the debate over aspects. For the record, I have never believed in AOP. Not that there aren’t real problems that the AOP community highlights; my problem is with the alleged solution.


In particular, colleagues I respect, like Mira Mezini, have told me that AOP is in large part about modularity. And yet, it’s become quite clear that AOP has serious problems with modularity. I’d encourage everyone to read Friedrich Steimann’s excellent essay on the topic.


Kevin Sullivan has done a great job of pinpointing the modularity problem with AOP, and to propose fixes. There’s fascinating work out of Harvard Business School that informs his approach. See his OOPSLA tutorial for starters.


The modularity problems with aspects are related to those with inheritance, but more severe. Let’s look at inheritance. If one simply copies a class (textually) and modifies it, the copy is independent of the original. We can change the original without considering repercussions on the validity of the copy. With inheritance, we have a linguistic mechanism that performs the derivation for us, recognizes the dependency and maintains it. The advantages are well know - changes to the original automatically propagate to the subclass, type systems understand the relationship between the two etc. And there is a benefit - the delta defined by the subclass is defined separately. The disadvantage is that we are much more restricted in what changes we can make to the original without causing breakage in subclasses.


The situation with aspects is not dissimilar. Aspects, like inheritance, are a linguistic mechanism that automatically derive a variant of the original base code, and maintains a dependency from the base code to the aspects. The aspect is also textually separated - this is what makes people think it helps modularity. If the base code changes, the aspect can still apply - as long as the changes are restricted enough; on the downside, if the base code changes something the aspect relies on, the aspect will break, and so we are limited in what we can change in the base code.


Over time, we’ve recognized what the interface between superclasses and subclasses is, made much of it explicit, and understood what limitations that places on superclasses (and superinterfaces).


For example, widely distributed interfaces cannot have methods added to them, which is a pretty harsh restriction. Incidentally, while the common wisdom is that you can add concrete methods to abstract classes,the truth is that these may conflict with subclasses and in principle should be avoided as well.


With aspects, this interface remains implicit, and without an interface, there is no modularity. The base code does not commit to any interface that the aspects can rely on; they can be undermined at any time. The problem is compounded because the coupling with the base is very tight. Resolving this requires giving up on obliviousness - the idea that the base code is unaware of the aspects. Instead, base code will have to declare itself as being an aspect-base in some way. The restrictions on its evolution in that situation are likely to be pretty limiting.


Interestingly, the cloning solution - making a copy of the original and applying the aspects changes to it - is more viable if you take the view that aspects are a reflective change to the base program. We can achieve the effect of an aspect using a suitable reflective API, that can quantify over and modify base code from the outside. Using reflection, the base code need not be edited, and the aspect remains textually separate. Unlike real aspects, no dependency is maintained between the base code and the changes to it. Our “aspects” are independent of changes to the original. Of course, we do have a maintenance problem, which may be eased by tools that track and warn about changes to the base - but do not enforce any dependency. One can even take a similar tack with respect to inheritance.


Given how onerous the restrictions on base code are likely to be if they commit to supporting aspects (or how weak the aspects will be if the commitments by base code are not onerous), I doubt modular aspects will be worth supporting at the language level; I’d put my money on reflection and tool support instead - but time will tell.

7 comments:

Yardena said...

Hi Gilad,

I am glad to read that you persue modularity topic, IMHO it is a very important one (and I hope JSR 294 does not get stuck without you).

I don't fully understand "reflective aspects", but I am very interested.

In our project we combine code generation and dynamic proxies. We generate method descriptor sub-classes based on parameter names and annotations of the original interfaces. Proxy invocation handler assembles aspect chain (security, transactions, logging etc.) and then reflectively invokes original code based on these descriptors (which are BTW also used for scripting bridge).

I wonder if this resembles somehow your suggestion, with method descriptor being the contract between base code and aspects?

Gilad Bracha said...

Hi Yardena,

Yes, I think what you are doing is related to my suggestion, but one would have to look at details to be sure.

What I had in mind was an API that allowed access to the code in a method body at run time. The API would allow queries that resemble point cuts. One could then query the code and modify it, much like an aspect. However, the API would operate on a clone of the code, to avoid dependencies on
the original code, which could be changed freely.

The approach you describe seems to require a lot of discipline and cooperation from the code originator - which is a good thing when it's possible.

PS: Are you by any chance the same Yardena who attended the Java course I gave last year in Israel?

Yardena said...

Thanks for the explanation. And yes, that's me, I am quite shocked that you remembered... :-)

Gilad Bracha said...

Shalom Yardena,

Good to hear from you. Feel free to e-mail me directly if you want to discuss the topic further.

Cheers, Gilad

Joshua Davies said...

Phil Wadler forgot:

2011: Foozles is widely accepted as an enterprise-class architecture framework. Senior IT management in most fortune 500 companies site faster time to market as their primary reason for choosing the foozles approach. Microsoft project includes a foozles plugin for its Gantt chart that estimates delivery dates occuring three days before requirements are drafted. Programmers tasked with migrating their legacy code to Foozles read the inside flap of the "white book", write off the technique as vaporware, and begin figuring out a way to write Fortran in it.

Corey Goldberg said...

Foozles are so lame.. just forget them already.

If you wanna talk Magic Mixin Markups (M^3), that's another story.. come see me at FOSD2 this year. I'll be at the Nimble Arrows booth.. perhaps you want to sign the Nimble Manifesto?


----
http://www.goldb.org

Hudsonchris said...

Comparing the issues of modularity in aspects and inheritance is very enlightening. Despite its advantages like the automatic propagations of changes and clear typing that it offers, inheritance also has some constraints. Knowing these fine points is essential for effectively resolving problems.

On a separate note, the term lightweight motorcycle trailer implies the significance of practicality vis-a-vis efficiency when addressing challenges. In much the same way as this blog post discusses complicatednesses connected with modularity, a lightweight motorcycle trailer implies how much we are supposed to weigh down our solutions.