By the way, I speak on Scala Days 2011 in the same subject . The basic idea is the same as the example of Kim and Dean. However, when it comes to the full range of cross-cutting issues, similarities and differences become more nuanced.
At one end of the spectrum there are no truly cross-cutting issues, such as caching. When the host language does not support higher-order functions (such as Java), implementing the problem as an aspect becomes attractive. For example, using the AspectJ method and annotation you can say:
@Cacheable(keyScript="#account.id") public double getNetWorth(Account account) { ... expensive computation }
But with a higher order function in Scala, you can do:
def getNetWorth(account: Account) : Double = { cacheable(keyScript=account.id) { ... expensive computation } }
Scala's approach is much better because:
- Caching is unlikely to be widely used. For example, it is unlikely that an entire method in a class or all public methods in all classes in a package can be cached. And even if there is such a situation,
keyScript
unlikely to be the same or easily expressed in general form. - The AspectJ approach uses annotation as a crutch to offer a decent implementation. With a higher order function in Scala, intent is expressed directly.
- To calculate the AspectJ key, you must use an external language (for example, OGNL or Spring Expression Language). With Scala, you can simply use the host language.
In the middle, there are common problems related to transaction management and security. At first glance, they look like caching. However, in practice, we see that applying this functionality to all methods of a class (with a common subselect, for example, open access) or all methods of all classes marked with an annotation (for example, @Service
) is common. If so, then the AspectJ approach becomes excellent because it provides a way to apply functionality at a higher level than higher order functions. You no longer need to surround each method with transactional {}
or secured {}
when class-level annotation is fine. In terms of security, the AspectJ approach simplifies security auditing.
At the other end of the spectrum , cross-cutting issues such as tracing, profiling, monitoring, political execution, auditing, some forms of concurrency management (for example, Swing / SWT / Android UI thread dispatching), etc. are considered. This is very well suited for selecting a pointcut (with and often without annotations). It is very difficult to do the same in a consistent way, using only higher-order functions.
There are more semantic nuances, but the bottom line is that when you find annotation of each method to use a cross approach, a higher order function is likely to be a better approach. For others, using Scala with AspectJ is likely to provide a consistent and compact solution.
ps I have not tried AspectJ + Scala in Eclipse recently (since Scala in Eclipse only started working recently). But the external build using Maven worked fine after http://lampsvn.epfl.ch/trac/scala/ticket/4214 has been fixed.