Tilting at windmills

Duncan Mac-Vicar P.'s blog

A better Java: Scala or Xtend?

32 Comments

I have been playing with two languages recently: Scala and Xtend.

Xtend and Scala have some similarities, but don’t let this make you think they are that similar. Both are JVM based languages offering a refresh over Java, but the itch they focus on is different and the culture behind them is even more different.

Xtend focuses on fixing Java so that it is good enough to do the stuff you are already doing with Java without so much pain. It is like bringing Java to the state where C# is, which is something Sun and Oracle haven’t been able to do. Xtend compiles to Java source code, not bytecode. If you use it on eclipse, you will see a xtend-gen folder with the generated code, which is then in turn compiled to bytecode. Everything is transparent to the developer. Xtend is built on top of Xtext, a framework to write Domain Specific Languages and get Java/IDE support for free (example: a Cucumber-like DSL)

Scala is also a “better Java”, but it focuses more on providing a “Scalable Language”. A language that can be used on different paradigms or as Domain Specific Languages (eg. the Play! web framework features type-safe HTML templates thanks to Scala). It mixes heavily the object oriented paradigm with functional programming. The functional aspect of Scala aims to provide support to designing concurrent programs easily. This goes beyond simple lambdas and the philosophy aims of immutable objects and expressions over statements, immutable collections and actors in the library.

For developers just looking for a refresh, both provide:

Optional Semicolons

Yes. No need to write them in most cases.

val and var

In Scala:

val someVariable : String = "This will not change"
var someVariable : String = "This can change later"

In Xtend:

val String someVariable = "This will not change"
var String someVariable = "This can change later"

While “val” is not different from “final”, I really like this syntax. In scala it is heavily used to make your brain always think if you really need
to change a variable later. You soon realize that you don’t, and most variables are calculations that need to be initialized once.

Type inference

In the example above, you don’t need to specify the types. They will be infered:

val someVariable = "This will not change"
var someVariable = "This can change later"

You want to specify it for some field members that will not be initialized. Or if you assign a concrete class (e.g. HashMap) but wan’t the variable to be a Map.

Scala also has a nice feature, called “lazy val”:

lazy val someVariable = new VerySlowToConstructClass()

In this case, the variable will be initialized the first time it is accessed.

Lambdas

In Xtend

val lambda = [String s | s.length]

In Scala

val lambda = (s : String) => { s.length }

Both languages have shorter versions for special cases (no parameters, one parameter, etc). I am not going to describe them here.

Something really cool in Xtend: if you have an interface with one method used as a callback, the compiler will convert a lambda automatically to the interface type.

final JTextField textField = new JTextField();
textField.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
    textField.setText("Something happened!");
  }
});

Can be described using a lambda in Xtend like:

val textField = new JTextField
textField.addActionListener([ ActionEvent e |
  textField.text = "Something happened!"
])

Or, using the shorter lambda version I did not describe:

val textField = new JTextField
textField.addActionListener [
  textField.text = "Something happened!"
]

Lambdas are closures, so they take variables from the current scope. Lambdas are not only useful for callbacks. I do miss ruby’s each/map/collect in Java:

movies.filter[ (1980..1989).contains(year) ].sortBy[ rating ].last.year)

Or map/reduce

val charCount = strings.map[s|s.length].reduce[sum, size | sum + size]

Extending libraries

Xtend has a really cool feature called extensions.

"hello".toFirstUpper // calls StringExtensions.toFirstUpper(String)
listOfStrings.map[ toUpperCase ] // calls ListExtensions.<T, R>map(List<T> list, Function<? super T, ? extends R> mapFunction)

Xtend already includes quite a lot of extensions for Java classes like String. Some are convenience methods, but some support features, like the map example above. It is not very useful to support lambdas if your collections do not have forEach or map. I like how this feature is implemented. Simple and elegant. There is more awesomeness in this area. You can find about it in the guide.

Scala on the other hand has something called implicit convertions. They can be used with a pattern called “pimp-my-library” to extend existing APIs:

For example, to add a method headOr to the List class, one first create a “wrapper” class with the method:

class ListExtensions[A](xs : List[A]) {
    def headOr(f : => A) : A = xs match {
        case h :: _ => h
        case Nil    => f
    }
}

Then you add a implicit conversion to this wrapper class:

implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs)

And then this should work:

println(List(1,2,3).headOr(0))     ==> 1

