Traits vs. Aspects in Scala 103
Scala traits provide a mixin composition mechanism that has been missing in Java. Roughly speaking, you can think of traits as analogous to Java interfaces, but with implementations.
Aspects, e.g., those written in AspectJ, are another mechanism for mixin composition in Java. How do aspects and traits compare?
Let’s look at an example trait first, then re-implement the same behavior using an AspectJ aspect, and finally compare the two approaches.
Observing with Traits
In a previous post on Scala, I gave an example of the Observer Pattern implemented using a trait. Chris Shorrock and James Iry provided improved versions in the comments. I’ll use James’ example here.
To keep things as simple as possible, let’s observe a simple Counter
, which increments an internal count variable by the number input to an add
method.
package example
class Counter {
var count = 0
def add(i: Int) = count += i
}
The count
field is actually public, but I will only write to it through add
.
Here is James’ Subject trait that implements the Observer Pattern.
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))
}
Effectively, this says that we can use any object as an Observer
as long as it matches the structural type { def receiveUpdate(subject:Any) }
. Think of structural types as anonymous interfaces. Here, a valid observer is one that has a receiveUpdate
method taking an argument of Any
type.
The rest of the trait manages a list of observers and defines a notifyObservers
method. The expression observers ::= observer
uses the List
::
(“cons”) operator to prepend an item to the list. (Note, I am using the default immutable List
, so a new copy is created everytime.)
The notifyObservers
method iterates through the observers, calling receiveUpdate
on each one. The _
that gets replaced with each observer during the iteration.
Finally, here is a specs file that exercises the code.
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 <- 1 to 3) watchedCounter.add(i)
counterObserver.updates must_== 3
watchedCounter.count must_== 6
}
}
}
The specs library is a BDD tool inspired by rspec in Rubyland.
I won’t discuss it all the specs-specific details here, but hopefully you’ll get the general idea of what it’s doing.
Inside the "observe counter increments" in {...}
, I start by declaring two classes, CounterObserver
and WatchedCounter
. CounterObserver
satisfies our required structural type, i.e., it provides a receiveUpdate
method.
WatchedCounter
subclasses Counter
and mixes in the Subject
trait. It overrides the add
method, where it calls Counter
’s add
first, then notifies the observers. No parentheses are used in the invocation of notifyObservers
because the method was not defined to take any!
Next, I create an instance of each class, add the observer to the WatchedCounter
, and make 3 calls to watchedCounter.add
.
Finally, I use the “actual must_== expected
” idiom to test the results. The observer should have seen 3 updates, while the counter should have a total of 6.
The following simple bash shell script will build and run the code.
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
Note that I put all the sources in a src/example
directory. Also, I’m using v1.3.1 of specs, as well as v2.7.1 of Scala. You should get the following output.
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
Observing with Aspects
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, e.g., object Foo {...}
become static final classes. Also, method names like +
become $plus
in byte code.
However, most Scala type, method, and variable names can be used as is in AspectJ. This is true for my example.
Here is an aspect that observes calls to Counter.add
.
package example
public aspect CounterObserver {
after(Object counter, int value):
call(void *.add(int)) && target(counter) && args(value) {
RecordedObservations.record("adding "+value);
}
}
You can read this aspect as follows, after calling Counter.add
(and keeping track of the Counter object that was called, and the value passed to the method), call the static method record
on the RecordedObservations
.
I’m using a separate Scala object RecordedObservations
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
}
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’m building the code. ;) However, it’s generally a good idea with aspects to delegate most of the work to Java or Scala code anyway.
Now, the “spec” file is:
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 <- 1 to 3) counter.add(i)
RecordedObservations.count() must_== 3
counter.count must_== 6
}
}
}
This time, I don’t need two more classes for the adding a mixin trait or defining an observer. Also, I call RecordedObservations.count
to ensure it was called 3 times.
The build script is also slightly different to add the AspectJ compilation.
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
The ajc
command not only compiles the aspect, but it “weaves” into the compiled Scala classes in the bin
directory. Actually, it only affects the Counter
class. Then it writes all the woven and unmodified class files to app.jar
, which is used to execute the test. Note that for production use, you might prefer load-time weaving.
The output is the same as before (except for the milliseconds), so I won’t show it here.
Comparing Traits with Aspects
So far, both approaches are equally viable. The traits approach obviously doesn’t require a separate language and corresponding tool set.
However, traits have one important limitation with respect to aspects. Aspects let you define pointcuts that are queries over all possible points where new behavior or modifications might be desired. These points are called join points in aspect terminology. The aspect I showed above has a simple pointcut that selects one join point, calls to the Counter.add
method.
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 modular way.
Aspect frameworks support this by providing wildcard mechanisms. I won’t go into the details here, but the *
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 Adder
to Counter.add
,
package example
class Counter {
var count = 0
@Adder def add(i: Int) = count += i
}
Then I can rewrite the aspect as follows.
package example
public aspect CounterObserver {
after(Object counter, int value):
call(@Adder void *.*(int)) && target(counter) && args(value) {
RecordedObservations.record("adding "+value);
}
}
Now, there are no type and method names in the pointcut. Any instance method on any visible type that takes one int
(or Scala Int
) argument and is annotated with Adder
will get matched.
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 load-time weaving.
Conclusion
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’t need another language. If you need more “pervasive” modifications (e.g., tracing, policy enforcement, security), consider using aspects.
Acknowledgements
Thanks to Ramnivas Laddad, whose forthcoming 2nd Edition of AspectJ in Action got me thinking about this topic.
Nice to see some mention of Scala’s mixing composition and comparison to AOP. There is also a short discussion of this subject towards the end of http://lamp.epfl.ch/~odersky/papers/ScalableComponent.pdf
I’m enjoying the posts about Scala, they seam to capture the main features that attracted me to the language.
As I see it, in regarding to interception, AOP is too powerful (and complex) and trait mixins aren’t powerful enough. I think something like Beta’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’t methods, everything is a “pattern” or something, but that is beside the point.
To keep things as simple as possible, let’s observe a simple Counter, which increments an internal count variable by the number input to an add method.
With an aspect framework like AspectJ, I also want to implement observation at all the points I care about in a modular way. I’ll surly use runtime retention policy, which will be necessary for load-time weaving.
I also want to implement observation at all the points I care about in a modular way.
I can only personally comment on this blog here. And like many have commented here, it’s very similar to some parts of US. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog. I am sure my visitors will find that very useful. I am always seeking online for articles that can help me
WatchedCounter subclasses Counter and mixes in the Subject trait. It overrides the add method, where it calls Counter’s add first, then notifies the observers.
ah ha you can have a yrt
good posing
i want you can proving it day by day
do you want to make more and more friends??
WatchedCounter subclasses Counter and mixes in the Subject trait. It overrides the add method, where it calls Counter’s add first, then notifies the observers.
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 modular way. cheap VPS Aspect frameworks support this by providing wildcard mechanisms. I won’t go into the details here, but the * 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 Adder to Counter.add,
I like the style of your website, it is beautiful, people feel very free
I am accomplishing analysis plan in the acreage of solar energy. I charge digital abstracts of all-around solar radiation of Nepal. If accessible amuse accommodate us for added analysis or informations.
Hee i just want to give u a big thank you for your fantastic railscast! I’m looking forward to the next episodes!
I am posting here just to let you know that you are doing a good job by keeping us posted about this. Please keep on posting such quality articles as this is a rare thing to find these days. I am always searching online for articles that can help me. Looking forward to another great blog. Good luck to the author! all the best!
this is a great tutorial, really
The comparison is pretty relevant, as Scala’s interesting semantics for super calls in a class that mixes in multiple traits make them a good, type-safe alternative to AOP in a lot of cases.
Unfortunately, apart from bare metal Java reflection, Scala lacks delegate support, so this means that your “advice” traits must share an “interface” with your “advised” implementations—it’s not as easy to reuse the same behaviour in multiple unrelated components the way you can with aspects.
Let’s say you want to wrap a logging aspect around your components, but you want to centralize the logging logic.
Buy the cheap North Face online in The North Face Shop for free shopping and save 50~70% OFF. north face outlet , Northface shop.
Here is very different. Thank you
How they work. could you explain more clearly.
I love your content & the way that you write.
you can think of traits as analogous to Java interfaces, but with implementations.
I won’t discuss it all the specs-specific details here, but hopefully you’ll get the general idea of what it’s doing.
We, how can we to be a good programmer, we should study alll the time, never lose our heart, keep good habit, learn from other people. that’s it.
you know, this is good, make sense, make it easy to understand.
Had a good response nearly completed, ended up being evidence studying that & acquired erased by an advertisement for Shipwreck beads. Been age ranges since i have checked throughout the following & left since the big site modifications lsat summer season built participating by means of dial-up AGONIZING. I notice everything is very similar. Sleepless & sprang around from the Etsy boards which usually don’t pick up myself tonight… Spend a while stalking about the community forums & perusing products for sale & lately offered.
very similar. Sleepless & sprang around from the Etsy boards which usually don’t pick up myself tonight… Spend a while stalking about the community forums & perusing products for sale & lately offered.
White iphone 4 Conversion Kit is now the hottest iphone 4 piece that you should get!
What an amazing content is this and surely it makes realize each and everyone who read this. Thanks for providing so fantastic and sweet suggestions ….i really appreciate it. testking 70-647|testking 642-873|testking 70-643|testking 70-648|testking 646-985|testking JN0-304
A few weeks ago when Steve Jobs held an extra press conference regarding the antenna problems with the white iPhone 4, Apple published a lot of information and a few videos that showed a similar problem with it’s competitors phones.
Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Moldsfor their worldwide customers.
like the one you mentioned here will be very useful to me! I will post a link to this page on my blog. I am sure my visitors will find that very useful.
Outsource services and solutions from oneoutsource. It provides best outsourcing services in india .
Things a lot of change right now in the education world. You don’t have to think twice if you want to continue your education. There are a lot of scholarships that you can get if yoy study hard in your high school. lottery numbers
Scala requires that you create any custom annotations as normal Java annotations.
I really like this essay. Thank you for writing it so seriously. I want to recommend it for my friends strongly. An Professional transfer that can transfer the ePub books onto your iPad on Mac and export the iPad ePub to Mac local folder.
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’t need another language.
Finally, I use the “actual must_== expected” idiom to test the results. The observer should have seen 3 updates, while the counter should have a total of 6.
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 load-time weaving.
7
8
9
Thanks for your post, very informative.
We are the professional coats manufacturer, coats supplier, coats factory, custom coats.
Buy $10 Replica Designer Sunglasses with 3-day FREE SHIPPING
Pandora UK jewellery sale online, cheaper than pandora chamilia and trollbeads
This is a good post. Thank you so much. Keep up the good works. Social Network
Outsource services and solutions from oneoutsource. It provides best outsourcing services in india
i will try it. Thanks
internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.
Your article is so informative and I like it Thanks :-)
Your article is so informative and I like it Thanks :-)
Your article is so informative and I like it Thanks :-)
Your article is so informative and I like it Thanks :-)
The Monster Beats By Dr. Dre Studio Headphones are classic shoes.You will be proud of owning them. Don’t hesitate!Take Monster Beats By Dr. Dre Pro home! Choose our Monster Beats By Dr. Dre Solo Headphones will make you have an amazing discovery.
Have the christian louboutin patent leather pumps is a happy thing. Here have the most complete kinds of christian louboutin leather platform pumps.
Online UK costume and fashion jewellery shop with,
Online UK costume and fashion jewellery shop with,
Online UK costume and fashion jewellery shop with,
Online UK costume and fashion jewellery shop with,
It’s amazing how interesting it is for me to visit you very often.
it needs a bokmark so i can come back to it later ,nice stuff
only do what you want to do
It’s a lucky day!I get one pair of women heels from http://www.aliexpress.com/fm-store/908014 ! It’s have beautiful appearance and very comfortable! Here’s your first look at the first Women’s Heels that I have ever seen. I do believe this is the first time our store has released a Women’s Heels in a high top form.
Blog posts about wedding and bridal are always rare to find , at least with great quality,you qualify for a great blog post writer title,kep the great job happening
Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Read everything you ever wanted to know about how to buy gold jewelry
e, I really enjoyed reading it and will certainly share this post with beats by dre sale cheap beats by dre
I really enjoyed reading it and will certainly share this post with my friends beats by dre sale cheap beats by dre
Both styles were seen in the World Cup worn by Eusebio da Silva Ferreira and in the Olympics worn by Lee Evans and Thomas Smith. Rudolf passed in 1974 of lung cancer, and his son ran the company. In 1989, Armin and Gerd Dassler sold Puma to Cosa Liebermann for a unknown amount. Since Puma was seen on the soccer field many years ago it’s still very popular with the players and fans. Puma offers tons of styles to pick from and with the basic look they never go out of style. Puma will be around for a very very long time.
When it comes to feather dress, what appears in your mind? Which kind brand of down jacket do you like prefer? Though there are many down jackets for you to choose from, on the word, which one you really enjoy? I want to say that canada goose coats is really your best choice. I believe you can’t agree with me any more. When you take the quality into consideration, you will find that it is superior to any other kind of coat. Besides, discount canada goose jackets is a world well-known brand, which has gained high reputation in the world, which has accepted by our customers and some organization. Because of its high quality, some of our loyal customers have promoted it to the people around them. In their opinion, it is good to informing others to know it. Recently, Canada Goose Trillium Parka is on hot sale. What I have to inform you is that all the products there are made by hand, so they are elaborative and elegant enough. It is really beautiful once you dress in. So, if you are a lovely girl or woman, go to the store to buy one for you. You will appreciate it that you have such a coat.In addition, they also have any other products like canada goose Gloves and canada goose jacket supplier.Hope your will like its!
“When the stars begin to huddle, the earth will soon become a puddle.”
http://www.oakleyshadestore.com/fake-oakley-gascan-c-29.html
Berlusconi canada goose jakke sagde ved en nyheder canada goose konference i et par dage siden, Gruppen canada goose outlet af otte topmødet udvides gradvist i de belstaff outlet næste to dage.Alt mere end mere end 30 andre belstaff ledere af nationale og internationale organisationer Canada Goose Chilliwack Parka blev opfordret til forskellige temaer afholdt dialog med lederne af gruppen af otte, involverer Canada Goose Trillium Parka spørgsmål spænder fra globale økonomiske styring, klimaændringer, handel, udvikling og fødevarer Canada Goose Solaris Parka sikkerhed i Afrika.Berlusconi sagde, l ’ Aquila topmødet forventes i år at opnå væsentlige resultater Canada Goose Handsker på en række spørgsmål.
Blog posts about wedding and bridal are always rare to find , at least with great quality,you qualify for a great blog post writer title,kep the great job happening
fuck girl vietnam please visit http://www.xxxgirl.us/2011/11/hoang-thuy-linh-paris-hilton-style-sex.html
And M550i HR tend to music taste and string very good vocal performance voices sweet thick with deep feeling singing nuanced string flavour seemed to be able to smell the violin string the flickering light of loose filled with each frequency band appeal fragrance extension is very good density are first-class More information in the best sound headphones’s official
art jordan 6 rate, breathing air jordan 2011 , but still in a deep coma jordan release dates 2011 . It is reported that these jordan 3 10 days air jordan 5 and more time,...
great stuff. thanks a lot!
Great blog. All posts have something to learn. Your work is very good and i appreciate you and hoping for some more informative posts. thank you……..
Take effect to save the file and you can retrieve them when necessary.
I appreciate this post.Thanks
I prefer Traits to Aspects. It is a good idea to make a right choice. so, make difference and it works for programming.
I like the style of your website, it is beautiful, people feel very free
Take effect to save the file and you can retrieve them when necessary.
I appreciate this post.Thanks
I really enjoyed reading it and will certainly share this post with my friends
I will be asked to do everything the best I think! Can read your blog with my own than I found too much difference! I admire you!
I love this article, it’s very well.replica Oakley Commit SQ Sunglasses
Thanks for the information, I’ll visit the site again to get update information video games
Traits vs. Aspects in Scala 87 good post53
Traits vs. Aspects in Scala 88 hoo,good article!!I like the post!88
This is a great post! Thanks.mac cosmetics saleOakley Sideways SunglassesOakley Bottlecap SunglassMAC Sheertone Blush saleReplica Oakley Commit SQ SunglassesMAC BrushOakley Commit SQ SunglassMAC Studio Finish Concealer sale
Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,
Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.
Hi, I really liked this ruby on rails example. You can’t find these things anymore. I liked it. Great job.
With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.
Laptops are increasingly becoming a must have in the world of today?
Il était certainement intéressant pour moi de lire le blog. Merci pour elle. J’aime ces sujets et tout connecté à eux. Je voudrais en savoir plus bientôt.
nice, gonna bookmark it love it all the way so far
There was a great stuff in this article I really liked it very much! Gold had save a lots of informative site. Thanks a lot for this post!
I am very happy for visiting the nice info in this blog that to utilize the great technology in this blog. I am searching for some info that to using the great services in this website.
I wanted to thank for this great read!I really enjoyed reading. One of the more impressive blogs Ive seen. Thanks so much
Espadrilles have become very popular with fashion lovers across the world. Christian Louboutin box Traditionally these shoes were made with natural material like cotton and christian louboutin ankle boot jute and were worn by farmers in Spain. They gradually became very popular Christian Louboutin men across the world because of the fact that they are very comfortable and men christian louboutin light-weight. Today, espadrilles shoes are available in all designs and wedge espadrilles are one of the most popular varieties.
Your article is so informative and I like it Thanks :-)
some truly cool information on this site , also I think the layout contains great features. very altruistic and nice :)
Intertech Machinery Inc.
With more than 25 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.
Main Products:
Injection Mold, Silicone Molding, Rubber Mold, Silicone molding, PC High-Gloss Plastic Mold, Die Casting Mold, Silicone Mold, Silicone Rubber Mold, Liquid Silicone Rubber , Cosmetic Packaging Mold, Medical Products Mold, Engineering Plastic Molds, Home Appliances Mold, etc…