This post originated from an RSS feed registered with Scala Buzz
by David Bernard.
Original Post: 'Application' trait considered harmful
Feed Title: Scala Blog
Feed URL: http://www.scala-blogs.org/feeds/posts/default?alt=rss
Feed Description: In an effort to realize the "grow together" spirit, the developers of lift have teamed up with other great minds in the Scala community to bring you Scala-Blogs.org. Our mission is to strengthen the community by sharing our experiences and knowledge so that others can learn from our mistakes and triumph along with our successes.
At Scala-Blogs.org you will find tutorials and articles written by a growing host of enthusiasts, each with a different background and area of expertise.
Programmers new to Java are often confused and annoyed by the overly complex structure of a basic Java program. One line in particular, "public static void main(String[] args)" stands out as lengthy and cryptic.
class MyJavaApp { public static void main(String[] args) { // ... body ... } }
Scala, descended from Java and reusing much of Java's ecosystem, has a similar requirement, though a slightly less onerous one.
Now, Scala claims to be able to scrap Java boilerplate in many cases, and simple program construction is no exception. A very ingenious Scala programmer devised the Application trait, which allows us to further simplify the declaration of a simple program. By simply mixing in the Application trait, we can turn any object into a program.
object MyScalaApp extends Application { // ... body ... }
For pedagogy, this second approach is clearly preferable. When teaching Scala to programmers unfamiliar with Java, it's no longer necessary to go into the details of a wordy, vestigial Java pattern. When teaching programmers familiar with Java, it can serve as yet another example of how Scala can make their lives easier.
Unfortunately, the Application trait is evil.
Given the simplicity of the pattern, one would be justified in assuming that both of the Scala code snippets are functionally equivalent. This is wrong. To understand why, let's look at the entire source code for a possible implementation of the Application trait. (The actual source code is slightly more involved, but not in any way that affects this discussion.)
How does it work?, you might ask. How can it run my code without referencing it in any way? To understand how the Application trait works, it's important to understand Scala constructors.
In Scala, the body of a class also doubles as its primary constructor. Likewise, the body of a singleton object doubles as its only constructor. The Application trait works by running the entirety of the application in the constructor for MyScalaApp. This is a clever trick for reducing a bit of boilerplate code, but it turns out to be a catastrophically bad idea.
It's a bad idea for two reasons.
First, concurrency is broken. The JVM does not allow other threads to access a class during initialization. You can easily get yourself into deadlock by writing concurrent code in classes that use Application. (See Ticket #746)
Second, performance is broken. HotSpot doesn't bother to optimize class initialization. This can cause performance differences of several orders of magnitude in classes that use Application. (See this blog post and the ensuing mailing list discussion.)
While the Application trait may save you a line of code, it comes with many severe and hidden pitfalls. Hopefully it will be removed from the standard library, or at least deprecated. In the meantime, save yourself the headache and avoid Application in your applications.