About a year ago I started using Scala. A programming language I felt in love with after all. The one and only programming language that started making me smile when I was happy to see how elegant I can express my ideas.
I have been trying to spread the word about Scala during various Flash conferences and always tried convincing my colleagues and friends to learn this great language. A blog post by Alan Shaw about his experience with Haskell inspired me to write about my journey.
Why Scala
I was very unhappy with ActionScript and Java last year. ActionScript is a good start but needs to adapt the features of the dropped ECMAScript 4 proposal to become interesting and competitive in my humble opinion. Java on the other hand is only interesting to me because of its virtual machine. The language itself is simple and has the features you need to get the job done.
I got very late into the Java game and missed the bumpy early years. However I was never earning money with Java since I was doing only open source.
Open source is a hobby. I like doing it. So why not use a language that is fun too? I finished the first version of Apparat in 2009 using Java. But the language became more and more annoying because of all the boilerplate code you have to write and the massive violation of the DRY mantra. A particular example are Java’s generics. I was dealing very often with graphs in Apparat. I had a parameterized graph class Graph<V, E> and of course sometimes the vertices and edges are parameterized too. I was tired of writing code like this over and over again.
final Graph<BasicBlockVertex<AbstractOp>, Edge<BasicBlockVertex<AbstractOp>>> graph = new BasicBlockGraph<BasicBlockVertex<AbstractOp>, Edge<BasicBlockVertex<AbstractOp>>>();
So I was searching for a new language that allows me to focus on ideas. I could now talk about languages like Lisp, Clojure, OCaml, Haskell and C#; but I will just explain why I did not use C# — a language that is superior to most other languages. If Scala would not exist, I would probably do more C# work.
I do not think that interoperability is an issue with C# since Mono is a great project that gives you Linux and OS X support. But I used C# already for Apparat’s predecessor AS3C. So why not learn something new? This is why I went for Scala . I thought I can learn more about programming if I start using it — and boy was I right: I am learning something new each day since then.
Learning Scala
Most people that see Scala for the first time are immediately irritated by the syntax they do not understand. Same happened for me. When I first saw Scala I just gave it five minutes and went on to something else. The second time I came back to Scala I spent more time on the examples and tried understanding them.
Here is the problem: learning Scala is hard. My main issue was not the syntax but the fact that most people simply slap you with a lot of academic topics right in the face. As an autodidact you have to read a lot before you will write your first line of code if you follow that path. If you studied computer science and took a Haskell or Lisp course you will probably know about algebraic data types and monads already.
Instead I started ignoring most of the cool features and tried understanding the syntax first by writing actual code. You will find a lot of high quality blog posts on Scala very easy. When it comes to understanding Scala from an ActionScript perspective it is a little bit easier since you know anonymous functions already. Let us demistify a little bit of the syntax.
Take this ActionScript example.
const square: Function = function(x: int): int { return x * x }
You can remove nearly all type annotations because of Scala’s type inference. You still have to annotate method arguments. The compiler would complain if you leave those types out. This is a trade-off for readable error messages and compiler speed.
const square = function(x: int) { return x * x }
Next you can get rid of the return keyword in Scala. Because it is a functional language every usual statement is an expression. val x = if(true) 1 else 2 has a value for instance and is equivalent to var x: int = true ? 1 : 2. What does val mean? It is the const keyword in Scala. I prefer it this way. You have variables and values.
val square = function(x: int) { x * x }
This looks already much better in my opinion. And here comes the catch. Scala is a functional language. It is also an object oriented language but more on that later. But it borrows a lot of the nice features from other languages like OCaml or Haskell.
Because you are working with functions so often there are multiple short-hand notations available. But the key is to drop the function keyword and replace it with the shorter =>. Last but not least we do not even need the curly braces in Scala and our example finally becomes
val square = (x: Int) => x * x
You will figure out that => is used more often. This is another catch. Two particular things are confusing for the beginner. => and _. => is used in multiple places like definition of anonymous functions, types, scope definitions and self type annotations. I will probably not talk about the other two in this post.
It is worth noting that Int => Int is the type of a function that takes one parameter typed Int and returns a result typed Int.
So Imagine you have this definition:
val applyIntFunction = (x: Int, f: Int => Int) => f(x)
This anonymous function takes two parameters. One is typed Int and another one is a function. So we could write applyIntFunction(2, square). But what if we want to increase x just by one? One option would be applyIntFunction(2, x => x + 1). You can see here that Scala knows the type of my anonymous function already and I am allowed to omit it. This is not too bad. But since it is so common in functional programming to work with functions, an even shorter syntax exists. Meet the underscore.
applyIntFunction(2, _ + 1)
This is where it gets confusing at first. However you will love this feature and it is not so hard to understand. The Scala compiler expects the type Int => Int as the second parameter. _ + 1 is in fact an anonymous method that takes one parameter. But we do not know anything about the type if we look at the method alone. It is always important to think about the context. _ * _ is a method that takes two parameters for instance. This would not work in our example. What does _ * _ do? Probably multiply two things. But again it is a question of the context and the required types.
val applyTwoIntFunction = (x: Int, y: Int, f: (Int, Int) => Int) => f(x, y)
applyTwoIntFunction(2, 2, _ * _)
One of my main problems with Scala was the usage of the _ character and how it works. Fortunately a great post I want to highlight again already exists. It explains very well which purpose the underscore fulfills in which context.
So even if you think that Scala is hard to understand at first keep in mind that it is just a different dialect of expressing your ideas. If you have less to write you can do that not only faster but more concise. Once you start thinking in Scala it becomes of course absolutely clear that _ * _ means multiply those two things whatever they are.
A Language For Hackers
Scala is a great language for hackers. Four features make it very easy to write any library that feels like real code. Namely anonymous functions, the ability to omit braces and dots, type parameters and implicit conversions. Okay, what does it mean? I already talked about anonymous functions but omitting braces and dots? In Scala the code 1.plus(2) is identical to 1 plus 2. Whenever you have a method with exactly one parameter and an object on the left hand side you are allowed to omit both braces and the dot. First of all this is quite cool but also I did the mistake to make extensive use of this feature. In the beginning of Apparat I was omitting nearly all dots just because I can. It does not make your code more readable and I inserted dots and braces back into the code.
So when does it help? When it makes sense. This sounds weird but lets think about another example. Lists are a key element of Scala and any other functional language. "Hello World".toList returns a list of characters. If we want to have all of them as lower case we would map that list. Even ActionScript has a predefined method for this task, called Array.map. Noone uses it. The explanation is that it is simply to complicated. Imagine we have a List[Char] in Scala or an Array in ActionScript and we want to convert it to an Array where all characters are lower case.
This is the ActionScript version:
array.map(function(x: String): String { return x.toLowerCase() }).
This is the Scala version:
list.map(x => x.toLowerCase())
But lets keep in mind what we have learned and simplify it a little bit:
list.map(_.toLowerCase())
Remember what I said about omitting dots and braces?
list map { _.toLowerCase }
Et voilĂ . You can decide which one is better to read. The Scala version is short and nice. However if I would simply give you this snippet of code you do not know what it does as long as you do not know about the context. But we are dealing with language and context all day. Words have different meaning in a different context and it is not hard to guess that toLowerCase probably converts a character to its lower case representation.
Please note two more things. I left out the () after toLowerCase because it is a method without side effects. This is the case whenever your method does not modify any state in your system. Those methods are usually written in ActionScript like public function get toLowerCase(): String { ... }. And we omit the () as well.
One more example to convince you why this makes sense: Imagine we want to get rid of all the space characters in our now lower-case List (or Array in ActionScript).
array.map(function(x: String): String { return x.toLowerCase() }).filter(function(x: String): Boolean { return x != ' '})
vs.
list map { _.toLowerCase } filterNot { _ == ' ' }
This also explains why Scala is a great language for hackers. You can bend the language to your needs. Usually those hacks are categorized as domain specific languages. A language for a specific task. I have written a CSS DSL using Scala for instance.
In order to do such things you will need implicit conversions. A very cool thing that is out of scope for this article (Update: I wrote a post on implicits).
Conclusion
Scala can do much more than you might expect. I just covered a small part of it. For me it is important to explain why I like it so much and why I believe that it is an elegant language that makes programming fun again.
After one year of extensive Scala use I do not regret a single minute spending confused in front of my screen. First of all I like that someone spent a good amount of time thinking about the language. It is simply great that you can distinguish between a class, something you want to instantiate multiple times, and an object, Scala’s notion of a singleton, at compile time. No need for private constructors and the other boilerplate fuzz.
The Scala community is filled with very intelligent and academic people who are not arrogant and always treat you with respect.
Speaking for myself I can only agree that Scala makes you more productive and it was a great decision to start learning it. Scala is also not a pure functional language. In my opinion a great decision although not everyone will agree. But you can always decide whether or not you want to write a loop using a simple while or to go for tail recursive functions with immutable values. It is up to you.
I started to use Scala also at work as well. It is very nice for smaller projects like determining the similarity between users and storing that in a database. Currently I am the only one writing Scala in our office so most projects are still either Java or ActionScript based.
If you are into speedcoding: Scala is your weapon of choice. The one time I was using it on stage I was finished after about 75% of the time which is great if you target ten minutes but then my IDE crashed. Tooling is a different topic but has greatly improved in the last couple of months. If you want to learn Scala why not simply start with an old experiment you wrote in Processing and convert that to Scala? Since Processing is written in Java you can call its methods from Scala without any problem. I did not mention it yet but since both languages run on the JVM you have full interoperability between them.
Apparat is also a great example of marrying Scala with Java. JITB is for instance written in Java and Scala. I have choosen to go for Java because I am working with Java Bytecode in Apparat and at that point the Scala compiler was not very stable regarding the bytecode it emitted. This does not mean it was broken but it changed during versions which would have made my job much harder.
However even if you will not use Scala on a daily basis it will make you a much better programmer. This is also true for any other functional language. I used immutable lists in my as3-signals fork to simplify the whole dispatch logic and was able to delete a lot of unnecessary code.
Regarding Apparat, in the end I got rid of writing
final Graph<BasicBlockVertex<AbstractOp>, Edge<BasicBlockVertex<AbstractOp>>> graph = new BasicBlockGraph<BasicBlockVertex<AbstractOp>, Edge<BasicBlockVertex<AbstractOp>>>();
Which became
val graph = BasicBlockGraph.empty[BasicBlockVertex[AbstractOp], Edge[BasicBlockVertex[AbstractOp]]]
Oh wait, it did not. In fact it is now
def createGraph() = BasicBlockGraph.empty[BasicBlockVertex[AbstractOp], Edge[BasicBlockVertex[AbstractOp]]]
...
val graph = createGraph()
What does def mean? Go figure it out and enojy learning Scala. You will not regret it!
Great post illustrating some benefits of scala. I gave a presentation on scala at work and had some initial interest, but no one seemed to really understand how much easier certain things are to express in Scala than Java.
One thing I find myself using scala for on a daily basis is as a REPL for java code. You need to change your java code slightly to have it run, but it definitely works.
I agree on the general awesomeness of Scala.
Just to mention it however, the example you gave for the verbosity of Java generics (your own generic classes) is actually the one case where Java does have type inference too, via static factory methods, e.g. something like:
Graph<List, Set> g = Graph.create();
Based on a method signature like this:
static Graph create() { // …
WordPress ate my generics, so I’ll try again with HTML entities:
Graph<List<String>, Set<Integer>> g = Graph.create();
Based on a method signature like this:
static <T1, T2> Graph<T1, T2> create() { // …
Great post. Scala will save the JVM.
The weakest point compared with C# and Java is IDE support but it’s improving every day. I expect 2011 to be a great year for the Scala community.
“In order to do such things you will need implicit conversions. A very cool thing that is out of scope for this article.”
AHHH!!!! Great article and I was reading through it hoping you’d talk about implicits which is one of those things that I can’t seem to grasp. Will you be tackling that in a future article? If not, do you have any resources you’d recommend?
Fabian: Yes that is possible of course. And Java 7 will hopefully bring the diamond operator to solve this once and for all but until then all the manual plumbing is just annoying for such a simple task.
Well I’ve been using Array.map and Vector.map in ActionScript; that’s how I know they’re even worse than you describe! The function has to have two ridiculous extra arguments besides the array element itself; also in the Vector version it only does a => a, not a => b.
This stuff absolutely makes you a better programmer. Hate side effects now. Want to return tuples. And as Robert Penner says, immutability is so hot right now.
Thank you for a good article. Another good scala overview http://beta.parleys.com/#st=5&id=10&sl=36 they talk about implicit conversion there.
Pretty nice work. Well explained with examples.
Thanks!
Is it possible to quantify on how much (in %) you could have accomplished the same with Java/C# in a year.
ActionScript has done ECMA4 for years. That’s where that all came from, was Adobe pushing forward in their virtual machine, which was later donated to Firefox.
John: Yes and they implemented some of the ES4 features (like Vector.) but you can read the full spec/proposal to understand why I think it is important.
That’s an interesting post. I am surely going to try Scala now.
Thanks for a great post! I haven’t started learning Scala yet but it’s on my list for 2011 and your article have given me more inspiration to accomplish that.
Other than the fact that you love Scala, what are you saying? You should say what Scala is and what it’s good for.
as3 question :
why
const square: Function = function(x: int): int { return x * x }
instead of
function square(x:int):int{return x*x);
i would see the use with var, but with const ???
thanx.
Thank you for your article, I always wanted to learn a functional language, but every tutorial I read made me feel too stupid to learn it.
I also preferred Scala, as I’m a Java developer; now I know I can do it.
Oh, thanks. That did actually make things a little easier to understand – instead of just getting Scala crazies telling me how awesome it was!
I hate to be a zealot myself, but did you try haxe? It’s got all your inferencing, and outputs to flash, php (soon java) etc. Thought it would be a perfect fit for ya!
Now that you’ve explained some of that Scala goodness I do see goodness in not having to say “function” or “return”, they’re just so verbose!