Damien Gonot
Home Blog Notes About

Scala

Homepage / Notes / Computer Science / Programming Languages / Scala

Setup

Coursier

https://get-coursier.io/

The recommended way to install Scala and other tools (Ammonite, SBT…)

Ammonite

https://ammonite.io/

Modernized Scala REPL

https://ammonite.io/#RunningAmmoniteREPL

Scala Scripts

https://ammonite.io/#ScalaScripts

org-babel

In Doom Emacs, use amm (Ammonite) in #+begin_src code blocks and not scala

Make sure to have a ~/.ammonite/predef.sc file present

Language Features

Basics

println("hello, world!")
hello, world!

Strings

Concatenation

println("This is " + "a string")
This is a string

Numbers

println(1 + 1)
2

Ranges

println((1 to 5))
Range 1 to 5

Values

Values are immutable

val x = 1 + 1
x: Int = 2

Variables

Variables are similar to values, but can be re-assigned

var y = 1 + 1
y = y + 1
y: Int = 3

Blocks

Expressions can be combined together in blocks surrounded by curly braces {}

println({
  val z = 2
  z + 2
})
4

Functions

val addOne = (x: Int) => x + 1
println(addOne(5))
6
addOne: Int => Int = ammonite.$sess.cmd31$$$Lambda$1460/0x00000008011a87d8@39ff4421

Compose

val f = (s: String) => "(" + s + ")"
val g = (s: String) => "(" + s + ")"
f: String => String = ammonite.$sess.cmd80$$$Lambda$1704/0x00000008011e6ef0@55ba1297
g: String => String = ammonite.$sess.cmd80$$$Lambda$1705/0x00000008011e72a0@be4982d
println(f("in parentheses"))
(in parentheses)
val fComposeG = f compose g
fComposeG: String => String = scala.Function1$$Lambda$1709/0x00000008011e1c20@23afde4a
println(fComposeG("in double parentheses"))
((in double parentheses))

Methods

def add(x: Int, y: Int): Int = x + y
println(add(1, 2))
3
defined function add

Classes

class Greeter(prefix: String, suffix: String) {
  def greet(name: String): Unit =
    println(prefix + name + suffix)
}
defined class Greeter
val greeter = new Greeter("Hello, ", "!")
greeter.greet("Damien")
Hello, Damien!
greeter: Greeter = ammonite.$sess.cmd34$Greeter@7585531b

Case Classes

Immutable and compared by value (not reference like classes)

case class Point(x: Int, y: Int)
defined class Point
val point = Point(1, 2)
val anotherPoint = Point (1, 2)

println(point == anotherPoint)
true
point: Point = Point(x = 1, y = 2)
anotherPoint: Point = Point(x = 1, y = 2)

Objects

Singletons of their own classes

object IdFactory {
  private var counter = 0
  def create(): Int = {
    counter += 1
    counter
  }
}
defined object IdFactory
val newId: Int = IdFactory.create()
println(newId)
val newerId: Int = IdFactory.create()
println(newerId)
1
2
newId: Int = 1
newerId: Int = 2

Traits

trait Greeter {
  def greet(name: String): Unit =
    println("Hello, " + name + "!")
}
defined trait Greeter
class DefaultGreeter extends Greeter

class CustomizableGreeter(prefix: String, postfix: String) extends Greeter {
  override def greet(name: String): Unit = {
    println(prefix + name + postfix)
  }
}

val greeter = new DefaultGreeter()
greeter.greet("Damien")

val customGreeter = new CustomizableGreeter("How are you, ", "?")
customGreeter.greet("Damien")
Hello, Damien!
How are you, Damien?
defined class DefaultGreeter
defined class CustomizableGreeter
greeter: DefaultGreeter = ammonite.$sess.cmd46$DefaultGreeter@61f18402
customGreeter: CustomizableGreeter = ammonite.$sess.cmd46$CustomizableGreeter@63b187f

Data Structures

Collections

Tuples

Fixed number of elements. Heterogeneous (can hold multiple types). One-indexed.

val t = (1, "hello", Console)
t: (Int, String, Console.type) = (1, "hello", scala.Console$@fc807c1)

Above is syntactic sugar for:

val t = new Tuple3(1, "hello", Console)
t: (Int, String, Console.type) = (1, "hello", scala.Console$@fc807c1)
Accessing an element by index
println(t._2)
hello
Short form for tuples with only two elements
val short_t = 1 -> 2
short_t: (Int, Int) = (1, 2)
Swap elements for tuples with only two elements
println(short_t.swap)
(2,1)
Arrays

Mutable

val a = Array(1, 2, 3)
a: Array[Int] = Array(1, 2, 3)
Lists

Immutable

val l = List('a', 'b', 'c')
l: List[Char] = List('a', 'b', 'c')
Access by index
println(l(0))
a
Length
println(l.length)
3
Reverse
println(l.reverse)
List(c, b, a)
Map
println(List(1, 2, 3).map(_ * 2))
List(2, 4, 6)
Filter
println(List(5, 6, 7, 8, 9, 10).filter(_ % 2 == 0))
List(6, 8, 10)
Reduce Left
println(List(1, 2, 3).reduceLeft(_ + _))
6
Range to List
println((1 to 5).toList)
List(1, 2, 3, 4, 5)
Prepend
println(0 :: List(1, 2, 3))
List(0, 1, 2, 3)
Sets

Iterables that can't have duplicate elements

val provinces = Set("Quebec", "Ontario", "Manitoba")
provinces: Set[String] = Set("Quebec", "Ontario", "Manitoba")
val otherProvinces = Set("Alberta", "Manitoba", "British Columbia")
otherProvinces: Set[String] = Set("Alberta", "Manitoba", "British Columbia")
Intersect
println(provinces & otherProvinces)
Set(Manitoba)
Union
println(provinces | otherProvinces)
HashSet(Quebec, Manitoba, Ontario, Alberta, British Columbia)
Subset of
println(otherProvinces subsetOf provinces)
false
println(Set(1, 2) subsetOf Set(1, 2, 3, 4, 5))
true
Diff
println(otherProvinces diff provinces)
Set(Alberta, British Columbia)

Maps

val countries = Map("FR" -> "France", "CA" -> "Canada", "US" -> "United States")
countries: Map[String, String] = Map("FR" -> "France", "CA" -> "Canada", "US" -> "United States")
Access by key
val fr = countries("FR")
fr: String = "France"
Add key/value
val moreCountries = countries + ("DE" -> "Germany")
moreCountries: Map[String, String] = Map("FR" -> "France", "CA" -> "Canada", "US" -> "United States", "DE" -> "Germany")
Keys
val keys = countries.keys
keys: Iterable[String] = Set("FR", "CA", "US")
Values
val values = countries.values
values: Iterable[String] = Iterable("France", "Canada", "United States")
Remove element by key
val lessCountries = countries - "US"
lessCountries: Map[String, String] = Map("FR" -> "France", "CA" -> "Canada")

Scala.js

https://www.scala-js.org/ Scala compiled to JavaScript

Frameworks

Slinky

https://slinky.dev/

Write React apps in Scala just like you would in ES6

Laminar

https://laminar.dev/

Native Scala.js library for building user interfaces

scalajs-react

https://github.com/japgolly/scalajs-react

Facebook's React on Scala.js

Resources

Metals (Scala Language Server)

Functional Programming

Scalaz

Cats

Zio

https://zio.dev/ Type-safe, composable asynchronous and concurrent programming for Scala

"The red book"

https://www.manning.com/books/functional-programming-in-scala

Scala School

https://twitter.github.io/scala_school/