Monday, November 23, 2009

AspectJ and Scala

What is the "atom" of software? If you consider an atom to be the smallest thing with which you can work, while continuing to do chemistry, then what's the software analogue?

My first thought was that an atom is a file. I can jar them up to make molecules, and string peptides of them together to make OSGi bundles. At some point the inorganic chemistry of programming becomes the protein-rich biochemistry of software engineering.

Or maybe an atom is the largest thing that, in isolation, can't possibly have a bug in it. Something like an instruction. Or maybe even a fully unit-tested class or method.

But, the history of the atom allows our analogy to grow richer, and weirder. Originally, atoms were a computational aid. They were discovered as a way to predict the outcomes of macroscopic chemical reactions. Even up until around 1905, there were still a handful of practicing chemists who didn't believe in atoms, except as a calculational tool.

But real they are, regardless of the intended meanings of the symbols chemists use to denote them. So, atoms feel more like aspects to me. Always there lurking in a program’s behavior, even if not represented using aspect syntax in the source code.

If I have a class implementing the public API of some library, then I log all the incoming calls. That logging is an aspect, even though I might have duplicated those slf4j calls in a dozen places. If I have code that takes care to release resources after I've acquired and used them, then that's another aspect. And if I've forgotten the finally clause somewhere, then that bug is a contaminant in the reactants, which makes my program behave differently than my chemistry equations would predict.

The trouble with hand-implemented aspects like repetitive logging calls or finally clauses -- even when you remember all of them -- goes beyond the biz logic pollution that they impose. All that duplicated code permits inconsistencies. For example, the log message in this method here looks a little different than the one over there.

And that's a bug escape. Because the log scraper that customer support is using, which you didn't even know about, is going to malfunction on that logging call that's only half a bubble off plumb.

It's a bit like isotopes of atoms. Not all carbon atoms are alike. You used a carbon-12 here, but whoops you used carbon-14 over there. And we know that one can decay on you. You used mostly protium, but here's a deuterium, so the heavy water that you made from it has measurably different physical properties (like boiling point), even though the chemical properties are the same.

Keeping with the analogy, hand-implemented aspects take you out of ordinary chemistry and force you to worry about nuclear and physical effects. It would be better to elevate aspects in the code to natively supported compiler constructs, like classes, so everybody is using the same isotopes.

That's why using AspectJ and Scala together tops my list of exciting things to do. I think of AspectJ as an external DSL that allows me to define pointcuts into my Scala code. Pretty much all my code, including the advice, continues to be written in Scala itself. The real virtue of AspectJ lies in the weaving.

And for some elegant work on internal DSL alternatives, refer to the paper by Daniel Spiewak and Tian Zhao about an AOP implementation in Scala.

So, rather than worrying about polluting my biz logic with code that better belongs in aspects, I'm now on guard against letting my biz logic leak into my aspects. And this is a much happier place to be.

Come to think of it, the false promise of object oriented programming was to offer reuse. This never really happened because classes are the wrong size to be reusable. Too small to be independently deployable, and too large to exclude application-specific implementation details. Instead, OO 's importance comes from the organizing principles it champions. But I wonder if aspects, devoid of custom biz logic, might take us closer to reusable software. Components and libraries are reusable in the large. But might some group (or period) of little aspect atoms be reusable in the small?