Implicit conversions in Scala can be used to use lambdas as event listeners:

implicit def function2ViewOnClickListener(f: View => Unit) : View.OnClickListener = {
   new View.OnClickListener() {
     def onClick(view: View) {
       f(view)
     }
   } 
}

Then this works:

loginButton.setOnClickListener((v: View) => { println("CLICK!") } ))

This is not automatic as in Xtend. When I was playing with Scala & Android what I did was to create a “trait ScalaActivity extends Activity” with the implicit conversion and then make my activity “class MainActivity extends Activity with ScalaActivity”. Traits are cool, give them a look.

There is more stuff in both languages I am not going to spend time on, but you can go to the respective documentation.

For Xtend go to the documentation or this document called “20 Facts about Xtend”.

For Scala. I bought “the book”. However you can also find more in the documentation site.

IDE support

I first tried Scala a year ago (can’t remember) and the IDE support was so bad that I did not go further. This is no longer true. There has been quite a lot of investment in it lately and it is good enough already.

Xtend is part of Eclipse now. Therefore you can expect good IDE support. I found some glitches and weird messages, but in general it works fine.

Android

I tried both languages on Android.

Scala worked fine, but you have to use ProGuard to reduce the size of the application by removing unused methods and classes.

This guide was a good start. However I hit weird errors with the Treeshaker Proguard plugin I was using. This Stackoverflow answer put me back on the right track with the right ProGuard plugin.

I don’t feel confortable with Scala on Android. Without an external tool to trim the jar the generated code goes over the limit of methods that can be handled, even when developing. Not only that. The scala runtime library is 8.7M:

-rw-r--r--  1 duncan users  8.7M Sep 17 00:01 org.scala-ide.scala.library_2.10.0.v20120820-123254-M7-1ab4994990.jar

Xtend was a surprise. Theoretically, as it just generates Java code, it should kind of work out of the box. This was not the case. It was harder than with Scala.

I spend quite some time trying to use the “R” Android class with Xtend. Basically:

setContentView(R.layout.activity_main);

And the answer was not intuitive for me.

setContentView(R$layout::activity_main)

This is a syntax issue. It is documented. But it was just too unexpected for me.

There is another issue you should know about. No debugging. The Dalvik VM does not support JSR-45 which is why debugging Xtend (and other Xbase languages) doesn’t work.

Once I accepted not being able to debug. I ran my program:

09-29 21:26:02.794: I/dalvikvm(11174): Failed resolving Lduncan/test/MainActivity$5; interface 514 'Lorg/eclipse/xtext/xbase/lib/Functions$Function1;'

Ok. The Xtend runtime libraries need to be put into the apk. I went to the build settings “Export and Order” and marked the Xtend library.

[2012-09-29 23:40:08 - Myapp] Error generating final archive: Found duplicate file for APK: about.html
Origin 1: /space/sw/eclipse/plugins/org.eclipse.xtend.lib_2.4.0.v201208210511.jar
Origin 2: /space/sw/eclipse/plugins/com.google.guava_10.0.1.v201203051515.jar

Ok, if I delete these files, everything will work (of course it will break again when I update Xtend with Eclipse:

zip -d /space/sw/eclipse/plugins/org.eclipse.xtend.lib_2.4.0.v201208210511.jar about.html
deleting: about.html
zip -d /space/sw/eclipse/plugins/org.eclipse.xtext.xbase.lib_2.4.0.v201208210511.jar about.html

Run again:

[2012-09-29 23:44:07 - MyApp] Error generating final archive: Found duplicate file for APK: plugin.properties
Origin 1: /space/sw/eclipse/plugins/org.eclipse.xtend.lib_2.4.0.v201208210511.jar
Origin 2: /space/sw/eclipse/plugins/org.eclipse.xtext.xbase.lib_2.4.0.v201208210511.jar

Ok. Now I get it. These are Eclipse plugins. There will be always duplicated files. This is not the solution.

What I did was to unmark the “Export and Order” check I did to “Xtend Libraries”. Copy xtend.lib, xbase.lib and guava jars from the plugins into libs/ of my project. And remove about.html and plugin.properties from these 3 jars. Basically I did a un-OSGi version of the jars.

Also, a good tip is to change the “xtend-gen” folder in the Xtend settings to use the “gen” folder Android already uses to dump generated files from resources and others.

After that, everything worked fine and I got my application running on Android. The size of the Xtend and Xbase libraries is 7K and 90K. guava is the heaviest dependency with 1.2M. But nothing compared to Scala. My application was 2M installed without proguard processing (which happens by default in release mode).

Criticism

Scala

In my opinion, Scala is much more mature. The syntax is well thought. I was annoyed for using [] for generics and () to index arrays until I saw the explanation in the book. I am enjoying reading the book and learning the “Scala way”.

Scala has a unified type system. Unlike Java, everything is an object. You can write:

"some text".length
1.abs

The problem starts when you realize there is Null, null, Nil, Nothing, None, and Unit (a.k.a void). Also Any, AnyRef and AnyVal. If you want to learn about those you can read this post. Or you look at scala.collections.immutable.List to look for more information about the type:

sealed abstract class List[+A] extends LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]]

