Scala is an impressive language built on top of the Java runtime. Many of the irksome problems in Java have been fixed in Scala.
* The language is concise and eliminates unecessary semicolons, type definitions and braces. For simple programs, the code is clean and easy to read.
* Scala classes can use and extend Java classes and can be made to work the other way around though a bit awkward in some areas.
* More flexible imports including a way to rename a class on import
* Addition of an “object” keyword so you can define static instances more flexibly (this replaces static members)
* Improved flexibility of get/set methods, properties and fields
* Interfaces replaced by more flexible Traits which do a better job approximating multiple inheritance
* More flexible abstract definitions
A few other Java changes are maybe good or bad:
* == In scala means .equals in java and “eq” in scala means ==. So make it more accurate but slow down the default case by requiring a method call for each comparison.
* A file can contain more than one top-level class. I personally liked that feature of Java as it makes it quick for both people and compilers to find the definition of a class.
Scala brings functional programming concepts to the Java runtime: Java meets Erlang. Well executed but it may limit the usefulness of Scala in the business world and in contexts which require strongly engineered solutions – i.e. high performance, scalable, low footprint, low CPU, and code readability and maintainability. With functional programming, you can create more elegant, concise, and likely more provably correct program. But you give up control to the implementation of the various high level language operators.
Scala has features which make it a great language for building languages. It seems almost enough to build an uber language which embeds DSLs from various disciplines. You can do operator overloading, and the flexible syntax lets you define keywords, etc. The samples seem quite elegant and well designed. But with these complex ways of layering code, it becomes hard to reason about performance costs, and hard to pick up any arbitrary piece of code and understand what is going on quickly. Various separator characters are optional so you often omit parens, dots, etc. I like that in many ways but wonder how it works out day to day when trying to find syntax errors. The language also has quite a grab bag of non-standard syntactical short cuts, most of which you can not just pick up by reading the code.
I like how they implement traits. Each trait maps to a simple Java interface and generates a class with static methods if necessary. Each concrete class gets the trait member fields which are then access via methods of the same name. The methods in the Trait definitions turn into static methods which take a “this” parameter. They are called by methods added to the concrete class which includes the trait. This avoids copying all of the code into each class which includes a Trait.
I use this pattern to avoid the need for multiple inheritance myself so it is nice to see it done automatically. But if you implement everything as traits, you double the number of method calls in your system plus and code bloats up by all of the wrapper code generated in each concrete class. Fortunately a Trait with no members is treated just like an interface though so this is good as long as you know the implementation cost and how to avoid overusing it.
Scala does generate a lot of classes. It is not shy on generating code to make your code smaller. Code in the Java runtime means not just executable size but also init time overhead due to lazy linking. It seems like the one or two simple benchmarks I’ve seen show a slowdown of ~20% loss going from Java to Scala with a higher memory footprint but I suspect it is highly variable depending on the code. IMO, footprint and startup time are Java’s biggest weaknesses so it is too bad it is getting even worse with Scala.
That said, that number is much better than other languages built on top of Java. The one big thing they got right is to use the Java type system and they avoid creating an object for each property – in some cases at least. From reading the book and looking at the code it is still not clear to me when you are dealing with an “int” or an “Integer” since this is behind the scenes. That can make a huge performance difference so I wish those rules were more transparent.
All in all I do think the designers of Scala have done a tremendous job in advancing the state of the art of language design. Not that many people seem as concerned about these efficiency issues as I am so you may take them with a grain of salt. I look at the language as the main tool in my toolbox to make my business competitive so I want it to be as flexible and efficient as possible. So I’m stuck in C and Java as general purpose languages – C for runtime efficiency and Java for the best mix of runtime, reliability, maintainability.
So for me personally, I would consider using Scala for coding and presenting academic work (assuming I had time for the learning curve). I would not use it for a typical commercial project as it stands now. With discipline you could certainly use the nice parts of the language and build efficient, maintainable systems with a minimum of overhead. Unfortunately this means everyone creates their own discipline which means we don’t have a nice consistent way of using it so code is not as “developer portable”.
That said, there is reason to think I could be wrong on this last point. Ruby also seems like a flexible language that lets you implement languages on top of it. Like Scala, even someone who knows the Ruby core might pick up a piece of code and have no idea what it is doing till they learned all of the new operators introduced. Given Ruby’s success, maybe Scala will create sub-niches that use/invent particular language patterns that work very efficiently? I am not following that particular trend myself because I don’t think we need this plethora of languages – just a few really good ones that are as intuitive as possible. In particular, we need to standardize on core operators so we can start exchanging software parts more effectively. A language which defines many sub-dialects may being working against that goal. An open language is harder to learn and keep control of in an engineering setting.
I believe that Ruby succeeds because we haven’t got these core operators exactly right yet. Ruby makes adding new abstractions easy and intuitive and folks have put together some really good ones that really help developers be more productive. But though it may be a great proving ground for language abstractions it is not something you’d use to implement a strongly engineered system given its fully dynamic, interpretive nature. Just check the benchmarks.
Anyone think I’ve misjudged Scala? Any other languages you think I should be looking at?