For the past two years, my day-to-day programming language has been Scala. Scala is a hybrid language that combines the approaches of object-orientation and functional programming. You can treat Scala as a “Java.next” with minimal changes in your object-oriented mindset (the only thing that springs to mind is that Scala’s “companion objects” might seem like unnecessarily clunky replacements of Java’s “static” functionality). Even just as a drop-in replacement, I think most programmers would prefer Scala to Java: type inference saves finger-typing, and fields and class structure are a little clearer.
Scala is also a functional programming language. I’ve talked about functional programming many times over the years, but it continues to have an undeserved air of mystery around it. The low bar for a language to be “functional” is the support of functions as “first-class constructs.” Essentially, wherever you can have a value (on the right-hand of assignments, as the input or output of functions, etc.), you can have instead an anonymous block of code (if you like Greek, you can call them “lambda functions”). This turns out to be so convenient that every mainstream language either already supports or is moving toward such support; every language is, or will be soon, a “functional programming” language.
The greatest practical benefit of first-class functions is that, multiple times per day, instead of writing a for loop that iterates over elements of a collection to transform, filter or accumulate something, you just pass a small function to common collection-class functions such as (in the Scala world), map, filter and foldLeft. I cannot imagine a programmer not preferring the use of such functions: They are both clearer and more concise than loops.
Mutable state is when, after having been assigned a value once, a variable is reassigned a value. In a loop, for instance, the index variable is constantly reassigned. In a Lightbulb object, one might have a mutable isOn field that is reassigned in a switch() function. In a more functional program, you don’t have explicit index values (using, instead, higher-order and recursive functions to manipulate collections), and objects have few fields (a Lightbulb class wouldn’t have a switch() function but only on() or off() ). If you are a low-level programmer, it may help to think that functional programs have just the same amount of state, but they keep it all in stack frames rather than in a shared heap.
There’s a whole vocabulary relating to this philosophy: “idempotency,” “pure functions,” “side-effect-free,” etc., but the principle is very simple: Functions are easier to understand if they have fewer “moving parts.” Although the philosophy can be universally embraced (one can program functional assembly language), language features can help. In Scala, one can declare a symbol as being a “var”—a traditional variable that can be reassigned—but one is encouraged to use a “val,” which cannot be reassigned (similar to the “final” modifier familiar to Java programmers).
An effect of this philosophy is that functions should have all of their context explicit in the argument list: If you want a “toggle()” function on a Lightbulb, you don’t refer to a mutable field, you pass the old state in and return the new state. In Java, the functional signature might look like Boolean isOn(boolean wasOn). (Or you’d use the Flyweight pattern to return a shared but immutable on-or-off Lightbulb.)
Changing the argument list can be more cumbersome than using hidden state, but as I’ve argued in the past, the rise of unit testing has trained a generation of developers in the practice and shown them the advantages. On the other hand, a corollary of this is that the unit-testing suite of a functional module tends to “lock in” the API more firmly than with traditional object-oriented design. You can avoid such lock-in by having a single argument that is a bag of “context” values, but that strikes me as abandoning the governing philosophy. If explicitness is beneficial, stuffing explicitness away in a bag called “context” is cheating.
Just as every mainstream language has or is gaining first-class functions, most good developers have a sense that avoiding mutable state and explicit context are good things. So again, there’s nothing particularly magical about the syntax or semantics of Scala or any other functional language. They just facilitate these approaches.
And on the grand question of whether a sophisticated static type system such as Scala is a benefit or a hindrance compared to a flexible dynamic type system such as is found in Ruby? After two years of Scala on a mission-critical project that included some complex algorithms, a decently complex user interface, a decently complex database and all that jazz, I am ready to state my conclusion, which will be the subject of my next column.
Larry O’Brien is a technology consultant, analyst and writer. Read his blog at www.knowing.net.