Scala is a functional and object-oriented programming language that runs on the Java Virtual Machine. It features type inference, immutable collections, pattern matching, and functions as first-class values. The document provides an overview of Scala's features such as its static typing, traits for multiple inheritance, and case classes for value objects. It also demonstrates Scala's collections API and use of functions and pattern matching.
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
Scala 101 overview of features, patterns, collections and functions
1. Scala 101
Beyond Java: JVM FP, July 2014
Shai Yallin, Wix.com
audience.filter(_.usesJava).foreach { member =>
sayHi(member)
}
2. A short overview of Scala’s features
• A functional/OO programming language that runs on the JVM
• Everything is an object – no primitive types
• Functions are first-class members, every function is a value,
including what is usually an operator*
• Scala is statically-typed and supports type inference
* Some of these are synthetic functions
3. A short overview of Scala’s features
• Lambda expressions, closures and currying naturally
• Pattern matching
• Multiple inheritance through Traits
• Comprehensive collections library
4. Determinism via Immutability
Scala encourages everything to be immutable by default:
• Variables (vals)
• Collections
• Value objects (using Case Classes)
5. Better type safety
• Scala is statically and strongly typed; type inference keeps the
code lean and mean
• Stricter generics (in comparison to Java) provide better compile-
time checks
• Advanced features include structural types and type aliases
6. Case Classes
Good software engineering makes use of value objects. These need to
encapsulate the way they represent their state, to provide information hiding
and to be easy to maintain.
case class Person(
firstName: String,
lastName: String,
age: Int)
val authorOfPascal = Person("Niklaus", "Wirth", 80)
7. Case classes give us:
Factory methods Person("Niklaus", "Wirth", 80)
Hashcode authorOfPascal.hashCode == 1423465897
Equals authorOfPascal.equals(authorOfModula) == true
Copy val happyBirthday =
authorOfPascal.copy(age = 81)
Pattern matching Wait for it :-)
8. Collections
Some collection types:
• Seq (abstract ordered sequence)
• List (linked list)
• Set (yeah, it’s a set)
• Map (dictionary/hash)
A collection can be:
• Immutable / Mutable
• Synchronous / Parallel
9. Collections
With type inference, trivial to instantiate
val numbers = List(1, 2, 3)
val numbers2 = 1 :: 2 :: 3 :: Nil
val firstNames = Set("john", "mary", "muhammad”)
val caloriesPer100gr = Map(
"bacon" -> 541,
"fries" -> 312,
"lettuce" -> 15 )
12. Pattern matching
abstract class Gender
case object Male extends Gender
case object Female extends Gender
abstract class MaritalStatus
case object Single extends MaritalStatus
case object Married extends MaritalStatus
case object Divorced extends MaritalStatus
case object Widowed extends MaritalStatus
case class Person(
firstName: String, lastName: String, age: Int,
gender: Option[ Gender ], maritalStatus: Option[ MaritalStatus ])
13. Pattern matching
def salutation(p: Person) =
(p.gender, p.maritalStatus) match {
case (Some(Male ), _ ) => "Mr."
case (Some(Female), Some(Single) ) => "Miss"
case (Some(Female), None ) => "Ms."
case (Some(Female), _ ) => "Mrs."
case _ => "Unknown"
}
14. Functions as 1st-class members
val people = Set(
Person("Niklaus", "Wirth", 80),
Person("Anders", "Hejlsberg", 53),
Person("Martin", "Odersky", 55),
Person("Kenneth", "Thompson", 71))
val toddlers = people.filter(person: Person => person.age <= 3)
val minors = people.filter(person => person.age < 18)
val seniorCitizens = people.filter(_.age >= 65)
val isSenior = { person: Person => person.age >= 65}
val alsoSeniorCitizens = people filter isSenior
15. No nulls
Scala urges us to declare a possible return value using the Option[T] monad; an
option can be either Some(value) or None, and allows us to assume to it can
never be null. We can use collection semantics to consume an Option[T].
case class Person(
firstName: Option[String],
lastName: Option[String],
age: Option[Int])
val completelyUnknown = Person(None, None, None)
val anonymousAdult = Person(None, None, Some(25))
val agelessPerson = Person(Some("John”), Some("Doe"), None)
def ageOf(p: Person): Int = p.age // Won't compile!
def unsafeAgeOf(p: Person): Int = p.age.get // What if age is unknown?
def ageOrZero(p: Person): Int = p.age.getOrElse(0)
16. Multiple Inheritance with Traits
Similar (but better than) Java 8’s interfaces with default
methods, a Scala class can extend multiple Traits; in case
of collision, the right-most trait wins.
17. Example: Logging
import org.slf4j._
class ClassWithLogs {
private val log = LoggerFactory.getLogger(this.getClass)
def getNormalizedName(person: Person) = {
log.info("getNormalizedName called")
log.debug("Normalizing " + person)
val normalizedName = person.firstName.toUpperCase.trim
log.debug("Normalized name is: " + normalizedName)
normalizedName
}
}
x1000 classes
Eagerly evaluated
Statically typed – types are checked in compile time verses runtime
Strongly typed - each variable must have a concrete type
You get the best of both worlds – lean code like in dynamic languages and compile-time checking of adherence to structure
Type inference can slow down compilation – use with care
Structural types – the canonical example is closeable
A case class automatically makes its constructor arguments into vals. It also provides automatic equals, hashCode, toString methods and a very useful copy method which makes use of Scala’s named arguments (with defaults) feature.
We also see that case classes with proper default argument values are essentially test object builders, which saves us tons of code for test setup