As requirements for computer programs get more complex, languages, too, must evolve. Every twenty years or so, the old paradigms become inadequate to handle the new demands for organizing and expressing ideas. New paradigms must emerge, but the process is not a simple one.
Each new programming paradigm ushers in a wave of programming languages, not just one. The initial language is often strikingly productive and wildly impractical. Think Smalltalk for objects or Lisp for functional languages. Then, languages from other paradigms build in features that allow people to absorb the new concepts while users can live safely within the old paradigm. Ada, for example, allowed some core object-oriented ideas such as encapsulation to exist within a procedural language. At some point, some hybrid language offers just the right practical bridge between the old paradigm and the new, such as a C++. Next, we see a commercially adoptable language, such as Java or C#. Finally, we see some mature, pure implementations of the new paradigm.
Scala is at least a bridge and maybe more. It offers tight integration into Java, offering a chance for people to protect their investment in many ways:
Scala runs on the Java virtual machine, so Scala can run side-by-side with existing deployments.
Scala can use Java libraries directly, so developers can leverage existing frameworks and legacy code.
Like Java, Scala is statically typed, so the languages share a philosophical bond.
Scala’s syntax is relatively close to Java’s, so developers can learn the basics quickly.
Scala supports both object-oriented and functional programming paradigms, so programmers can gradually learn to apply functional programming ideas to their code.
Some languages that embrace their ancestors go too far, extending the very limiting concepts that make the base inadequate. Although the similarities to Java are striking, Scala’s design has some significant departures that will serve its community well. These important improvements represent important departures from the Java language:
Type inference. In Java, you must declare the type of every variable, argument, or parameter. Scala infers variable types where possible.
Functional concepts. Scala introduces important functional concepts to Java. Specifically, the new language allows you to use existing functions in many different ways to form new ones. Concepts you’ll see in this chapter are code blocks, higher-order functions, and a sophisticated collection library. Scala goes far beyond some basic syntactical sugar.
Immutable variables. Java does allow immutable variables but with a rarely used modifier. In this chapter, you’ll see that Scala forces you to explicitly make a decision about whether a variable is mutable. These decisions will have a profound effect on how applications behave in a concurrent context.
Advanced programming constructs. Scala uses the foundational language well, layering on useful concepts. In this chapter, we’ll introduce you to actors for concurrency, Ruby-style collections with higher-order functions, and first-class XML processing.
Before we dive in, we should know about the motivations behind Scala. We’ll spend some time with the creator, focusing on how he decided to tie two programming paradigms together.
Martin Odersky, the creator of Scala, is a professor at École Polytechnique Fédérale de Lausanne (EPFL), one of two Swiss Federal Institutes of Technology. He has worked on the Java Generics specification and is the creator of the javac reference compiler. He is also the author of Programming in Scala: A Comprehensive Step-by-Step Guide [OSV08], one of the best Scala books available today. Here is what he had to say:
Why did you write Scala?
I was convinced that unifying functional and object-oriented programming would have great practical value. I was frustrated both by the dismissive attitude of the functional programming community toward OOP and by the belief of object-oriented programmers that functional programming was just an academic exercise. So, I wanted to show that the two paradigms can be unified and that something new and powerful could result from that combination. I also wanted to create a language in which I would personally feel comfortable writing programs.
What is the thing you like about it the most?
I like that it lets programmers express themselves freely and that it feels lightweight, yet at the same time gives strong support through its type system.
What kinds of problems does it solve the best?
It’s really general purpose. There’s no problem I would not try to solve with it. That said, a particular strength of Scala relative to other mainstream languages is its support of functional programming. So, everywhere a functional approach is important Scala shines, be that concurrency and parallelism or web apps dealing with XML or implementing domain-specific languages.
What is a feature that you would like to change, if you could start over?
Scala’s local type inference works generally well but has limitations. If I could start over, I’d try to use a more powerful constraint solver. Maybe it’s still possible to do that, but the fact that we have to deal with a large installed base makes it more difficult.
The buzz around Scala is growing, because Twitter has switched its core message processing from Ruby to Scala. The object-oriented features allow a pretty smooth transition from the Java language, but the ideas that are drawing attention to Scala are the functional programming features. Pure functional languages allow a style of programming that has strong mathematical foundations. A functional language has these characteristics:
Functional programs are made up of functions.
A function always returns a value.
A function, given the same inputs, will return the same values.
Functional programs avoid changing state or mutating data. Once you’ve set a value, you have to leave it alone.
Strictly speaking, Scala is not a pure functional programming language, just like C++ is not a pure object-oriented language. It allows mutable values, which can lead to functions with the same inputs but different outputs. (With most object-oriented languages, using getters and setters would break that rule.) But it offers tools that allow developers to use functional abstractions where they make sense.
The biggest problem facing concurrency-minded programmers in object-oriented languages today is mutable state, meaning data that can change. Any variable that can hold more than one value, after initialization, is mutable. Concurrency is the Dr. Evil to mutable state’s Austin Powers. If two different threads can change the same data at the same time, it’s difficult to guarantee that the execution will leave the data in a valid state, and testing is nearly impossible. Databases deal with this problem with transactions and locking. Object-oriented programming languages deal with this problem by giving programmers the tools to control access to shared data. And programmers generally don’t use those tools very well, even when they know how.
Functional programming languages can solve these problems by eliminating mutable state from the equation. Scala does not force you to completely eliminate mutable state, but it does give you the tools to code things in a purely functional style.
With Scala, you don’t have to choose between making some Smalltalk and having a little Lisp. Let’s get busy merging the object-oriented and functional worlds with some Scala code.