Sven Efftinge's Blog
Wednesday, January 11, 2012
I like free beer!
They list programs generating lyrics for a song about beer in 1440 different programming languages (it will be 1441 very soon ;-)). These are the lyrics to generate.
So here is a version written in Xtend:
It uses a couple of interesting features:
Seriously, I think this is one of the most concise and readable versions. Compare yourself.
Wednesday, January 04, 2012
Collection Literals in Java (or a hidden gem in Eclipse JDT)
In that talk he discusses the various language features which have been added to Java in terms of how important resp. problematic their addition was. I agree with most of his reasoning but not with the following two:
- static imports
He said they are ok, but not too useful and that he makes use of them only about once a month. - diamond operator
He claimed, that this was an important addition, since now creating new collections is less noisy.
I disagree for the following reasons
Joshua Bloch actually also helped designing a very cool collection library which is part of Google Guava. If you don't know it, have a look! Besides other useful stuff that library contains factory methods for the common collection types.
For instance to create an ArrayList you could write the following:
List<String> names = Lists.newArrayList();
Making use of a static import one can write something like this:
import static com.google.common.collect.Lists.*;
...
List<String> stuff = newArrayList("Foo","Bar","Baz");
But the inconvenience of adding a static import every time you want to create a new collection is a problem. JDT to the rescue! There is an almost hidden gem in JDT, that allows you to have static import favorites for content assist. This is my configuration:
Having your static imports configured here, will make their methods available through code completion without having an import first. Instead the import will automatically be added as you apply the proposal.
I only create collections that way, because it's so easy and readable, and I don't have much use cases for the diamond operator (in fact inference on the left hand side would have been much more interesting). On the other hand I use static imports in almost any class file.
Btw, those static imports not only make the factory methods available but also all the nice higher-order functions like, collect, filter, etc..
A welcome productivity gain!
Tuesday, January 03, 2012
Upcoming Presentations on Xtext / Xtend
Hope to see you there!
Wednesday, December 21, 2011
Groovy, Scala, Java, Xtend - an UPDATED stupid comparison
Measurement
Henning suggested that the number of iterations is too small:10000 iterations are probably not enough for a comparison: If I go from 10k to 100k iterations, the Scala version needs 5x time -- the Java version only 2x.
Indeed. Here's what I got when using 1M iterations:
- Java (the pretty version):
Took : 245 ms, number of elements : 3000000
- Xtend :
Took : 278 ms, number of elements : 3000000
- Xtend (using switch - see below) :
Took : 298 ms, number of elements : 3000000
- Scala (using for comprehensions) :
Took : 5140 ms, number of elements : 3000000
- Scala (using while loops) :
Took : 931 ms, number of elements : 3000000
- Scala (using while loops and java.util.collections - see below) :
Took : 315 ms, number of elements : 3000000
- Groovy (using << operator - see below):
Took : 1683 ms, number of elements : 3000000
Groovy
Thorsten and Jochen pointed out that I used the wrong operator for adding new elements to a list. I should use '<<' instead of '+=' since the latter would create a new list for the single elements before adding them. I've fixed this and the Groovy program is much faster now.Jochen also pointed out that the comparison is unfair since, because of the dynamic dispatch Groovy does heavy caching assuming that a method is invoked for the same type of argument most of the time.
My initial idea was to do a comparison where Groovy has a strength (i.e. dynamic dispatch). After all the other examples also do dispatching at runtime. The Java and Scala version don't call another method, but since Xtend does so and is as fast as Java I'd say this extra call doesn't change much.
Jochen also states:
Imagine a class with those three foo methods written in Java. Then in Groovy you can still run your test. I dare to say that in Xtend you cannot make this work without a dispatcher method somewhere - and your dispatch keyword is implying that - thus I assume you cannot make this then work using a Java class.
I think this is actually a big problem with Groovy. Although it's syntax might look a bit like Java it behaves totally different.
In contrast Xtend binds statically just like Java and in fact a multi method in Xtend behaves always the same no matter if you call it from Java or Xtend.
He further says
But let us not stop here... let us assume that you write the base class in Java, where it knows foo(String) foo(Object) and foo(Boolean). Using this class the Integer variant would call the foo(Object) method in your code. Now extend that class in Java with a foo(Integer) method and Groovy would no longer call foo(Object) but foo(Integer).
I doubt you can easily simulate that case.
I can indeed not do that in Java. But I can do that with Xtend and it still behaves as expected no matter form what language you'd call that code.
Scala
Jan said:I rewrote your little program to use while loops and the java utils collections and the scala version was as fast as java - but nearly as ugly to :-D
Here's the updated Scala version with while and java.util.collections, which is now almost as fast as the Java version:
object Scala extends Application {
val absoluteResult = new ArrayList[Any]()
val before = System.currentTimeMillis()
var i =0
while (i<1000000) {
i = i+1
val result = List("foo", 23, true).iterator
while (result.hasNext) {
absoluteResult.add(foo(result.next))
}
}
println("Took : "+(System.currentTimeMillis() - before)
+" ms, number of elements : "+absoluteResult.size)
def foo(obj : Any) =
obj match {
case _:String => "String"
case _:Boolean => "Boolean"
case _:Integer => "Integer"
case _ => throw new IllegalArgumentException()
}
}
Clojure
Stefan did a nice little example in Clojure. It doesn't use any mutable collections but uses a pure functional style:(defn foo [x] (cond (number? x) "Number" (string? x) "String" (= (class x) Boolean) "Boolean")) (time (println (count (map foo (apply concat (repeat 10000 ["foo" 23 true]))))))On his machine the Java example takes '31ms' and the Clojure program prints
Prints: 30000 "Elapsed time: 194.046477 msecs"
Xtend
An alternative way to do the dispatch in Xtend is using type guards in switch,which doesn't make a huge difference performance-wise :
class XtendWithSwitch {
def static void main(String[] args) {
val absoluteResult = newArrayList()
val before = System::currentTimeMillis()
for (times : 0..1000000) {
val result = newArrayList('foo', 23, true)
for (y : result) {
absoluteResult += foo(y)
}
}
println("Took : "+(System::currentTimeMillis() as int - before)
+" ms, number of elements : "+absoluteResult.size)
}
def static foo(Comparable comp) {
switch(comp) {
String : 'String'
Boolean : 'Boolean'
Integer : 'Integer'
default : throw new IllegalArgumentException()
}
}
}
Java
Finally based on Henning's suggestion I beautified the Java version a bit using Guava and static imports:
public static void main(String[] args) {
List<Object> absoluteResult = newArrayList();
long before = System.currentTimeMillis();
for (int i=0; i < 1000000; i++) {
for (Object y : newArrayList("foo", 23, true)) {
absoluteResult.add(foo(y));
}
}
System.out.println("Took : "+(System.currentTimeMillis() - before)
+" ms, number of elements : "+absoluteResult.size());
}
static String foo(Object s) {
if (s instanceof String) {
return "String";
} else if (s instanceof Boolean) {
return "Boolean";
} else if (s instanceof Integer) {
return "Integer";
} else {
throw new IllegalArgumentException();
}
}
Tuesday, December 20, 2011
Groovy, Scala, Java, Xtend - a stupid comparison
Disclaimer: This is probably the worst possible way to compare execution performance. I'm posting it nonetheless since the result was significant. Judge for yourself.
Today I took some time to check out the latest Eclipse plugins for both Groovy and Scala. I mainly wanted to know how nice the tooling is and played around with it a bit. I had been doing some Scala a couple of years ago, but since the Eclipse plugin not even existed those days it was a bit too painful for me to get used to it.
Groovy's tooling looks very good. There are just a few oddities but mainly I think it's well done... in contrast to the Scala plugin (I used 2.0.0 RC4). It holds a lot of surprises. For instance, with the Scala-IDE installed you'll get Scala-related template proposals in the Java and the Groovy editor. Still Scala the language would be my personal choice if I had to decide between the two. Anyway, this post is not about language features or Eclipse-plugin quality, but about what I experienced regarding runtime performance.
I knew Groovy's performance is bad. But I expected the performance problems to diminish, if I use a scenario using dynamic dispatch and mostly untyped objects. So I wrote the following brain dead code:
class Groovy {
public static void main(String[] args) {
def absoluteResult = []
def before = System.currentTimeMillis()
for (times in 1..10000) {
def result = ['foo', 23, true]
for (y in result) {
absoluteResult += foo(y)
}
}
println("Took : "+(System.currentTimeMillis() - before)
+" ms, number of elements : "+absoluteResult.size);
}
static String foo(String s) {
'String'
}
static String foo(Boolean s) {
'Boolean'
}
static String foo(Integer s) {
'Integer'
}
}
It doesn't do anything interesting but leverages Groovy's built-in way of resolving overloaded methods using the runtime type. I thought it's fair to use this feature in a comparison, also because Xtend's dispatch methods have the same behavior. The result of the code above would be a list containing the string 'String', 'Boolean', and 'Integer' each 10.000 times.
When I run this code on my machine, it prints something like the following:
Took : 2025 ms, number of elements : 30000
A possible Xtend version
This is how I could achieve the same using Xtend:
class Xtend {
def static void main(String[] args) {
val absoluteResult = newArrayList()
val before = System::currentTimeMillis()
for (times : 1..10000) {
val result = newArrayList('foo', 23, true)
for (y : result) {
absoluteResult += foo(y)
}
}
println("Took : "+(System::currentTimeMillis() - before)
+" ms, number of elements : "+absoluteResult.size)
}
def static dispatch foo(String s) {
'String'
}
def static dispatch foo(Boolean s) {
'Boolean'
}
def static dispatch foo(Integer s) {
'Integer'
}
}
On a first glance it looks very similar. Note, the dispatch keyword, which turns a set of overloaded methods into dynamically dispatched methods (i.e. the default Groovy behavior).
In contrast to the Groovy version this one is fully statically typed and as it turned out much faster. (Again as you see my measurement technique is everything but professional, but given such a big difference I dare to say it's faster).
It prints something like:
Took : 43 ms, number of elements : 30000
I also did a Scala version:
object Scala extends Application {
val absoluteResult = MutableList[Any]()
val before = System.currentTimeMillis()
for (times <- 0 until 10000) {
val result = List("foo", 23, true)
for (y <- result) {
absoluteResult += foo(y)
}
}
println("Took : "+(System.currentTimeMillis() - before)
+" ms, number of elements : "+absoluteResult.size)
def foo(obj : Any) =
obj match {
case _:String => "String"
case _:Boolean => "Boolean"
case _:Integer => "Integer"
case _ => throw new IllegalArgumentException()
}
}
I got this kind of result:
Took : 130 ms, number of elements : 30000
And finally a Java version:
public class Java {
public static void main(String[] args) {
List<Object> absoluteResult = new ArrayList<Object>();
long before = System.currentTimeMillis();
for (int i=0; i < 10000; i++) {
List<Object> result = new ArrayList<Object>();
result.add("foo");
result.add( 23);
result.add(true);
for (Object y : result) {
absoluteResult.add(foo(y));
}
}
System.out.println("Took : "+(System.currentTimeMillis() - before)
+" ms, number of elements : "+absoluteResult.size());
}
static String foo(Object s) {
if (s instanceof String) {
return "String";
} else if (s instanceof Boolean) {
return "Boolean";
} else if (s instanceof Integer) {
return "Integer";
} else {
throw new IllegalArgumentException();
}
}
}
Which prints:
Took : 40 ms, number of elements : 30000
Monday, December 12, 2011
Writing Android UIs with Xtend
Xtend is a great fit for Android development. Since Xtend translates to Java source code, it's very easy to use it. After you've installed the Xtend SDK and the Android Development Tools you only need to do two things to get started.
- In Eclipse's preferences configure Xtend's compiler to generated to the gen/ folder.
- Add the Xtend lib and Google Guava to your project's classpath.
Using a combination of Xtend's powerful extension methods and closures, it's possible to come up with a very declarative API to define UI models. It takes a couple of minutes to write an API which allows for defining a UI like the following:
class AppActivity extends Activity {
override void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
contentView = this.linearLayout [
orientation = VERTICAL
view = this.textView ("Hello Android!")
view = this.button ("Click Me!") [
onClickListener = [
this.textMessage('Hello you clicked me!').show
]
]
]
}
}
The API is made available by means of a static extension import. To outline the idea, here's how the button method is defined:
def static button(Context context, String text,
(Button)=>void initializer) {
val result = new Button(context)
result.text = text
initializer.apply(result)
return result
}
Used as an extension method button can be invoked on any instance of Context. Since the last argument is a function type it can be passed after the actual method invocation:
view = this.button ("Click Me!") [
onClickListener = [
this.textMessage('Hello you clicked me!').show
]
]Also note how you can simply assign a closure to onClickListener (which is btw. invoking setOnClickListener()). The compiler will automatically convert it to an abstract class of View.OnClickListener.
And everything is 100% statically typed!
Tuesday, November 22, 2011
What’s So Special About Xtend’s Extension Methods?
You should read this, if you are :
- interested in new programming language concepts
- understood how great dependency injection is
- want to learn about some uniqueness in Eclipse Xtend
Extension Methods
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. In C# extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. (Wikipedia November 2011)In Xtend you could, for instance, add a new method to java.util.List like this:
def static <T> T head(List<T> list) {
for (element : list)
return element
return null
}
Which then can be used as an extension method on any instance of Iterable<T>:
newArrayList(“foo”,”bar”).head()
Using the prefix notation is much closer to how we think, read, and write. From left to right that is. Also the IDE can now provide useful proposals because the receiver is known. The readability gets even better if you use chained method invocations. For instance, let's assume you want to filter the list before obtaining the head. Using the regular infix syntax known from Java the code would like like that :
head(filter(newArrayList(“foo”,”bar”) , [e | e != “foo”]))
But reading inside out doesn’t seem to be the best way to understand what’s going on. So better use extension methods:
newArrayList(“foo”,”bar”).filter(e | e != “foo”).head
Much better, isn't it?
Static Methods Are Bad!
But wait, don’t extension methods advocate the heavy use of static methods? And isn’t that bad coding style?
Yes, often it is.
With static methods you’ll bind your code not only to the signature of a certain method but to the actual implementation. There’s no way (aside from byte code manipulation) to change the implementation without touching the client code. That’s probably not a big deal with the kind of extension methods I just showed. But what if you want to have DAO-like methods available on your domain model types? Accessing them in a static way seems totally uncool, since we wouldn’t be able to run the code with mocks or exchange the database layer easily or just fix or change something later on. That's why static methods are a bad choice most of the time.
Typically you would want to use a dependency injection container to have such services injected. This is where Xtend’s extension methods are different from the one you find in C#.
Xtend allows to use methods from local fields as extension methods.
Let’s assume we have the following Java interface:
interface SaveSupport {
void save(Entity entity);
}
And given we have some domain model type Person which implements Entity, you can write the following code:
class Controller {
@Inject extension SaveSupport
def testStuff() {
val p = new Person()
p.name = “Fred Flintstone”
p.save // translated to ‘this._saveSupport.save(p)’
}
}
That’s a big deal, because now you can use an object oriented coding style but keep your domain model free from layer specific code at the same time! And everything is easily testable and can be run in different scenarios using different DI configuration. There are other unique language features in Xtend, like the template expression, but the combination of extension methods and a good dependency injection framework (Guice) really changes how you structure your software system and reason about it.



