One nicety about a language with functional underpinnings is code brevity. Denser code, if you will. Fewer lines. Take, for instance, the following one-liner:
val neighbourNames = children.map(i => "AS"+i) ::: parents.map(i => "AS"+i)
This is code from the simulator I’m building right now. This one line is doing something relatively complex, but it does so in a way that, if you engage your brain, is still quite readable. This stuff can get dense in the same way that C code can get dense (if you know what you’re doing with your pointers), but with much less boilerplate.
For context, I have an Actor who, on initiation, receives (among other things,) two lists of Int_s representing parent and child nodes in the network I’m simulating. But actually, the actor doesn’t really care about whether a node it’s connected to is its parent or its child, it just wants a list of its _neighbours. Also, it doesn’t want the neighbour’s names in Int form, it wants neighbours names in the form “AS_num_”. Altering the form of the input to make the actor’s life easier would impact all sorts of other code elsewhere, so I want to munge the input within the actor.
In Java (or indeed, many other languages, but Java is what Scala is built upon, so I’ll stick with that), I guess I’d create a new ArrayList or Vector of Strings, and loop through each list appending the concatenation of (“AS” + each int) individually until I’d built the full list I want. There may be a more compact way in Java to do this, but I’m a child of Java 4, and lots of Java 5/6 features are still new to me. Granted, this isn’t the most arduous task in the world, but it’s a few lines that are just a hassle to write. I want to alter the contents of two lists in a predictable manner and join them together; the actual mechanics of this process are boring. I don’t care about the mechanics, and writing the mechanics of this is especially boring. Scala helps compact this process considerably, with the List.map() function.
The map function lets me transform each element in a given list, providing me a completely new list which I can play with. Map() is called on each input List: children.map(i => “AS”+i) and parents.map(i => “AS”+i); to understand the input to the map() function, it takes each element ‘i’, an Int, and maps it to ‘ASi’, creating a String in the process.
Both calls to map() create a new list with the input in the format I want, I just need to join the two together, and it’s the “:::” in the middle that does this. “:::” allows me to prepend children onto the front of parents. “:::” is actually a function of ‘parents’, so I could write this line as “parents.map(i => “AS”+i).:::(children.map(i => “AS”+i)), but that’s considerably uglier, and doesn’t quite match, conceptually at least, the output. The output is a List of Strings called neighbourNames. One line. Done. The end result? I have a List called neighbourNames which contains exactly what I want.
What’s neat is that Scala is statically typed, but tries to throw away the boilerplate evident in the likes of Java. It just knows that the output from each call to map() is a List of Strings, and that the concatenation of these is still a List of Strings. So I don’t need to tell it twice that I want “neighbourNames” to be a List of Strings; I’ve already told it.
I’m enjoying coding in Scala at the moment. I’m no functional programmer, so I reckon a lot of what I’m writing is Java-esque with Actors, but little things like this help tend toward a more functional mindset.