Tuesday, January 15, 2008

Scala vs Groovy: Lists (Part 1)

Before looking at the syntactic sugar Scala and Groovy have for strings, I'm going to have a quick look at how they handle lists. Collection classes are fairly important in both languages, so I'll have a more in depth look later.

Lists in Groovy

In Groovy, Lists come straight out of the Java collection classes but with added syntactic sugar.

The easiest way to create a list is:

def myList = [1, 2, 3]

An empty list can be created by using []

def myEmptyList = []


As Groovy's List is a java.util.List, you can use all the methods on the java.util.List interface. An example would be add:

myList.add(4)

which will add 4 to the end of the list.

You can add an element (or even the contents of another list) to the end of a list with the += operator

myList += 5
myList += [6,7]

will result in myList containing [1, 2, 3, 4, 5, 6, 7]. The + operator works much as you would expect:

def anotherList = [1,2,3] + [4,5,6]

results in [1, 2, 3, 4, 5, 6]. One interesting thing to note is that:

def yetAnotherList = [1, 2, 3]
yetAnotherList.add([4, 5, 6])

results in [1, 2, 3, [4, 5, 6]] and not [1, 2, 3, 4, 5, 6]

To access a particular element of a list, you use square brackets:

println(myList[0])

will print the number 1.

You can an also slice a list using a range:

def subList = myList[2..4]

results in subList containing [3,4,5].

If you create two different lists and they both contain the same elements, == works as you expect:

def list1 = [1,2,3]
def list2 = [1,2,3]

list1 == list2


returns true.


As you have seen, lists in Groovy are mutable - you can add, remove and change the elements to your hearts content. Scala is different.

Lists (and Arrays) in Scala

Unlike Groovy, Scala has both Lists and Arrays. The main difference between them (at least for the purposes of this post) is mutability - Arrays are mutable, Lists are not.

Scala doesn't have a special syntax for either lists or arrays (though it does use a language feature so that you don't need to use new). So, to create a list (or an array) in Scala, you can use:

val myList = List(1, 2, 3)
val myArray = Array(4, 5, 6)

As arrays are mutable, you may wish to create an empty array and populate later:

val myEmptyArray = new Array[Int](3)

which creates an array of size 3 that contains integers. There are a couple of ways to set the values in this array:

myEmptyArray.update(0, 10)
myEmptyArray(1) = 11

myEmptyArray will now contain [10, 11, 0] - when the array was created, each value was initialized to the default "empty" value for that type, which in this case is 0 for Ints.

With lists in Scala, you can't add elements to the list (or delete or change elements either), in the same way that you can't add, delete or change characters in a string. But just like with strings, you can still perform operations on lists, it's just that you get an entirely new list as a result of the operation. We'll start by looking at adding elements:

var aList = List(1, 2, 3)
aList = 0 :: aList

results in aList containing [0, 1, 2, 3]. You'll note how I used var and not val - val would not have worked as we are creating a new list and changing aList to reference the new list. You'll also notice the :: "operator"1 , which is called "cons". Cons creates a new list with the the object on the left hand side of cons as the first element of the new list and the elements of the list on the right hand side making up the rest of the new list.

Scala has a special "shorthand" for creating an empty list, "Nil"

You can use Nil to build up lists. For example:

var bList = 0 :: 1 :: 2 :: 3 :: Nil

results in bList containing [0, 1, 2, 3]. One interesting thing to note is that

aList == bList

will return true, as both lists contain [0, 1, 2, 3].

There is also a ::: operator, which will combine 2 lists into a single new list

var cList = List(1, 2, 3)
var dList = 4 :: 5 :: 6 :: Nil
var longList = cList ::: dList

will result in a list containing [1, 2, 3, 4, 5, 6]

If we wanted to slice longList and get a sub list of elements:

var sliced = longList.slice(2, 4)

results in a list contain [3, 4] and not [3, 4, 5] that the Groovy slice above (using (2..4)) returns.

Conclusion

I've left a lot (and I mean a lot) of info about Lists in both Groovy and Scala out in this post. The reason why I'm introducing them now is that both languages give Strings list-like syntactic sugar. As I've barely scratched the surface of Lists (let alone the rest of the collection classes) I will get back to them in greater detail later.

Footnotes:
1Why operator is in double quotes will be the subject of a future comparison of operators and operator overloading

Friday, January 11, 2008

Scala vs Groovy: Strings (Part 1)

Single Line Strings

I'm going to start the comparison of string handling in Scala and Groovy with a look at single line strings - the sort of string found in Java.

String s = "Hello, Java!";

Scala's basic string handling is just like Java (but with Scala's syntax and type inference):

var s: String = "Hello, Scala!"
var s2 = "Hello Type Inferer!"

