Tuesday 6 May 2014

Why not Scala?

Scala is a very powerful and relatively new language that runs on the Java runtime - the "Java Virtual Machine" (JVM).  It's getting a lot of positive publicity, and it seems that it is gaining acceptance.  However, I'm really cautious about using it in any major project that is expected to be run and maintained for years.  Why?  There are many reasons, here are a few:

1. Complexity.

Scala is BIG language.  It combines object-orientation with functional styles and seems to include almost every possible thing that a programming language can do.  Some (far from all) the programming idioms currently in Scala (2.11.0) are:

declarative matching
case conditions
case classes
value classes
'for' comprehensions
xml embedding
dynamic method calls
generics
type range syntax
implicit methods
implicit classes
parameter placeholders
method references
special 'apply' method
currying
tuples
destructuring binds
traits
relative imports
package objects
named arguments
partially applied functions
lazy values
type aliasing
'operator' overloading

I have been programming and keeping up as best I can with programming for over 30 years, and, to be honest, I'm not sure what a few of these mean.

I do like many of these features: Implicit methods are a neat way to add functionality to existing classes by invisibly transforming such classes into new classes with new functions:

// Here is a silly example

class MyString {
def hello {
    println("hello")
}

implicit def toMyString(s: String) = new MyString

// Now "abcd".hello will print "hello" - effectively a new method .hello has been added to all strings where 'toMyString' is in scope.

However, this ability to tweak what code can do in hidden ways can lead to source that is extremely hard to follow.  Also, what can be done by a developer will end up being done by someone in a development team if that team is of any but the smallest size.  I know from experience.

2. What does Scala code do?

Here is an example of normal Scala code:

val x = myFunction()

What is going on here?  All we can see is a function call.  What kind of thing is 'x'?  What can it do?  The problem here is that Scala can infer types based on whatever is assigned to a value or variable.  You could write:

val x: String = myFunction()

Assuming, of course, myFunction returned a String, but this isn't necessary, and inference of type is standard practice.  But, if someone changes the return type of myFunction() at the point of its definition, you may have no idea that this has happened until a program has been run.  Look at the following code:

def getMyValue() = 1

val result = getMyValue() + getMyValue()
println(result)

When run, this will print "2"

Now, change the function:

def getMyValue() = "1"

When run, this will print "11"

Type inference is an example of where I think Java is doing things the right way.  Java insists on the type of a variable being described when the variable is defined:

String x = myFunction()

Any change in the result type of the function will be immediately caught at this point in the code by the compiler.  Java 8 allows for type inference to be used to reduce the amount of code needed to describe lambdas. 

Java 7:

Runnable code = new Runnable() { public void run() { System.out.println("run!"); }};

Java 8:

Runnable code = () -> System.out.println("run!");

That the lambda (the bit after "=") represents a Runnable, and the code should be seen as the body of a "run" method is inferred from the type of the variable "code". 

Java has the contract between function developer and function user explicit at the point of use.  This leads to clearer code.

3. Scala changes.

You can run positively ancient compiled Java code on the most modern Java VM.  a Java GUI program written from the early days of Java will still compile, and still run.  Java code doesn't die.

Scala is younger, and already a significant part of the language and libraries - the Actor system for parallel code - has been deprecated and replaced by a newer library, resulting in the need for migration work.  The new library (Akka) is a great system, but developers of significant and long-term projects really don't want to have to face this kind of change to keep up-to-date with bug-fixes and new features.  At least I don't!  Java's slow adoption of new idioms can be a real advantage for this kind of development, where stability is vital.

4. Who uses Scala?

In spite of it's frequent discussion, the actual use of Scala seems to be very small.  The TIOBE site monitors the volume of information on many Internet sites about different languages.  As expected, Java and C dominate.  Over recent years JavaScript and Objective C have grown hugely.  Scala is down below the decimal point of a percentage, somewhere between Fortran and Prolog. This does not directly indicate the quality of Scala, but it does show that getting Scala developers for a major project can be difficult and expensive.

It could be justifiably said that I'm not helping Scala with this attitude.  But I have to face the fact that software development for large and long-term projects isn't about taking a charitable approach to development languages and tools.  It's about delivering stability, reliability, and long-term maintainability.  It's about being justifiably dull!

No comments: