Thursday, December 27, 2012

Scalable Component Abstractions

The German computer scientist Martin Odersky is world-famous for his work in programming language theory.

Recently, he has become particularly famous for the invention of the programming language Scala.

At this point, Scala has matured significantly; there is a lot of documentation, and plenty of books, examples, etc.

But for the underlying theory behind Scala, it is valuable to go back to some of Odersky's original papers, including this one by Odersky and Zenger in 2005: Scalable Component Abstractions.

We identify three programming language abstractions for the construction of re-usable components: abstract type members, explicit selftypes and symmetric mixin composition. Together, these abstractions enable us to transform an arbitrary assembly of static program parts with hard references between them into a system of re-usable components.

Designing a programming language that successfully provides for reusable components is one of the holy grails of computing; theorists have been working on this for decades, slowly making progress. Reusable components, if implemented well, enable large teams of people to work together on the construction of large systems.

Scalable Component Abstractions describes the theoretical underpinnings of Scala's approach to componentization. Papers in programming language theory can often be dense and abstract, but Scalable Component Abstractions is clearly written with well-chosen examples.

More importantly, after developing the theory of abstract type members, explicit selftypes and symmetric mixin composition, they demonstrate how these tools were successfully used in a real system; for example, they modify the existing Scala compiler to add trace-logging functionality:

The crucial point is that we want to extend an existing compiler with logging functionality. To do this, we do not want to modify the compiler’s source code. Neither do we want to require of the compiler writer to have pre-planned the logging extension by providing hooks. Such hooks tend to impair the clarity of the code since they mix separate concerns in one class. Instead, we use subclassing to add logging functionality to existing classes.

As they observe, it is interesting to compare this to one of the major alternate techniques for solving this problem, Aspect-Oriented Programming:

our architecture can handle all before, after, and around advice on method reception pointcut designators. These represent only one instance of the pointcut designators provided by languages such as AspectJ. Therefore,general AOP is clearly more powerful than our scheme. On the other hand, our scheme has the advantage that it is statically typed, and that scope and order of advice can be precisely controlled using the semantics of mixin composition.

I've tried AOP a few times, and while it works, I've found it awkward to deploy, and rather fragile. So I'd be willing to give up some of its power in return for a simpler, more transparent, and more reliable solution.

I haven't yet done any serious programming in Scala, but I've been following the language's development for several years now, and it's becoming increasingly common to see major systems implemented in Scala (for example, the Twitter team use Scala extensively, as I mentioned earlier this week), so I suspect it won't be too long before I find myself working on projects where Scala is a significant part of the solution.

If you haven't been paying attention to Scala, you might find it interesting to explore; I think it's powerful and well-designed, and has a bright future ahead.

No comments:

Post a Comment