<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Object Mentor Blog: Traits vs. Aspects in Scala</title>
    <link>http://blog.objectmentor.com/articles/2008/09/27/traits-vs-aspects-in-scala</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Traits vs. Aspects in Scala</title>
      <description>&lt;p&gt;Scala &lt;em&gt;traits&lt;/em&gt; provide a mixin composition mechanism that has been missing in Java. Roughly speaking, you can think of &lt;em&gt;traits&lt;/em&gt; as analogous to Java interfaces, but with implementations.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Aspects&lt;/em&gt;, &lt;em&gt;e.g.,&lt;/em&gt; those written in &lt;a href="http://aspectj.org"&gt;AspectJ&lt;/a&gt;, are another mechanism for mixin composition in Java. How do &lt;em&gt;aspects&lt;/em&gt; and &lt;em&gt;traits&lt;/em&gt; compare?&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s look at an example trait first, then re-implement the same behavior using an AspectJ aspect, and finally compare the two approaches.&lt;/p&gt;


	&lt;h3&gt;Observing with Traits&lt;/h3&gt;


	&lt;p&gt;In a previous &lt;a href="http://blog.objectmentor.com/articles/2008/08/14/the-seductions-of-scala-part-iii-concurrent-programming"&gt;post on Scala&lt;/a&gt;, I gave an example of the &lt;em&gt;Observer Pattern&lt;/em&gt; implemented using a trait. Chris Shorrock and &lt;a href="http://james-iry.blogspot.com/"&gt;James Iry&lt;/a&gt; provided improved versions in the comments. I&amp;#8217;ll use James&amp;#8217; example here.&lt;/p&gt;


	&lt;p&gt;To keep things as simple as possible, let&amp;#8217;s observe a simple &lt;code&gt;Counter&lt;/code&gt;, which increments an internal count variable by the number input to an &lt;code&gt;add&lt;/code&gt; method.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

class Counter {
    var count = 0
    def add(i: Int) = count += i
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;The &lt;code&gt;count&lt;/code&gt; field is actually public, but I will only write to it through &lt;code&gt;add&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Here is James&amp;#8217; &lt;em&gt;Subject&lt;/em&gt; trait that implements the &lt;em&gt;Observer Pattern&lt;/em&gt;.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

trait Subject {
  type Observer = { def receiveUpdate(subject:Any) }

  private var observers = List[Observer]()
  def addObserver(observer:Observer) = observers ::= observer
  def notifyObservers = observers foreach (_.receiveUpdate(this))
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Effectively, this says that we can use any object as an &lt;code&gt;Observer&lt;/code&gt; as long as it matches the &lt;em&gt;structural type&lt;/em&gt; &lt;code&gt;{ def receiveUpdate(subject:Any) }&lt;/code&gt;. Think of structural types as anonymous interfaces. Here, a valid observer is one that has a &lt;code&gt;receiveUpdate&lt;/code&gt; method taking an argument of &lt;code&gt;Any&lt;/code&gt; type.&lt;/p&gt;


