Sunday, December 30, 2007

Scala: first impressions

I'm reading the prerelease of the Scala book, since I'm working for a heavily Java-invested organization now and programming in Java feels like running a race with cement shoes. Politically, Jython doesn't seem like an option; Scala might be an easier sell.

Here's some of my impressions going through the book.

Scala is a decent scripting language

[updated this section thanks to comments from anonymous, Jörn, and Eric.]

Getters and setters

One thing I despise in Java is the huge amount of wasted lines of code dedicated to getFoo and setFoo methods. Sure, your IDE can autogenerate these for you, but it still takes up lines in your editor and effort to mentally block them out when examining an unfamiliar class to determine what it does.

C# has Python-style properties, so in theory could be virtually free of this kind of boilerplate, since there is no syntactic difference between "foo.x = y" whether x is a raw field or a property. So, the right thing to do, which you'll see in Python code, is using a raw public field until you actually need extra logic, at which point you replace it with a property and nobody's code breaks.

But C# wasn't far enough removed from Java culturally so everyone writes boilerplate properties instead of boilerplate getters and setters. (I'm aware that in a compiled language like C# it makes sense to start with properties for classes in certain kinds of libraries but these make up a vanishingly small number of actual classes in the wild.)

This is a long way of saying that Scala's properties make a lot of sense given the audience they are targetting (Java programmers). Scala vars are automatically turned into properties (or getters and setters, if you prefer to think in terms of those). So even the most obstinate fan of boilerplate code has absolutely no reason to keep writing unnecessary getters and setters.

If you need to manually tweak your properties later, you can magically define a setter for "field" by naming a method "field_=". This seems a bit like a one-off hack rather than part of a well-designed system, but I can live with it. (Since parentheses are optional for a scala method taking no arguments, any no-argument method call is already syntactically indistiguishable from a raw field read.)

Scala doesn't know what it wants to be when it grows up, yet

Scala contains a lot of features from a lot of different influences, which means there's often competing styles to use; the young scala community hasn't yet decided which to emphasize. For instance, iteration vs traversal -- "for (item <- items)" vs "items.foreach" -- or even whether to leave out optional (inferred) type declarations.

Perhaps this is merely a failure of one book trying too hard to make scala be all things to all readers.

Random thoughts

Scala needs something like Python's enumerate function; if you want to loop each object in a collection but you need its index too, you have to do a manual for loop.

Using parenthesis for collection access ("array(0); map("foo"))") makes it unnecessarily difficult to tell if you're looking at a method call or a collection access.

The scala stdlib is not very google-able yet; if you don't know exactly the class you are looking for ahead of time, you probably won't find it. For example, when looking for a scala object that could iterate through lines in a file, I correctly guessed the scala.io package, but would never have bothered looking at Source until more googling turned it up in a blog entry.

Conclusion and disclaimer

This is long enough; I'll probably write more as I go through more of the book. Patterns and implicit conversions are particularly interesting.

I was attracted to scala while looking for a sane alternative to Java on the JVM and it looks like scala might "drag Java programmers halfway to Python," to paraphrase Guy Steele. And I'm happy to be corrected on anything I've written here.

Using foreach(print) instead of foreach(println) gives me a better result. Though again an example where Scala hasn't quite settled on one approach for a common problem.

I'm using the Scala Eclipse plugin which compiles the file on save, hiding the extra compile step from me. I agree that its hardly a "true" scripting language without that tool.

About the enumerate method: Yeah, I was missing that, too. Good thing with Scala is that you've got good chances to ask for that an actualy see it in one of the next releases, which isn't too far away. And until then you can just add it yourself with implicit.

With posts like yours odds are quite good that Google will have more to find in the future.

joe: that's why I said "it makes sense to start with properties for classes in certain kinds of libraries," specifically libraries for use by others. For libraries and other code for internal use only, that is, the vast majority of code, who cares if you have to recompile; you do it constantly anyway. :)

jorn: thanks for the comment; I hope the eclipse plugin stabilizes soon.

About scala as scripting language: Did you actually try to run a "script" on the command-line via "scala myscript.scala"? I've just tested it with a file that just contained println("Hello, world") and it works just fine. No need to provide an application object or a main method.

I started editing the post to explain that scala was really a decent language for short scripts after all, but couldn't figure out a way to read command-line arguments without a main method and scalac, so I ended up making only minor changes. Am I missing the obvious still? :)

I'm really a Scala fan (being tired of Java as pretty much everyone else). Yet I haven't used it much for pure scripting stuff (only when scripting involves using existing java libraries). In that case I feel much more comfortable with Ruby.Anyway your post is interesting and I would like to know how far we can push Scala to become a "total" scripting language.

> So even the most obstinate fan of boilerplate code has absolutely no reason to keep writing unnecessary getters and settersYou can also refer to case classes where you also have equality, hashcode and pattern matching for free.

>Scala needs something like Python's enumerate function; if you want to loop each object in a collection but you need its index too, you have to do a manual for loop.You have the method List.zipWithIndex which can help you

>Using parenthesis for collection access ("array(0); map("foo"))") makes it unnecessarily difficult to tell if you're looking at a method call or a collection access.This is indeed a method, the "apply" one (page 55 in the book)

What I would really like to have for 2008 is lightweight script environment with autocompletion (with a less than 2s startup time,...). I don't know how feasible this is but this would make Scala a very, very interesting scripting language over the dynamic ones.

Eric.

PS: "advertising" -> if you're interested, you can have a look to my scala project (http://code.google.com/p/specs). I'm very interested in getting as much as possible (constructive ;-)) feedback about it.

Hey jonathan, you commented on my blog about scala.io.Source and I see you're using it here. There is a small problem with it, it loads the entire file in memory. The code in my file was used to process some large files which caused an out of memory exception if I used scala.io.Source.

@ericI can't wait to try out specs, I'm a long time rubyist and a heavy user of rspec. Thanks for making specs :)

groovy was originally inspired by python and is definitely the closest lanaguage for you to pick up. may people wrote it off because early version were pretty poor, but a new crop of developers took it over and turned it on it's head. i honestly think it is *the* easiest language to read because it is less magical than ruby but less verbose than java. not unlike python ;-)

i'd take a look at some of the groovy samples and some of the grails videos to see it in action. i think it would be much easier to adopt than scala, many people are wondering why it doesn't become java7 seeing as it has the features that people have been asking for (closures, type inference..).

on javascript, i disagree that javascript is much like java at all, their constructs can be very different. also, rhino is interpreted on the JVM whereas groovy is compiled to byte code so it enjoys good performance in most situations (with some well documented exceptions).

i'm primarily a java guy that would like to code more python, but we still have to deploy to a JVM and I find groovy a better way forward than any other option right now.