Oh, and there is a generic called “Either[+A, +B]“.

I know there is a reason for this. I know at some point a page in the Scala book will explain it. But the step curve is not easy. I was writing very basic code and I was asking myself how to do lot of stuff. The biggest problem in my opinion is that Scala, being “Scalable”, allows to write the code in various ways. One is the Scala way. The other is not. Sometimes one is the intuitive one. Sometimes the other is to slow.

An example of this is the Quick Pimp Library Pattern. This allows you to write the explicit conversion easier by not having to create a “wrapper” type.

implicit def string2toInt(s: String): { def toInt: Int } = new {
  def toInt: Int = java.lang.Integer.parseInt(s)
}

But for some reason (see the link) this is slow. There was also some speed issue with “for” loops if you write the “for” in the wrong way (I forgot the details).

This gives me a feeling of the Scala culture very similar to what some subworld of C++ doing heavy template meta-programming, policy based design gives to me. I like boost. But I have to be very awake to decode the signatures and understand how to use a library. The design and the quality is top-notch, but it is an advanced device. You need to invest quite a bunch of time on it and make sure those features will actually pay off. I am not against a language that requires some CS background and a type system that requires you to think a bit. But if you are going to master it, you have to be aware of the cost/benefits.

Xtend

Xtend was a pleasure to write and read. I got used to it very fast. The documentation is a single page guide. The type system is the same as Java.

However, Xtend is not fully mature yet (despite version being 2.x). I was playing with the JFugue library and I tried to do this:

rhythm.addSubstitution('O', "[BASS_DRUM]i")

But I got an error, because the char was interpreted as an string. Then I realized that Xtend does not have character literals yet. The solution:

rhythm.addSubstitution('O'.charAt(0), "[BASS_DRUM]i")

Then when playing with Android, I tried to use one of the greatest features: automatic conversion of lambdas to interfaces with one callback method:

button.onClickListener =  [
  this.textView.text = "Foo" 
] 

But it did not compile! The simplest example did not work. Disclaimer: I was not using the released version. But I was not using the nightly builds either. I was using the milestones. I got a “Incompatible types” error. I updated the eclipse plugin to the current milestone, restarted Eclipse, and everything was working. (Facepalm).

Conclusions

Both are great languages. If you are doing servers and services, I’d pick Scala. But be prepared to invest some time learning the culture behind it.
Learning Scala gives you the most from the Play! Framework. It can also be used from Java, but it is not the same.

If you are only looking for a Java refresh. Go with Xtend. You will learn it in one night and will benefit from the value it provides. Once the quirks with Android get resolved (especially the debugger), it is a great addition to Android development. Being an Eclipse project means the IDE will be a first citizen and releases will be stable enough to ship with Eclipse itself.

About these ads

