16+ Reasons to Why Learn Scala
Type Inference
Scala automatically infers(detects) the data type of an expression partially or fully. This means that we don’t need to declare it ourselves. Such a facility lets the programmer leave out type annotations while still allowing type checking.
So, how does this work? The compiler takes in the types of subexpressions, or those of atomic values like 42(Integer), true(Bool), and so on. It then aggregates this information, and then decides the type for an expression.
Read: Features of Scala
Singleton Object
Scala has no static variables or methods. Instead, it makes use of a singleton object. This is essentially a class with only a single object in the source file. We do this using the ‘object’ keyword, and not the ‘class’ keyword. For instance:
- object Main extends App {
- println("Hello, World!")
- }
Follow this link to know about Scala Singleton & Scala Companion Object
Immutability
In Scala, every variable you declare is immutable by default. You cannot change it. However, you can also explicitly declare it to be mutable. You can change the value of such a variable.
Immutable data helps us manage concurrency control, as you would imagine. Once we create an immutable object, we cannot modify its state.
Lazy Evaluation
We discussed this when we talked Scala vs Java. Lazy evaluation is when Scala delays evaluating an expression until it absolutely needs it. This is also called call-by-need.
This also avoids repeated evaluations. Lazy evaluation has the following benefits:
- We can define control flow as abstractions instead of primitives.
- We can define potentially infinite data structures.
- Lazy evaluation improves performance.
In Scala, we can have a lazy declaration:
lazy val images=getImages()
Read: Control Structures in Scala
Case Classes and Pattern Matching
A Scala case class is a regular one that is immutable by default, and is decomposable via pattern matching. All its parameters are immutable and public by default.
Defining a case class takes the keywords ‘case class’, an identifier, and a parameter list(can be empty).
case class Book(isbn: String)
val frankenstein = Book(“978-0486282114”)
Pattern matching lets us check a value against a pattern. You can use this in place of a switch-statement or a series of if-else statements in Java.
- import scala.util.Random
- val x: Int = Random.nextInt(10)
- x match
- {
- case 0 => "zero"
- case 1 => "one"
- case 2 => "two"
- case _ => "many"
- }
Concurrency Control
Scala’s standard library includes the Actor model. Using this, you can implement concurrency in your code. Apart from this, it also has a platform/tool, Akka. It is a separate, open-source framework providing for Actor-based concurrency. You can combine or distribute Akka’s actors with software transactional memory.
String Interpolation
Scala String interpolation is the act of evaluating a string literal, consisting of one or more placeholders, to yield a result. In this result, corresponding values replace the placeholders. This is a kind of template-processing.
Since version 2.10.0, Scala offers string interpolation. The three methods it offers for this are- s, f, and raw.
Read: Tuples in Scala
Higher-Order Functions
A higher-order function is one that takes another as a parameter, or returns it. This is possible in Scala only because it treats functions as first-class citizens.
- val salaries = Seq(20000, 70000, 40000)
- val doubleSalary = (x: Int) => x * 2
- val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000)
Here, map is a higher-order function.
Such functions also let us implement function compositions, and lambdas.
Read more about Scala Functions in detail
Traits
A trait in Scala is a type containing certain fields and methods. You can combine multiple traits.
To define a trait, we use the ‘trait’ keyword:
trait Greeter
- {
- def greet(name: String): Unit
- }
So, a trait is like a partially implemented interface. You can create a trait with abstract, and optionally, non-abstract methods.
Not yet convinced Why Scala is good for you? We have more reasons.
Rich Set of Collections
Scala has a huge set of collections in its library. This has classes and traits to help you collect data into a mutable or immutable collection. The scala.collection.mutable package holds all mutable collections. Making use of this package, you can add, remove, and update data. Likewise, the scala.collection.immutable package holds all immutable collections; they don’t let us modify data.
Read: Best Books for Scala
Functional
Scala is a language of a functional paradigm. It treats its functions as first-class citizens. This is why it also lets us create higher-order functions- ones that can return a function, or take it as a parameter. It also supports nesting of functions, and currying(translating evaluation of a function, that takes multiple arguments, into evaluating a sequence of functions, each with a single argument).
Object-Oriented
Scala supports object-oriented programming, purely. Every value is an object. We’ll have more on this later.
Statically-typed
In most cases, you won’t need to specify redundant type information to Scala; it will figure it out on its own. This is in relevance to type inference.
Read: Scala vs Java