	&lt;p&gt;The rest of the trait manages a list of observers and defines a &lt;code&gt;notifyObservers&lt;/code&gt; method. The expression &lt;code&gt;observers ::= observer&lt;/code&gt; uses the &lt;code&gt;List&lt;/code&gt; &lt;code&gt;::&lt;/code&gt; (&amp;#8220;cons&amp;#8221;) operator to &lt;em&gt;prepend&lt;/em&gt; an item to the list. (Note, I am using the default immutable &lt;code&gt;List&lt;/code&gt;, so a new copy is created everytime.)&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;notifyObservers&lt;/code&gt; method iterates through the observers, calling &lt;code&gt;receiveUpdate&lt;/code&gt; on each one. The &lt;code&gt;_&lt;/code&gt; that gets replaced with each observer during the iteration.&lt;/p&gt;


	&lt;p&gt;Finally, here is a &lt;a href="http://code.google.com/p/specs"&gt;specs&lt;/a&gt; file that exercises the code.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

import org.specs._

object CounterObserverSpec extends Specification {
    "A Counter Observer" should {
        "observe counter increments" in {
            class CounterObserver {
                var updates = 0
                def receiveUpdate(subject:Any) = updates += 1
            }
            class WatchedCounter extends Counter with Subject {
                override def add(i: Int) = { 
                    super.add(i)
                    notifyObservers
                }
            }
            var watchedCounter = new WatchedCounter
            var counterObserver = new CounterObserver
            watchedCounter.addObserver(counterObserver)
            for (i &amp;lt;- 1 to 3) watchedCounter.add(i)
            counterObserver.updates must_== 3
            watchedCounter.count must_== 6
    }
  }
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;The &lt;em&gt;specs&lt;/em&gt; library is a &lt;span class="caps"&gt;BDD&lt;/span&gt; tool inspired by &lt;a href="http://rspec.info"&gt;rspec&lt;/a&gt; in Rubyland.&lt;/p&gt;


	&lt;p&gt;I won&amp;#8217;t discuss it all the specs-specific details here, but hopefully you&amp;#8217;ll get the general idea of what it&amp;#8217;s doing.&lt;/p&gt;


	&lt;p&gt;Inside the &lt;code&gt;"observe counter increments" in {...}&lt;/code&gt;, I start by declaring two classes, &lt;code&gt;CounterObserver&lt;/code&gt; and &lt;code&gt;WatchedCounter&lt;/code&gt;. &lt;code&gt;CounterObserver&lt;/code&gt; satisfies our required &lt;em&gt;structural type&lt;/em&gt;, &lt;em&gt;i.e.,&lt;/em&gt; it provides a &lt;code&gt;receiveUpdate&lt;/code&gt; method.&lt;/p&gt;


	&lt;p&gt;&lt;code&gt;WatchedCounter&lt;/code&gt; subclasses &lt;code&gt;Counter&lt;/code&gt; and mixes in the &lt;code&gt;Subject&lt;/code&gt; trait. It overrides the &lt;code&gt;add&lt;/code&gt; method, where it calls &lt;code&gt;Counter&lt;/code&gt;&amp;#8217;s &lt;code&gt;add&lt;/code&gt; first, then notifies the observers. No parentheses are used in the invocation of &lt;code&gt;notifyObservers&lt;/code&gt; because the method was not defined to take any!&lt;/p&gt;


	&lt;p&gt;Next, I create an instance of each class, add the observer to the &lt;code&gt;WatchedCounter&lt;/code&gt;, and make 3 calls to &lt;code&gt;watchedCounter.add&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Finally, I use the &amp;#8220;&lt;code&gt;actual must_== expected&lt;/code&gt;&amp;#8221; idiom to test the results. The observer should have seen 3 updates, while the counter should have a total of 6.&lt;/p&gt;


	&lt;p&gt;The following simple bash shell script will build and run the code.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
SCALA_HOME=...
SCALA_SPECS_HOME=...
CP=$SCALA_HOME/lib/scala-library.jar:$SCALA_SPECS_HOME/specs-1.3.1.jar:bin
rm -rf bin
mkdir -p bin
scalac -d bin -cp $CP src/example/*.scala
scala -cp $CP example/CounterObserverSpec
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Note that I put all the sources in a &lt;code&gt;src/example&lt;/code&gt; directory. Also, I&amp;#8217;m using v1.3.1 of &lt;em&gt;specs&lt;/em&gt;, as well as v2.7.1 of Scala. You should get the following output.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
Specification "CounterObserverSpec" 
  A Counter Observer should
  + observe counter increments

Total for specification "CounterObserverSpec":
Finished in 0 second, 60 ms
1 example, 2 assertions, 0 failure, 0 error
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;Observing with Aspects&lt;/h3&gt;


	&lt;p&gt;Because Scala compiles to Java byte code, I can use AspectJ to advice Scala code! For this to work, you have to be aware of how Scala represents its concepts in byte code. For example, object declarations, &lt;em&gt;e.g.,&lt;/em&gt; &lt;code&gt;object Foo {...}&lt;/code&gt; become static final classes. Also, method names like &lt;code&gt;+&lt;/code&gt; become &lt;code&gt;$plus&lt;/code&gt; in byte code.&lt;/p&gt;


	&lt;p&gt;However, most Scala type, method, and variable names can be used as is in AspectJ. This is true for my example.&lt;/p&gt;


	&lt;p&gt;Here is an aspect that observes calls to &lt;code&gt;Counter.add&lt;/code&gt;.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

public aspect CounterObserver {
    after(Object counter, int value): 
        call(void *.add(int)) &amp;#38;&amp;#38; target(counter) &amp;#38;&amp;#38; args(value) {

        RecordedObservations.record("adding "+value);
    }
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;You can read this aspect as follows, &lt;em&gt;after calling &lt;code&gt;Counter.add&lt;/code&gt; (and keeping track of the Counter object that was called, and the value passed to the method), call the static method &lt;code&gt;record&lt;/code&gt; on the &lt;code&gt;RecordedObservations&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m using a separate Scala object &lt;code&gt;RecordedObservations&lt;/code&gt;&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

object RecordedObservations {
    private var messages = List[String]()
    def record(message: String):Unit = messages ::= message
    def count() = messages.length
    def reset():Unit = messages = Nil
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Recall that this is effectively a static final Java class. I need this separate object, rather than keeping information in the aspect itself, because of the simple-minded way I&amp;#8217;m building the code. ;) However, it&amp;#8217;s generally a good idea with aspects to delegate most of the work to Java or Scala code anyway.&lt;/p&gt;


	&lt;p&gt;Now, the &amp;#8220;spec&amp;#8221; file is:&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

import org.specs._

object CounterObserverSpec extends Specification {
    "A Counter Observer" should {
        "observe counter increments" in {
            RecordedObservations.reset()
            var counter = new Counter
            for (i &amp;lt;- 1 to 3) counter.add(i)
            RecordedObservations.count() must_== 3
            counter.count must_== 6
    }
  }
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;This time, I don&amp;#8217;t need two more classes for the adding a mixin trait or defining an observer. Also, I call &lt;code&gt;RecordedObservations.count&lt;/code&gt; to ensure it was called 3 times.&lt;/p&gt;


	&lt;p&gt;The build script is also slightly different to add the AspectJ compilation.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
SCALA_HOME=...
SCALA_SPECS_HOME=...
ASPECTJ_HOME=...
CP=$SCALA_HOME/lib/scala-library.jar:$SCALA_SPECS_HOME/specs-1.3.1.jar:$ASPECTJ_HOME/lib/aspectjrt.jar:bin
rm -rf bin app.jar
mkdir -p bin
scalac -d bin -cp $CP src/example/*.scala 
ajc -1.5 -outjar app.jar -cp $CP -inpath bin src/example/CounterObserver.aj
aj -cp $ASPECTJ_HOME/lib/aspectjweaver.jar:app.jar:$CP example.CounterObserverSpec
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;The &lt;code&gt;ajc&lt;/code&gt; command not only compiles the aspect, but it &amp;#8220;weaves&amp;#8221; into the compiled Scala classes in the &lt;code&gt;bin&lt;/code&gt; directory. Actually, it only affects the &lt;code&gt;Counter&lt;/code&gt; class. Then it writes all the woven and unmodified class files to &lt;code&gt;app.jar&lt;/code&gt;, which is used to execute the test. Note that for production use, you might prefer &lt;a href="http://www.eclipse.org/aspectj/doc/released/devguide/ltw.html"&gt;load-time weaving&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The output is the same as before (except for the milliseconds), so I won&amp;#8217;t show it here.&lt;/p&gt;


	&lt;h3&gt;Comparing Traits with Aspects&lt;/h3&gt;


	&lt;p&gt;So far, both approaches are equally viable. The traits approach obviously doesn&amp;#8217;t require a separate language and corresponding tool set.&lt;/p&gt;


	&lt;p&gt;However, traits have one important limitation with respect to aspects. Aspects let you define &lt;em&gt;pointcuts&lt;/em&gt; that are queries over all possible points where new behavior or modifications might be desired. These points are called &lt;em&gt;join points&lt;/em&gt; in aspect terminology. The aspect I showed above has a simple pointcut that selects one join point, calls to the &lt;code&gt;Counter.add&lt;/code&gt; method.&lt;/p&gt;


	&lt;p&gt;However, what if I wanted to observe all state changes in all classes in a package? Defining traits for each case would be tedious and error prone, since it would be easy to overlook some cases. With an aspect framework like AspectJ, I can implement observation at all the points I care about in a &lt;em&gt;modular&lt;/em&gt; way.&lt;/p&gt;


	&lt;p&gt;Aspect frameworks support this by providing wildcard mechanisms. I won&amp;#8217;t go into the details here, but the &lt;code&gt;*&lt;/code&gt; in the previous aspect is an example, matching any type. Also, one of the most powerful techniques for writing robust aspects is to use pointcuts that reference only annotations, a form of abstraction. As a final example, if I add an annotation &lt;code&gt;Adder&lt;/code&gt; to &lt;code&gt;Counter.add&lt;/code&gt;,&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

class Counter {
    var count = 0
    @Adder def add(i: Int) = count += i
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Then I can rewrite the aspect as follows.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
package example

public aspect CounterObserver {
    after(Object counter, int value): 
        call(@Adder void *.*(int)) &amp;#38;&amp;#38; target(counter) &amp;#38;&amp;#38; args(value) {

        RecordedObservations.record("adding "+value);
    }
}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now, there are no type and method names in the pointcut. Any instance method on any visible type that takes one &lt;code&gt;int&lt;/code&gt; (or Scala &lt;code&gt;Int&lt;/code&gt;) argument and is annotated with &lt;code&gt;Adder&lt;/code&gt; will get matched.&lt;/p&gt;


	&lt;p&gt;Note: Scala requires that you create any custom annotations as normal Java annotations. Also, if you intend to use them with Aspects, use runtime retention policy, which will be necessary if you use &lt;a href="http://www.eclipse.org/aspectj/doc/released/devguide/ltw.html"&gt;load-time weaving&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;Conclusion&lt;/h3&gt;


	&lt;p&gt;If you need to mix in behavior in a specific, relatively-localized set of classes, Scala traits are probably all you need and you don&amp;#8217;t need another language. If you need more &amp;#8220;pervasive&amp;#8221; modifications (&lt;em&gt;e.g.,&lt;/em&gt; tracing, policy enforcement, security), consider using aspects.&lt;/p&gt;


	&lt;h4&gt;Acknowledgements&lt;/h4&gt;


	&lt;p&gt;Thanks to Ramnivas Laddad, whose forthcoming 2&lt;sup&gt;nd&lt;/sup&gt; Edition of &lt;cite&gt;AspectJ in Action&lt;/cite&gt; got me thinking about this topic.&lt;/p&gt;</description>
      <pubDate>Sat, 27 Sep 2008 22:33:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:8628eb5f-f195-4ebe-a10a-f3ee9d66d591</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/09/27/traits-vs-aspects-in-scala</link>
      <category>Dean's Deprecations</category>
      <category>Design Principles</category>
      <category>Clean Code</category>
      <category>Scala</category>
      <category>aspects</category>
      <category>AspectJ</category>
      <category>mixins</category>
    </item>
    <item>
      <title>"Traits vs. Aspects in Scala" by annie2278</title>
      <description>&lt;p&gt;To keep things as simple as possible, let&#8217;s observe a simple Counter, which increments an internal count variable by the number input to an add  method.&lt;/p&gt;</description>
      <pubDate>Wed, 10 Mar 2010 03:41:29 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:a01f7131-8e03-4b3c-a0d9-81a53244b699</guid>
      <link>http://blog.objectmentor.com/articles/2008/09/27/traits-vs-aspects-in-scala#comment-7842</link>
    </item>
    <item>
      <title>"Traits vs. Aspects in Scala" by Rafael de F. Ferreira</title>
      <description>&lt;p&gt;I&amp;#8217;m enjoying the posts about Scala, they seam to capture the main features that attracted me to the language.&lt;/p&gt;


	&lt;p&gt;As I see it, in regarding to interception, AOP is too powerful (and complex) and trait mixins aren&amp;#8217;t powerful enough. I think something like Beta&amp;#8217;s notion of having methods derive from other methods would be a promising middle-of-the-road solution for the problem of interception. Actually in Beta there aren&amp;#8217;t methods, everything is a &amp;#8220;pattern&amp;#8221; or something,  but that is beside the point.&lt;/p&gt;</description>
      <pubDate>Sun, 05 Oct 2008 04:45:50 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:adb1c464-3362-479d-b512-8ecfa7478066</guid>
      <link>http://blog.objectmentor.com/articles/2008/09/27/traits-vs-aspects-in-scala#comment-2114</link>
    </item>
    <item>
      <title>"Traits vs. Aspects in Scala" by michi</title>
      <description>&lt;p&gt;Nice to see some mention of Scala&amp;#8217;s mixing composition and comparison to AOP. There is also a short discussion of this subject towards the end of &lt;a href="http://lamp.epfl.ch/~odersky/papers/ScalableComponent.pdf" rel="nofollow"&gt;http://lamp.epfl.ch/~odersky/papers/ScalableComponent.pdf&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 28 Sep 2008 15:32:37 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:40fd9807-5533-4a89-afa4-f92b0ab4584c</guid>
      <link>http://blog.objectmentor.com/articles/2008/09/27/traits-vs-aspects-in-scala#comment-2097</link>
    </item>
  </channel>
</rss>
