Could Scala the Best of Both Worlds?
Jul 12th 2020
By Robert Kirchner JR
Scala an Alternative to Java?
Scala is a high level language run on the JVM. It is known for the ability to be used in both object-oriented and functional styles. We will look at how it does as both.
The concept behind object oriented software is quite simple, all the data and business logic in your application, are encapsulated in small(hopefully), modular objects.
An entire program being an intricate web of these objects, carefully(hopefully) wired together working in harmony to transform your data, or whatever you need software for.
There are two characteristics that every object can have(your objects only have one or the other if your good), state and behavior. State being actual data, and behavior being some kind of functionality, be it manipulating data, or something else.
A common, and also good example, might be a user on social media. A user has state, a username, email address, status... And a user also has behaviors, logging in, commenting on a post.
This is probably the most common uses of programming objects. Typical mature object-oriented software languages have some very powerful advanced features. Inheritance, polymorphism, encapsulation and abstraction. Those being what are called the four pillars of object-oriented programming.
The Downsides of OOP
Data stored in memory, that can be manipulated, mutated and totally reassigned is said to be mutable. At first glance this seems quite natural for computer programs.
But in a world of multi-core CPUs, and multi-million user applications, mutability can have very negative effects.
Mutable data can easily become corrupt when being manipulated by more than one process at the same time.
Synchronization is the act of purposely de-parallelizing work in order to avoid corrupting data. As you can guess, this can significantly slow down software and lead to race conditions and deadlocks.
A side effect is when a method, or some operation doesn't return anything. It goes on its own and mostly mutates state. Side effects can cause undesired and unexpected behavior.
Functional programming is based behind the concept that software components are not objects but pure functions.
Pure functions are a mathematical concept in which a function or operation takes an input, and returns a single output. And given the same input, returns the same output. Pure functions do not have side-effects.
First Class Functions
In functional languages, functions can be returned and passed around like any other data variable.
Scala is an extremely complicated language that is run on the Java Runtime Environment. Scala is named to be a scalable language, that is strongly typed and can be used in both object-oriented and functional style.
OOP and Functional Features
Scala is a very popular choice for big data applications. This largely due to the focus on immutability. In Scala all data and collection types are immutable. This makes them safe from corruption in heavily multi-threaded environments.
Case Classes and Pattern Matching
Case classes are classes that only have a definition, and are perfect immutable data beans. Pattern matching, especially when used with case classes, is the ultimate replacement for the dreaded switch statement.
The notion of a static object is a perfectly static helper class. These are often used as companions and give functionality to case classes.
A trait is Scala's take of the ultimate abstract class. Traits can contain both method contracts, but also override-able concrete method implementations. A child class can implement multiple traits using the
with keyword, simulating multiple inheritance.
Another noteworthy feature of the language known as implicit parameters. Implicit parameters are special because the don't to be supplied during a function call, the interpreter goes off and finds one of the correct type.
Option and Named Arguments
The Scala option is a more robust and less verbose version of Java's optional(jdk8). Options can be used with patterns that prevent the dreaded null pointer exception. Named arguments can be a powerful tool, especially when paired with options and case classes. These patterns allow our immutable bean objects to possess default values, and using named arguments, we can declare them with only the arguments that are needed.
With functional parameters, Scala allows us to pass functions as parameters, and also the luxury of factory functions.
Scala, being a scalable and big data language, is heavily focused on multi-threading and parallel asynchronous processing. Scala's future allows our functions to return us a promise that we can call on when it is done processing.
Being a JVM language, Scala provides the ability for you to use nearly any Java library or features. With very little effort, you can use nearly any Java code, this helps makeup for some of the features that Scala lacks.
My Take on Scala
Scala gets most its popularity from the big data industry. But this does not make it a popular or high demand platform. Fact of the matter is that Scala peaked in popularity years ago. If you were to try to hire a team of Scala engineers, you might have a hard time filling your roster. Not too many people are practicing it.
Scala has been one of the, if not the most complex language I ever set out to learn
Inversion of Control
Not only does Scala have means for dependency injection, but lets not forget the Scala implicit. Dependency injection is usually a welcomed form of the inversion of control, but implicit s have the tendency to add a layer of mystery around how the interpreter decides what argument it will actually provide. If not executed perfectly, they can produce strange behavior that is hard to debug.
Since Scala runs on the JVM, it is compiled into Java byte code. It turns out this process is heavy duty, and can take an absurd amount of time. This tends to be very painful to engineers, especially when coupled with test driven development.
The simple build tool(SBT) can also make compile time painful. It tends to be very fragile, and most IDEs don't recognize its syntax as valid.
Type inference is one of the Scala features I actually do like. It helps Scala to accomplish it's goal of being less verbose than Java. But it is true that excessive use of type inference and syntactic sugar can make it difficult to read and maintain code.
Functional parameters can have the same effect. Functional parameters tend to make function/method definitions messy.
Scala lacks some basic functionality, forcing you to use Java as a means to perform low level tasks. Scala works best in an API or web service use case. Given Java's already rich network socket features, Scala is a good choice for this case.
Google can be a software engineers best friend. When faced with an obscure problem, you can typically find solutions on several of the many community support sites. Given the lack of popularity of Scala, this is not often the case.
Scala strives to be a scalable, robust and easy to read big data JVM language. Scala can be used in both object-oriented and functional flavors.
Their is a strong focus on immutability, that makes Scala a great candidate big data and concurrent processing applications.
Scala is very complex and difficult. It is not very popular, nor high demand, and this can make it hard to find developers for your project dev team.