ENGIMY.IO - CHEATSHEET
SCALA × QUICK REFERENCE
REFERENCE vScala 3.x

Scala Quick Reference

Everything you need day‑to‑day – functional, object‑oriented, and powerful.

Basic Syntax

// Entry point
@main def hello(): Unit =
    println("Hello, World!")

// Main with args
@main def main(args: String*): Unit =
    args.foreach(println)

// Semicolons are optional
val x = 5
val y = 10

// Comments
// Single line
/* Multi‑line */
/** Documentation */

Variables & Values

// Immutable (val) – preferred
val name = "Alice"
val age: Int = 25
val pi = 3.14159

// Mutable (var) – use sparingly
var counter = 0
counter = 1

// Lazy values
lazy val expensive = computeExpensive()

// Type inference
val x = 42          // Int
val y = 3.14        // Double
val z = "hello"     // String

// Type annotation
val score: Double = 95.5
val isActive: Boolean = true

Data Types

Basic Types
  • Int42
  • Double3.14
  • Float3.14f
  • Long42L
  • Booleantrue, false
  • Char'A'
  • String"Hello"
  • Unitvoid (())
  • Nothingbottom type
  • Anytop type
Compound Types
  • Array[T]Array(1,2,3)
  • List[T]List(1,2,3)
  • Vector[T]Vector(1,2,3)
  • Map[K,V]Map("a" -> 1)
  • Set[T]Set(1,2,3)
  • Option[T]Some(1), None
  • Either[A,B]Left("err")
  • Tuple(1, "Alice")

Type Aliases

type UserID = Int
type ValidationResult = Either[String, User]

Control Flow

if / else

if x > 0 then
    println("positive")
else if x == 0 then
    println("zero")
else
    println("negative")

// If as expression
val result = if x > 0 then "positive" else "negative"

match (Pattern Matching)

value match
    case 1 => println("one")
    case 2 => println("two")
    case 3 | 4 => println("three or four")
    case x if x > 10 => println("large")
    case _ => println("other")

// Match as expression
val result = value match
    case 1 => "one"
    case 2 => "two"
    case _ => "other"

Loops

// for
for i <- 1 to 5 do
    println(i)

// until (excludes upper bound)
for i <- 1 until 5 do
    println(i)  // 1,2,3,4

// with step
for i <- 1 to 10 by 2 do
    println(i)

// Iterate over collection
for item <- list do
    println(item)

// for with index
for (item, index) <- list.zipWithIndex do
    println(s"$index: $item")

// for comprehensions
val result = for
    x <- Some(10)
    y <- Some(20)
yield x + y  // Some(30)

// while
var i = 0
while i < 5 do
    println(i)
    i += 1

Functions

// Basic function
def add(a: Int, b: Int): Int = a + b

// Void function (Unit)
def log(message: String): Unit = println(message)

// Default parameters
def greet(name: String, greeting: String = "Hello") =
    s"$greeting, $name"

// Named arguments
greet(greeting = "Hi", name = "Alice")

// Variadic parameters
def sum(numbers: Int*): Int = numbers.sum

// Higher‑order functions
def applyTwice(f: Int => Int, x: Int): Int = f(f(x))

// Function literals (lambdas)
val square = (x: Int) => x * x
val square: Int => Int = x => x * x
val square = (x: Int) => x * x

// Anonymous function shorthand (_)
list.map(_ * 2)
list.filter(_ > 5)

// Partial functions
val square: PartialFunction[Int, Int] =
    case x if x >= 0 => x * x

Collections

List

// Create
val list = List(1, 2, 3, 4, 5)
val empty = Nil

// Operations
list.head          // first
list.tail          // rest
list(0)            // element at index
list.length
list.isEmpty
list.nonEmpty

// Add
0 :: list          // prepend
list :+ 6          // append (O(n))

// Transform
list.map(_ * 2)
list.filter(_ % 2 == 0)
list.reduce(_ + _)
list.fold(0)(_ + _)
list.flatMap(x => List(x, x * 2))
list.flatten
list.distinct
list.reverse
list.sorted
list.sortBy(-_)

// Take / Drop
list.take(3)
list.drop(2)
list.takeWhile(_ < 4)
list.dropWhile(_ < 4)

// Exists / Find
list.exists(_ > 3)
list.find(_ > 3)    // Option
list.forall(_ > 0)

// Fold
list.foldLeft(0)(_ + _)
list.foldRight(0)(_ + _)

// Zip
list.zip(List("a", "b", "c"))

Map

// Create
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)

// Operations
map("a")            // 1 (throws if missing)
map.get("a")        // Some(1)
map.getOrElse("d", 0)
map.keys
map.values
map.size

// Transform
map.mapValues(_ * 2)
map.filter(_._2 > 1)
map.map { case (k, v) => k -> v * 2 }

Option

// Create
val some = Some(42)
val none = None

// Operations
some.get           // 42 (dangerous)
some.getOrElse(0)
some.isDefined
some.isEmpty

// Transform
some.map(_ * 2)    // Some(84)
some.flatMap(x => Some(x * 2))
some.filter(_ > 10)
some.foreach(println)
some.orElse(Some(0))

// fold
some.fold(0)(_ * 2)

// for comprehension
for
    x <- some
    y <- Some(10)
yield x + y

Either

// Create
val right: Either[String, Int] = Right(42)
val left: Either[String, Int] = Left("Error")

// Operations
right.isRight
right.isLeft
right.map(_ * 2)
right.flatMap(x => Right(x * 2))
right.fold(
    left => s"Error: $left",
    right => s"Success: $right"
)