Groovy has both Java-esque strings that are enclosed in double quotes as well as strings that are enclosed in single quotes.

def s = "Groovy's double quoted String"
def s2 = 'A "single quoted" Groovy String'

Groovy also has a third syntax for strings, using forward slashes

def s3 = /Slashy String/

All of the above are java.lang.String - however in Groovy, double quoted strings can become "GStrings". GStrings contain an expression contained in a ${ } block (something that will be familiar to anyone who has written JSP pages). For example:

def x = 4
def gs = "the value of x is: ${x}"
println gs

will print:

the value of x is: 4

Double quoted strings only get promoted to GStrings when they contain ${some expression}. If they don't, then they're plain old java.lang.String strings.


Multi-line Strings


Both Scala and Groovy support multi-line strings. Both use a similar syntax - the triple quote:

var ms = """This is
a Scala multi-line
String"""

def ms = """This is
a Groovy ${lines}
String"""

You'll notice that in Groovy, multi-line strings get promoted to GStrings as well.

Character

While looking at Strings, we should also look at Character. In a manner not dissimilar to Java, a Character in Scala is defined by a single character in single quotes:

val c = 'd'

In Groovy, Characters can't be created directly. This:

def c = 'd'

creates a String, not a Character. Instead, you need to write this:

def c = 'd' as char

which will create a String and then use some dynamic magic to convert it to a Character



End of Part 1


That's it for the basic comparison. However, both languages have syntactic sugar that gets layered onto strings, but that really should be a post on it's own.

Scala vs Groovy: Variable Definintion & Optional Semicolons

Because Groovy is a dynamic language, when you declare a variable you don't have to specify a type for the variable because the run time will work out what the type is for you. To declare such an untyped variable, you use:

def s = "Hello, World!"

However, if you feel like declaring the type, you can:

String s = "Hello, World!"

One thing to note is that declaring the type might actually slow your code down (at least with the version of Groovy current at the time of writing).

Unlike Groovy, Scala is a statically typed language, just like Java. Unlike Java, it can often work out what the type is supposed to be at compile time, and when it can you don't have to explicitly declare the type. In Scala, you use either the "var" keyword or the "val" keyword when you define a variable (I'll discuss the difference between var and val below)

var s = "Hello, World!"

val t = "Hello, World!"

Just like in Groovy, you can also declare the variables type. Unlike Groovy, the way you do this does not look like Java:

var s: String = "Hello World"

You'll notice that you still need the var (or val) keyword and that the type comes after the variable name.

Vars and Vals

What's the difference between var and val? Vars are mutable, vals are not. What this means is that you can change the value of var, but the value of a val is constant. Effectively:

val t = "Hi There!"

is the same as this in Java:

static final String t = "Hi There!";

One thing to be aware of with vals is that if they reference an object, the properties of that object may be mutable - the val is really only a reference to the object, so it's only that reference that's guaranteed to never change.

What all this means is that while you can do this:


var s = "Hello, World!"
s = "Dominate, World!"


You can't do this:

val t = "Hello, World!"
t = "Dominate, World!"


I've found myself thinking of vals as "values" instead of variables because they don't vary.

Optional semicolons

One thing to quickly point out, both Groovy and Scala have optional semicolons. You can still use them if you want to, but most of the time they can be left out.

Comparing Scala And Groovy

As I've started to learn Scala, I've been thinking that it would be a good idea to compare Scala and Groovy. I'm going to assume that both are correctly installed and running.



I'll start by comparing comments:




//This is a Groovy comment

/*
It shows how I'll be using green to indicate Groovy code
*/


//This is a Scala comment

/*
It shows how I'll be using blue for Scala code
*/


//This is a Java comment

/*
It shows how I'll be using red if I ever need to show some Java code as well
*/

As you can see Groovy, Scala and Java all use the same style comments.

Monday, January 7, 2008

Playing With Scala

Recently I've started playing with Scala, a mixed OO/functional language for the JVM. It's biggest selling point is that it looks and feels a lot like a dynamic (ie scripting) language, but it's statically typed and therefore about as fast as Java code.

My biggest issue has been that a lot of the documentation about it has a very academic feel. One doc I read jumped almost straight into "Actors" (a rather advanced topic, especially for people who have never used Erlang) instead of introducing you to the language. I've been hearing that 2008 is the year Scala will take off - but I think that will only happen if there is "documentation for the rest of us".

Fortunately, that does appear to be coming. I broke down and bought the preprint of Programming in Scala, which goes some way towards decent documentation (though some of the examples do stray into academic territory). Even though it's still in an early form, I highly recommend it to anyone who might be interested in looking into Scala and who doesn't want to feel that they're back on a Computer Science course. My first look at Scala was a couple months back and the lack of decent docs put me off, I thought I'd give it another shot now that this book is out and I haven't dropped Scala yet.