Introduction
Scala is a language that has been on my radar for quite a while. I have wondered whether it would fit the gap of an expressive (like ruby) yet performant (like java) language. Scala is a statically typed hybrid Object-Oriented/Functional programming language out of the EPFL and designed primarily by Martin Odersky, with the goal of being a productive, modern general purpose programming language that fuses OO and functional approaches and that is scalable from small scripts to large complex systems.
Preconceptions
One of my main preconceptions about Scala is that it is a large (somewhat complex) language. Some personal history; the first language I learned to program in was C++, which is a fairly large language with lots of different rules and features. At the time this didn't bug me as i thought 'this is just what programming languages are like'. I didn't even really realize it until i began to see other programming languages that just had less stuff in them. With time I have become less enamoured of C++ as I have seen languages with 'simpler' designs yet similar if not greater expressive power. Scala seems to have a lot of features, and a fair amount of syntax, my hope is that they fit together cleanly and the language doesn't end up with too much of a kitchen sink feeling. But I must admit peeking from the outside in, this does seem like a concern.
The other preconception/hope i have is that Scala can function well as a 'better Java'. Some of the buzz around Scala is that can indeed fit this role and bring a host of modern language design and powerful abstractions to the JVM in an equally performant and statically typed package.
Code
Day one of Scala in Seven Languages in Seven Weeks was a whirlwind tour of the main OO features in Scala. It takes a look at basic constructs and expressions as well as classes, inheritance, companion objects (singleton objects that are like the static classes in java, but share the same name with a regular class) and a brief discussion of traits (more on that later).
The exercise at the end of the section was to write a tic tac toe program. Here is my code for that.
We see a number of Scala features; foremost is type inference. Variables in Scala are strongly typed, but you don't always have to explicitly type out the type ;). The compiler will automatically infer types where possible. It can also do this for the return types of functions. The type system is one of Scala main features and I hope to get a decent peek into what an advanced type system like Scala's can offer in terms of flexibility.
You can also see that some variables are declared as vals and others as vars, this is part of Scala's strategy to help you manage mutable state. Vals are immutable, one the variable is assigned a value, it cannot be made to point to another value. The value itself may be mutable however (like in the case of Array we can edit the array but a List value is immutable). A var is a mutable variable, you can reassign it to point to different values (which may or may not be mutable themselves). Along with numerous immutable data structures, this provides you with a means to control where you want mutability to manifest (important in writing concurrent programs).
We also see collection iterators that take anonymous functions (map, foreach, etc.). Simple syntax for manipulating collections is one of the things I have come to love about languages like Ruby.
Scala also allows you to define nested functions. I quite liked this ability in Io as it allows you to make little helper functions without adding to the namespace of the class or containing scope. It may not have been totally necessary in this case but I wanted to get a feel for it with a simple example.
Some of the superficial/aesthetic similarities (lots of curly braces) and differences (position of type information) to Java also begin to show in this code.
Traits
One of the features we are introduced to is Scala's traits (and it really is just a basic introduction, from what I've seen online there is much more to them). Scala traits can be thought of like Java Interfaces or Ruby Modules, they can contain both data and methods (or just method stubs that must be implemented by classes that include the trait) and can be used to add functionality to classes much like ruby mixins or allows classes to present shared interfaces without fitting them into the same inheritance chain (much like interfaces). Here is an example
The widget class includes the two traits that provide the means to calculate volume and shipping cost. Because Scala is statically typed, you can check at compile time that all the needed methods are in place and that it will all work. The traits are added to the class using the keywords extends and with. This is where I see one minor aesthetic wart. In Scala you can only inherit from one class, and that is done with the extends keyword, the with keyword is for adding traits. However in this case because our widget is not subclassing another class, the first trait that is included needs to use the extends keyword, while the rest use the with keyword. If we were subclassing another class then all the traits would use the same keyword. This is a little thing, but i find it to be inconsistent, and it is little inconsistencies and rules that can sometimes add up to what seems like a lot unnecessary complexity. One nice thing was that even though I include the Shippable trait last it knows not to replace the volume method defined in Volume with the empty volume method in Shippable.
Another feature of Scala that is shown here is the Uniform Access Principle, this is also a feature of ruby that I dearly love and it basically states
"All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation" — Bertrand Meyer
It basically means that you can access attributes through methods and not know the difference. In ruby when you access or modify a class attribute you are always using methods, the methods just happen to look like foo and foo= (i.e. they look like attributes). Note the second thing defined in the Volume trait, this is a method without a parameter list (it is called without parentheses), when mixed into the Widget class the implementation of this will actually resolve to a call to the height attribute. If the class wants to add computation to determining height, then it can make a new height method (with no parens) and make the height val a private attribute, the call to access height will still look the same. I overall like this pattern of access way more than the getter and setter pattern one sees in Java.
Weird little things
For lack of a better place there are a few weird things that i still don't quite know the answer to. If you look at the docs for the Array object. You will see the ofDim method, which creates an Array of a particular dimension. You will notice that there are 5 overloads of this method, one to create a 1 dimensional array, one to create a 2 dimensional array, one to create a 3 dimensional array and so on up to 5 dimensions. What happens when you want to create a 6 dimensional array? I am curious why this method works like this. I know Java has varargs (methods that take variable length's of arguments)—it is quite possible that Scala does not. The argument could alternatively be a list (that would allow you to pass more than 5 elements in), I am just not sure why it is the way it is. If you look at the Tuple class, or rather the Tuple1, Tuple2, Tuple3 ... Tuple22, you see that there are separate classes for Tuples with up to 22 values, again why? In this case I suspect it may be to do with the type system (so you can at compile time guarantee the size of tuples being passed around), but I really am not sure. What would be the way to get around this for someone who wants a larger tuple? Do they just have to abandon tuples at this point.