// For comprehension
for
    x <- Right(10)
    y <- Right(20)
yield x + y

Classes & OOP

Basic Class

class Person(val name: String, var age: Int) {
    def greet(): String = s"Hello, $name"

    def isAdult: Boolean = age >= 18
}

// Usage
val person = Person("Alice", 25)
println(person.greet())

Case Classes

// Auto‑generated: toString, equals, hashCode, copy, apply
case class User(id: Int, name: String, email: String)

val user1 = User(1, "Alice", "alice@example.com")
val user2 = user1.copy(id = 2)

// Pattern matching on case classes
user match
    case User(id, name, _) => println(s"$id: $name")
    case _ => println("unknown")

Objects (Singletons)

object AppConfig {
    val version = "1.0.0"
    def printVersion() = println(version)
}

Companion Objects

class User(val id: Int, val name: String)

object User {
    def apply(id: Int, name: String): User = new User(id, name)
    def fromString(s: String): User =
        s.split(",") match
            case Array(id, name) => User(id.toInt, name)
}

Traits (Interfaces)

trait Greetable {
    def name: String
    def greet(): String = s"Hello, $name"
}

// Extending trait
class User(val name: String) extends Greetable

// Mixing traits
trait Loggable {
    def log(msg: String): Unit = println(s"[LOG] $msg")
}
class User extends Greetable with Loggable

Inheritance

class Animal(val name: String):
    def speak(): String = s"$name makes a sound"

class Dog(name: String, val breed: String) extends Animal(name):
    override def speak(): String = s"$name barks"

Abstract Classes

abstract class Shape:
    def area(): Double

class Circle(val radius: Double) extends Shape:
    override def area(): Double = math.Pi * radius * radius

Pattern Matching

// Constant patterns
x match
    case 1 => "one"
    case 2 => "two"

// Variable patterns
x match
    case y if y > 0 => "positive"
    case _ => "non‑positive"

// Constructor patterns (case classes)
user match
    case User(id, _, _) => s"User $id"

// Tuple patterns
tuple match
    case (a, b) => s"$a, $b"

// List patterns
list match
    case head :: tail => head
    case Nil => 0

// Type patterns
value match
    case s: String => s"String: $s"
    case i: Int => s"Int: $i"

Implicits

// Implicit parameter
def greet(name: String)(implicit greeting: String) =
    s"$greeting, $name"

implicit val defaultGreeting = "Hello"
greet("Alice")  // "Hello, Alice"

// Implicit conversion (use carefully!)
implicit def stringToInt(s: String): Int = s.toInt
val x: Int = "42"  // 42

// Implicit class (extension methods)
implicit class StringOps(s: String) {
    def isEmail: Boolean = s.contains("@") && s.contains(".")
}

"alice@example.com".isEmail  // true

Futures (Concurrency)

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.*

// Create Future
val future = Future {
    Thread.sleep(1000)
    42
}

// Transform
future.map(_ * 2)
future.flatMap(x => Future(x * 2))
future.filter(_ > 10)

// Await (blocking)
import scala.concurrent.Await
val result = Await.result(future, 5.seconds)

// For comprehension
for
    x <- Future(10)
    y <- Future(20)
yield x + y

// Recover
future.recover {
    case e: Exception => 0
}

Error Handling

// try / catch / finally
try
    val result = 10 / 0
catch
    case e: ArithmeticException => println("Division by zero")
    case e: Exception => println(s"Error: $e")
finally
    println("Always runs")

// Either for error handling
def divide(a: Int, b: Int): Either[String, Int] =
    if b == 0 then Left("Division by zero")
    else Right(a / b)

divide(10, 2) match
    case Right(result) => println(result)
    case Left(err) => println(err)

// Option for nullable values
def toInt(s: String): Option[Int] =
    try Some(s.toInt)
    catch case _ => None

Common Built‑in Functions

String
  • s.length
  • s.toUpperCase
  • s.toLowerCase
  • s.trim
  • s.split(",")
  • s.contains("sub")
  • s.startsWith("pre")
  • s.endsWith("suf")
  • s.replace("old", "new")
  • s.substring(0, 3)
Math
  • math.abs(x)
  • math.ceil(x)
  • math.floor(x)
  • math.round(x)
  • math.pow(x, y)
  • math.sqrt(x)
  • scala.util.Random.nextInt(100)
  • scala.util.Random.between(1, 100)

Best Practices

  • Use val over var – prefer immutability.
  • Use case classes – for data models.
  • Use pattern matching – instead of long if/else chains.
  • Use Option – instead of null.
  • Use Either – for error handling.
  • Use for comprehensions – for sequential operations.
  • Avoid mutable state – use immutable collections.
  • Use collection functions – map, filter, fold, etc.
  • Use traits – for modular design.
  • Use implicits – sparingly and with caution.
  • Use Futures – for asynchronous code.
  • Follow the style guide – use 2 spaces for indentation.
  • Use scalafmt – for code formatting.
  • Use sbt – for build and dependency management.
📌 Quick Reference
Variables: val (immutable), var (mutable)
Functions: def name(args): ReturnType = body
Collections: List, Map, Set, Option, Either
Pattern matching: match with case
For comprehension: for ... yield
Case classes: Immutable data holders with auto‑generated methods
Traits: Interfaces with default implementations
Implicits: Implicit parameters, conversions, classes
Futures: Future for async, Await.result for blocking
Error handling: Option, Either, try/catch
← Back to All Cheatsheets