32 thoughts on “A better Java: Scala or Xtend?

  1. How about Groovy? Much less exotic, much better than Java.

  2. Interesting read. A few nit-picks though:

    val lambda = (s : String) => { s.length }

    should be

    val lambda = (s: String) => s.length

    In general, there is no space ahead of the colon (see other examples).

    Some of your stuff is also a bit dated, for instance, instead of

    implicit def string2toInt(s: String): { def toInt: Int } = new {
    def toInt: Int = java.lang.Integer.parseInt(s)
    }

    you can write something like this in the upcoming version

    implicit class RicherString(s: String) {
    def toInt: Int = java.lang.Integer.parseInt(s)
    }

    and get no runtime overhead at all.

    Same thing for “headOr”:

    implicit class ListExtensions[A](xs : List[A]) {
    def headOr(f : => A) : A = xs match {
    case h :: _ => h
    case Nil => f
    }
    }

    There are a few significant advantages of Scala’s extension mechanism compared to Xtend’s extension mechanism like that you are able to implement new interfaces wtih it.

    I agree that the collection stuff can be a bit scary to read. The reason is that every single bit of functionality is factored out into reusable components which can be used across different collection implementations wtihout duplicating code.
    Another reason is Scala’s adherence to the uniform-return-type principle which means that not only operations on a List return a List and operations on a Set return a Set, but that also things like Strings and specialized collections like BitSet do “the right thing” automatically.
    No other language has managed to do this until this day (especially not without any special compiler support).

    Scala on Android is pretty much painless. SBT does everything I want, blazingly fast and the resulting apk for some example aplication weighs in less than 120 kb.

    All in all, thnaks for the great article!

  3. Pingback: In the News: 2012-09-30 | Klaus' Korner

  4. IMHO , xtend should build a play1-like full-stack , stateless web framework , with type-safety (which play1 lacks). This will attract many developers abandoned by play2+scala.

  5. Nice post! And very constructive feedback as well. Would be interesting to tackle down what went wrong with click listener. Maybe you can file a bugzilla, since I did exactly that myself without any problems.

  6. Nice post.

    I think Xtend is a really good add on to the java language that brings java up to c#. Combined with Xtext it is of course way more then just a language.

    Scala is a language that tries to combine functional and object oriented programming with a powerful type system. You can express a lot with the scala type system that is plain impossible with xtend or C#. This power comes with a price. You have to learn new stuff and at the beginning it looks like gibberish… ;-)

    Concerning types. In Scala you have AnyRef and AnyVal (both being subtypes of Any). In Java you have
    - objects
    - primitives
    which can be boxed leading to funny null pointer exceptions where you don’t expect them
    - enums
    - null

    So 4 different types in java to 1 in scala…. ;-)

    There is a fine and good reason to use “()” to access an array. An array can be seen as a function from Int to the type of the array contents.

  7. A very nice comparison. Sometime back I used Xtext to create some simple DSL to augment Java development in a project, but need to look at Xtend as well.

  8. Nice post indeed, I find it very good to ignite discussion about the topic :-)

    I think that Scala goes above and beyond C# “parity” and syntax sugar, which seems Xtend’s main focuses to me (extension methods, operator overloading, vars, etc).

    In other words, I think that the main difference between Scala and Xtend is that the main differences between Java and Xtend are syntactical, while the main differences between Java and Scala are conceptual.

    As Jan pointed out being conceptual means that they are harder to learn and a lot harder to use correctly but also that they have deeper, systematic consequences that can be very powerful if used properly.

    Take, for example, traits/mixins: although it might seem an easy concept it really has profound implications on the way you write code, how you test it and even how you think about it during design. For one, it changes many design patterns, even making some of them useless.

    Another one, which by the way I miss very much in Java, are proper closures[1]. Note that Xtend’s lambdas are *not* closures in a complete sense[2], since they can only “close” final variables/vals just as Java anonymous classes: if you need to write to local variables you must “bridge” the context yourself.

    A further Scala feature that has surprised me is support for generics variance/contravariance. I don’t expect many programmers to be familiar with the concept, let alone using it properly for API design – but it does help if you are writing a framework and you know how to use it!

    Lastly, the Scala team added macros as an experimental feature in 2.10[3] – I think that feature alone opens a whole lot of new possibilities. I look forward to play with the definitive implementation!

    [1] It seems I’m not the only one, Martin Fowler misses them too: http://martinfowler.com/bliki/Closure.html
    [2] http://en.wikipedia.org/wiki/Closure_%28computer_science%29
    [3] http://docs.scala-lang.org/overviews/macros/overview.html

  9. Pingback: Xtend : à lire sur le web | Jmini Dev

  10. As a potential small-scale generator of pv cell heat energy at the Ministry of Basic Industry.

  11. With the growth of solarWhat these opposing organizations are really doing is slowing down the race photovoltaic manufacturers to grid parity.
    Just kind of what you’re hearing in terms of our outlook for the company net of expenses. To finance that growth, we’ve increased our total
    debt by $212 million on a net basis but also from
    bringing up your own new capacity? S, Germany does not have a big balance sheet to use the greenhouse effect and thermal dynamics to produce electricity for the growing public.

  12. Why users still use to read news papers when in this technological
    globe everything is existing on net?

  13. I have learn several just right stuff here. Certainly price bookmarking
    for revisiting. I wonder how much effort you set to make this kind of magnificent informative web site.

  14. Pingback: Scala: Links, News And Resources (6) | Angel "Java" Lopez on Blog

  15. But that doesn’t mean for ONE SECOND that I don’t believe how vital it is for every horse owner
    to develop skills in training a horse on some level.
    This is where the need for a good horse racing systems comes
    in. Several of the rocking horse pozycjonowanie stron plans include things like steel hardware and slats that could pose difficulties for younger youngsters.

  16. Wykupując urlop. Co chwila wyżywieniem, albo także co chwila
    nierzadko oferty róży częściej wystawać naszych rodaków
    na ekskluzywne wczasy. Raz za razem częstokroć
    oferuje dodatkowe zapewniają naprawdzić, azali lepiej mieć wliczone w cenę.
    niedaleko wersji all inclusive – porady Maroku jest na bodajże droższa,
    jednej osoby, awantura z Afryką z pewnością pikieta jest samemu robić kupowanie.
    W niektóre wykupić opcję na terenie danego zwierzchni a
    więc też zwięźle przede suma gotowe, w cenie. Pozycjonowanie katowice.
    Pozycjonowanie katowice. Urlop all inclusive.
    Zazwyczaj niedaleko wyborze wycieczki sugeruje dodatkowe zapewniają.

  17. It’s going to be end of mine day, but before ending I am reading this great article to increase my knowledge.

  18. Hey there! I just wanted to ask if you ever have any issues with hackers?

    My last blog (wordpress) was hacked and I ended
    up losing a few months of hard work due to no back up. Do you have any methods to prevent hackers?

  19. After the incubation period, reactivation or fresh outbreaks can occur.
    A doctor should try as many different pills, creams and ointments
    as he or she can before finding the correct one. 2006), it’s apparent that many
    women are safely having babies despite having herpes.

  20. If you enjoyed reading this article and would like to
    read more about Karate Gear and MMA Gear. Kids learn to
    concentrate more effectively and think more clearly.
    There can be some aspect of sport or self defense in these Arts.

  21. The second concern is the Instructor who is doing the teaching.
    Karate Plus Martial Arts Personal Development Center in San Antonio, Texas WINS 2010 Nickelodeon. Dan Osler during his reserve Physical
    fitness associated with Gap Runner’s pronounces “There tend to be definite indications which your player might recognize after only their self when the attempt for peaking is definitely accelerating proficiently.

  22. Have the parent work with them as often as possible and they’ll learn it in no time.

    This move can also be used while trying a takedown and striking the opponent using punches, elbow strikes and knees to the opponent’s body.
    There is no need for a special training place or equipment’s for practicing this workout routine.

  23. Jst got off the phone with a single.

  24. This is my first time pay a quick visit at here and i am genuinely pleassant to read everthing at single place.

  25. Hello i am kavin, its my first occasion to commenting anywhere, when i read this
    piece of writing i thought i could also create
    comment due to this sensible piece of writing.

  26. Hi there, I wish for to subscribe for this website to take latest updates, so where can i do it please help
    out.

  27. Taken in pieces, it becomes reduces to a trivial method akin to taking
    aspirin when a person gets a headache. Alright, I’m
    going to climb off my soap box for a minute and tell
    you a story from my past which I hope will help to show what
    real martial arts CAN do for you in the real world. t do them any good unless the facilities and the instructors are good.

  28. An impressive share! I have just forwarded this onto a coworker who was conducting a
    little homework on this. And he actually bought me lunch
    because I discovered it for him… lol. So let me reword this….
    Thanks for the meal!! But yeah, thanx for spending some time to discuss
    this subject here on your internet site.

  29. Pretty great post. I just stumbled upon your
    blog and wisheed too mention that I have trly enjoyed browsing your blog posts.

    Aftedr all I will be subscribing on your rss feed and I hope you write once more
    soon!

  30. That is why I am encouragingall eBay sellers to include some kind of
    printed make a difference with your shipments. The 3rd card will be straight correlated to the fourth card, which is called the Previous.

  31. Keep in mind that personal integrity is the basis of accurate intimacy and pleasure.
    You require to delay a serious conversation you are
    planning to have with someone. We individually use VistaPrint and adore their service.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.