// SCALARS — LANGUAGE REFERENCE

scalars v0.1.4 · Scala on fusevm · lex/parse → AST → bytecode → Cranelift JIT · no bespoke VM, no JVM · MIT · in active development

Docs GitHub

>_LANGUAGE REFERENCE

Every name the current scalars build resolves, grouped by chapter: reserved keywords, declaration forms and modifiers, comprehensions and ranges, pattern forms, collection constructors, the sequence and map method surfaces, String / Int / Double / Boolean methods, tuples and records, function values, scala.math, the throwable hierarchy, the operators, and Predef with the string interpolators. Each entry carries a signature and a runnable example. This page is generated from the reference corpus (src/corpus.rs) by the gen-docs binary, which is also what editor completion and hover read, so the page never drifts from the runtime. Keywords mirror lexer.rs; declarations and patterns mirror parser.rs; the method surfaces, scala.math, throwables and operator lowering mirror src/host.rs and src/compiler.rs. Where behaviour diverges from Scala on the JVM, the entry says so.

Keywords

# object

Declare a singleton object. scalars runs the object whose body `extends App` or whose `def main(args: Array[String])` it finds; any other object is an ordinary namespace whose members are reached as `Name.member`.

object Name [extends App] { … }
object Counter { var n = 0; def bump(): Int = { n += 1; n } }
object T extends App { println(Counter.bump()) }   // => 1

# def

Define a method. A `def` inside a block is scoped to that block, may shadow an outer one, and is lambda-lifted by `resolve.rs` before compilation, so it may close over the enclosing locals.

def name([p: T, …])[: R] = expr
def sq(x: Int): Int = x * x
println(sq(7))   // => 49

# val

An immutable binding. The compiler rejects a later assignment to the same name at compile time rather than at run time.

val name[: T] = expr
val x = 41
println(x + 1)   // => 42

# var

A mutable binding, reassignable with `=` or any of the compound assignments `+=` `-=` `*=` `/=` `%=`.

var name[: T] = expr
var n = 0
n += 5
println(n)   // => 5

# if

Conditional branch, and an expression: its value is the taken branch's. With no `else` the missing branch is Unit.

if (cond) expr [else expr]
println(if (1 < 2) "yes" else "no")   // => yes

# else

The fallback branch of an `if`. It binds to the nearest unmatched `if`.

if (cond) expr else expr
println(if (false) 1 else 2)   // => 2

# while

Loop while the condition holds. A `while` is a statement — its value is Unit, so it is not usable as an operand.

while (cond) { … }
var i = 0
while (i < 3) { i += 1 }
println(i)   // => 3

# for

Comprehension over a range or a collection, with optional `if` guards. Without `yield` the body runs for effect; with `yield` its results are collected. A counted integer range compiles to a dedicated loop rather than a materialized collection.

for (x <- gen [if guard]) [yield] body
for (i <- 1 to 3 if i > 1) print(i)   // => 23

# extends

Name a supertype: its fields and concrete methods are inherited and its constructor receives the `extends P(args)` arguments. `extends App` instead makes the object body the program entry point.

class C(…) extends P(args) [with T …]
class A(val n: Int)
class B(m: Int) extends A(m)
println(new B(2).n)   // => 2

# new

Construct an instance of a user `class`, of a built-in throwable, or of a mutable collection (`new ListBuffer[Int]()`). `new Array[T](n)` is the one form whose type argument is load-bearing — it picks the zero value the array is filled with.

new Class(args)
class P(val n: Int)
println(new P(2).n)   // => 2

# return

Early return from a `def`, exiting before the body's last expression. Only valid inside a method body.

return expr
def f(x: Int): Int = { if (x < 0) return 0; x * 2 }
println(f(-1))   // => 0

# match

Match a scrutinee against `case` arms in order; the first arm whose pattern matches (and whose guard holds) supplies the value. No arm matching raises `scala.MatchError`. `match` binds looser than every operator, so it wraps the whole preceding expression.

expr match { case pat [if guard] => expr; … }
println(2 match { case 1 => "one"; case n => "n=" + n })   // => n=2

# case

Introduce a `match` arm, a `catch` handler, a `{ case … }` function literal, or — before `class`/`object` — a case declaration with derived `toString`, `equals`, `hashCode`, `copy` and `unapply`.

case pat [if guard] => expr
case class P(x: Int)
println(P(1))   // => P(1)

# try

Run a body with handlers. Its value is the body's, or the matching handler's. `try`/`catch`/`finally` lower to the `EXC_*` builtin family rather than to native unwinding.

try { … } [catch { case … }] [finally { … }]
println(try { 1 / 0 } catch { case _: ArithmeticException => -1 })   // => -1

# catch

The handler block of a `try`. Arms are patterns — `case e: T`, `case e`, with an optional guard — and a typed arm walks the modelled JVM throwable hierarchy.

catch { case e: T [if guard] => expr; … }
try { "z".toInt } catch { case e: NumberFormatException => println(e.getMessage) }   // => For input string: "z"

# finally

A block that runs on both the normal and the exceptional exit of a `try`, before an unhandled exception continues unwinding. Its own value is discarded.

try { … } finally { … }
try { println(1) } finally { println("done") }   // => 1 then done

# throw

Raise an exception. It is an expression of type `Nothing`, so it may stand in operand position — the right of an `else`, the body of a `case` arm.

throw expr
def pick(b: Boolean): Int = if (b) 7 else throw new RuntimeException("no")
println(pick(true))   // => 7

# true

The Boolean true literal.

true
println(true && false)   // => false

# false

The Boolean false literal.

false
println(false || true)   // => true

# null

The null reference literal. It prints as `null`, and it is what a no-argument throwable's `getMessage` answers.

null
val x = null
println(x)   // => null

Declarations and Modifiers

# class

Declare a class. It is a soft keyword — the lexer hands it back as an identifier and the parser gives it meaning in declaration position, so a class may only be declared at the top level, not inside a method body. A `val` constructor parameter becomes a readable field.

class Name(params) [extends P(args)] [with T …] { members }
class Box(val n: Int) { def twice = n * 2 }
println(new Box(3).twice)   // => 6

# trait

Declare an abstract type to mix in: abstract members (`def f: Int`) alongside concrete ones. A trait cannot be instantiated, and takes no constructor parameters.

trait Name { members }
trait S { def area: Int; def show: String = "a=" + area }
class C(r: Int) extends S { def area = r * r }
println(new C(3).show)   // => a=9

# case class

A class with derived members: `toString` renders `Name(f0,f1)` over the primary-constructor parameters only, `equals`/`==` compare structurally, `hashCode` is the MurmurHash3 product hash, `copy` takes named updates, and the name works as a constructor pattern and as a factory without `new`.

case class Name(params)
case class P(x: Int, y: Int)
println(P(1, 2).copy(y = 9))   // => P(1,9)

# case object

A singleton with case-class semantics. It prints as its bare name rather than `Name()`, which is how the built-in `None` renders.

case object Name [extends P]
sealed trait Shape
case object Origin extends Shape
println(Origin)   // => Origin

# override

Replace a supertype's concrete member. The call dispatches on the receiver's runtime class, not on the declared type of the reference.

override def f = expr
class A { def f = 1 }
class B extends A { override def f = 2 }
val a: A = new B()
println(a.f)   // => 2

# with

Mix another supertype into a `class` or `trait`. Method lookup is the class itself, then its parents right to left — the linearization order.

class C extends P with T1 with T2
trait L { def tag = "L" }
class R extends L
println(new R().tag)   // => L

# super

Call the supertype's implementation of a member, skipping this type in the linearization. Useful for wrapping rather than replacing an inherited method.

super.member
class A { def f = "a" }
class B extends A { override def f = super.f + "b" }
println(new B().f)   // => ab

# this

The receiver inside a class or trait body. `this.f` and a bare `f` name the same field; `this` is passed implicitly to every method call on an instance.

this[.member]
class Box(val n: Int) { def twice: Int = this.n * 2 }
println(new Box(3).twice)   // => 6

# sealed

A soft keyword accepted and skipped: it documents that a hierarchy is closed, but this frontend performs no exhaustiveness analysis, so a non-exhaustive `match` over a sealed type is a run-time `MatchError` rather than a compile-time warning.

sealed trait Name
sealed trait Shape
case class Circle(r: Int) extends Shape
val s: Shape = Circle(2)
println(s match { case Circle(r) => r * r })   // => 4

# abstract

A member modifier accepted and skipped. The runtime is dynamically typed, so an unimplemented member is only an error when it is actually called.

abstract def f: T
abstract class Base { def name: String }

# final

A member modifier accepted and skipped; it carries no run-time meaning here, since dispatch is by the receiver's class either way.

final def f = expr
class A { final def tag = "a" }

# private

A member modifier accepted and skipped. Every member is reachable at run time — visibility is not enforced.

private val x = expr
class A { private val secret = 1; def peek = secret }

# protected

A member modifier accepted and skipped, like `private`; access control is not modelled.

protected def f = expr
class A { protected def helper = 1 }

# implicit

Accepted as a modifier and skipped. There is no implicit resolution in this frontend — an implicit parameter is never supplied automatically, and an implicit conversion never fires.

implicit val x = expr
class A { implicit val scale = 2 }

# lazy

Accepted as a modifier and skipped, so a `lazy val` is initialized eagerly at its declaration rather than on first use. A `lazy val` whose initializer diverges therefore diverges here.

lazy val x = expr
def f = { lazy val z = 1; z }
println(f)   // => 1

# package

A package prologue line. It is parsed and skipped: names are not namespaced, and the object entry point is found regardless of the declared package.

package name[.name…]
package demo
object T extends App { println(1) }   // => 1

# import

An import prologue line, tolerated and ignored. Imports are not tracked, so `scala.math` members are reachable through `math`/`Math` whether or not they were imported.

import path[._]
import scala.math._
object T extends App { println(math.sqrt(16.0)) }   // => 4.0

# App

The mixin whose object body scalars runs directly as the program, with no `main` method needed.

object Name extends App { … }
object T extends App { println("hi") }   // => hi

# main

The entry method scalars looks for when no object `extends App`. Its parameter list is accepted but not populated — command-line arguments are not passed through.

def main(args: Array[String]): Unit = { … }
object T { def main(args: Array[String]): Unit = { println(0) } }   // => 0

Comprehensions and Ranges

# yield

Collect a `for` comprehension's body for each binding instead of running it for effect. A range generator yields a `Vector`; a collection generator yields the source's own kind.

for (x <- gen) yield expr
println(for (x <- List(1, 2, 3) if x > 1) yield x * 10)   // => List(20, 30)

# <-

The generator arrow of a `for` comprehension: bind the name on the left to each element produced on the right.

for (name <- generator) …
for (x <- List("a", "b")) print(x)   // => ab

# until

Exclusive range bound: `a until b` is the values a … b-1, usable as a `for` generator or as a first-class `Range` value.

a until b: Range
for (i <- 0 until 3) print(i)   // => 012

# to

Inclusive range bound: `a to b` is the values a … b, usable as a `for` generator or as a first-class `Range` value.

a to b: Range
println((1 to 3).sum)   // => 6

# by

Range step. A negative step counts down; a zero step raises `IllegalArgumentException: step cannot be 0.`.

range by step: Range
for (i <- 10 to 1 by -3) print(i + " ")   // => 10 7 4 1

# Range

The lazy integer sequence `a to b` / `a until b` builds. It prints its bounds rather than its elements, and any transforming method over it answers a `Vector` — Scala's `IndexedSeq` result for a range.

(a to b): Range
println(1 to 4)               // => Range 1 to 4
println((1 to 4).map(_ * 2))   // => Vector(2, 4, 6, 8)

Pattern Matching

# case _

The wildcard pattern: matches anything and binds nothing. As the last arm it makes a `match` total, so no `MatchError` can escape.

case _ => expr
println(9 match { case 1 => "one"; case _ => "other" })   // => other

# case x

The binding pattern: matches anything and binds it to the name. In a `catch` arm this is the catch-all that also takes a thrown user object outside the modelled throwable hierarchy.

case name => expr
try { throw new RuntimeException("x") } catch { case e => println(e) }   // => java.lang.RuntimeException: x

# case x: T

The type pattern: a run-time test against the registered class hierarchy, then a bind. For a throwable it walks the modelled JVM parent chain — which is why `case e: Exception` catches an `IllegalArgumentException`.

case name: Type => expr
println(try { 1 / 0 } catch { case _: ArithmeticException => -1 })   // => -1

# case C(a, b)

The constructor pattern: match a case-class instance and bind its primary-constructor fields positionally. Nested patterns and `_` holes are allowed. This is implemented despite the parser's own note that it is not.

case Class(pat, …) => expr
case class P(x: Int, y: Int)
println(P(1, 2) match { case P(a, b) => a + b })   // => 3

# case (a, b)

The tuple pattern: destructure a `TupleN` positionally. This is what `{ case (k, v) => … }` uses over a `Map`'s entries and over a `zip` result.

case (pat, …) => expr
println(Map("a" -> 1).map { case (k, v) => k + v })   // => List(a1)

# case 1

The literal pattern: an `Int`, `Double`, `String`, `true`, `false` or `null` literal, matched by value equality.

case literal => expr
println("b" match { case "a" => 1; case "b" => 2 })   // => 2

# case x if g

A guarded arm: the pattern must match and the guard must be true. The guard sees the pattern's bindings, and a failing guard falls through to the next arm.

case pat if cond => expr
println(4 match { case n if n % 2 == 0 => "even"; case _ => "odd" })   // => even

# isInstanceOf

Run-time type test against the registered class hierarchy — the same test `case x: T` performs. Its type argument is one of the two that survive parsing.

x.isInstanceOf[T]: Boolean
trait S
class C extends S
println(new C().isInstanceOf[S])   // => true

# asInstanceOf

Type ascription. The runtime is dynamically typed, so this is a no-op that answers the receiver unchanged — it never raises `ClassCastException`.

x.asInstanceOf[T]: T
val x: Any = 5
println(x.asInstanceOf[Int])   // => 5

Collection Constructors

# List

The default immutable sequence, and the kind most conversions answer. Built by `MAKE_LIST`; indexed with `xs(i)`, extended with `::`, and the receiver of the whole sequence-method surface.

List(e, …): List[A]
println(List(3, 1, 2).sorted.map(_ * 2))   // => List(2, 4, 6)

# Seq

An alias for `List` — `Seq(1, 2)` builds and prints as a `List`, as it does in Scala 3.

Seq(e, …): List[A]
println(Seq(1, 2))   // => List(1, 2)

# Vector

The immutable indexed sequence. It carries the same method surface as `List`, prints as `Vector(…)`, and is what a range comprehension yields.

Vector(e, …): Vector[A]
println(Vector(1, 2, 3).map(_ + 1))   // => Vector(2, 3, 4)

# IndexedSeq

An alias for `Vector`, matching Scala 3's default `IndexedSeq` implementation.

IndexedSeq(e, …): Vector[A]
println(IndexedSeq(1, 2))   // => Vector(1, 2)

# Set

The immutable set: duplicates dropped, first occurrence winning. Up to four elements it prints in insertion order as `Set(…)`; beyond four it becomes a CHAMP hash trie printed as `HashSet(…)` in trie order, which is Scala's own behaviour.

Set(e, …): Set[A]
println(Set(3, 1, 2))         // => Set(3, 1, 2)
println(Set(9, 3, 1, 2, 7))   // => HashSet(1, 9, 2, 7, 3)

# HashSet

The hashed set, reachable as `new mutable.HashSet[T]` for the mutable one. An immutable `Set` prints under this name automatically once it outgrows four elements.

new mutable.HashSet[T]()
val s = new mutable.HashSet[Int]()
s += 1
println(s)   // => HashSet(1)

# Map

The immutable map of `k -> v` pairs. Up to four entries it prints in insertion order as `Map(…)`; beyond four it is a CHAMP trie printed as `HashMap(…)` in trie order.

Map(k -> v, …): Map[K, V]
val m = Map("a" -> 1, "b" -> 2)
println(m.getOrElse("z", 0))   // => 0

# HashMap

The hashed map, reachable as `new mutable.HashMap[K, V]`. An immutable `Map` prints under this name once it outgrows four entries, and `groupBy` always answers one.

new mutable.HashMap[K, V]()
println(List(1, 2, 3).groupBy(_ % 2))   // => HashMap(0 -> List(2), 1 -> List(1, 3))

# Array

The mutable fixed-length sequence: `Array(a, b)` or `new Array[T](n)` for a zero-filled one. `a(i)` reads and `a(i) = v` writes; its `hashCode` is identity, as on the JVM.

Array(e, …): Array[A]   |   new Array[T](n): Array[T]
val a = Array(1, 2, 3)
a(1) = 9
println(a.mkString(","))   // => 1,9,3

# new Array[T](n)

Allocate a zero-filled array of length `n`. The type argument is load-bearing — it picks the fill value: `0` for the integral types, `0.0` for `Double`/`Float`, `false` for `Boolean`, `null` otherwise. A negative `n` raises `NegativeArraySizeException`.

new Array[T](n: Int): Array[T]
val a = new Array[Int](3)
println(a.mkString(","))   // => 0,0,0

# Nil

The empty `List`, and the tail a `::` chain terminates with.

Nil: List[Nothing]
println(1 :: 2 :: Nil)   // => List(1, 2)

# Tuple

A fixed-length heterogeneous group, written `(a, b, …)`. It prints comma-joined with no spaces, its `hashCode` is the MurmurHash3 product hash, and it is the element shape of `zip`, `groupBy` and a `Map`'s entries.

(a, b, …): TupleN
println((1, "x"))   // => (1,x)

# Some

The present `Option`, built by `find`, `headOption`, `collectFirst`, `lift`, `Map.get`, `put` and `remove`. It is a case-class record: destructure it with `case Some(v)` or read `.value`. Scala's `get`/`getOrElse`/`map` on `Option` are not implemented.

Some(v): Some[A]
println(List(1, 2).find(_ > 1))          // => Some(2)
println(List(1, 2).find(_ > 1).value)   // => 2

# None

The absent `Option`, a case object that prints as its bare name. Match it with `case None`.

None
println(List(1, 2).find(_ > 9))   // => None

# mutable

The `scala.collection.mutable` package prefix: `mutable.ListBuffer`, `mutable.ArrayBuffer`, `mutable.Queue`, `mutable.Stack`, `mutable.ArrayDeque`, `mutable.Set`, `mutable.Map`, `mutable.LinkedHashSet` and `mutable.LinkedHashMap`. It is recognized whether or not it was imported, and `scala.collection.mutable.X` is accepted too.

mutable.Kind(e, …)
val s = mutable.Set(1, 2, 3)
s += 4
println(s)   // => HashSet(1, 2, 3, 4)

# ListBuffer

The growable mutable sequence. It accepts `+=`, `++=`, `-=`, `append`, `prepend`, `insert`, `remove`, `clear` and `b(i) = v` alongside every read-only sequence method, and a derived collection is another `ListBuffer`.

mutable.ListBuffer(e, …): ListBuffer[A]
val b = mutable.ListBuffer(1, 2)
b += 3
println(b)   // => ListBuffer(1, 2, 3)

# ArrayBuffer

The growable indexed mutable sequence. It takes the same mutators and combinators as `ListBuffer` and prints as `ArrayBuffer(…)`. Both names are usable unqualified.

mutable.ArrayBuffer(e, …): ArrayBuffer[A]
val a = mutable.ArrayBuffer(1, 2)
a ++= List(3, 4)
println(a)   // => ArrayBuffer(1, 2, 3, 4)

# Buffer

An alias for `ArrayBuffer`, matching Scala's default `Buffer` implementation.

mutable.Buffer(e, …): ArrayBuffer[A]
println(mutable.Buffer(1, 2))   // => ArrayBuffer(1, 2)

# mutable.Set

The mutable hash set. Unlike the immutable one it prints `HashSet(…)` at every size, in its flat table's iteration order — the table growth the JVM implementation performs is replayed so the order matches.

mutable.Set(e, …): mutable.Set[A]
val s = mutable.Set(1, 2)
println(s.add(3))   // => true
println(s)          // => HashSet(1, 2, 3)

# mutable.Map

The mutable hash map. It prints `HashMap(…)` at every size and adds `put`, `update`, `getOrElseUpdate`, `remove` and `clear` to the read-only map surface.

mutable.Map(k -> v, …): mutable.Map[K, V]
val m = mutable.Map("a" -> 1)
m("b") = 2
println(m)   // => HashMap(a -> 1, b -> 2)

# Queue

The growable mutable FIFO. `enqueue` appends, `dequeue` takes the head and answers it, `front` peeks. `+=` is `Growable.addOne` and so also appends.

mutable.Queue(e, …): Queue[A]
val q = mutable.Queue(1, 2)
q.enqueue(3)
println(q.dequeue())   // => 1
println(q)             // => Queue(2, 3)

# PriorityQueue

The growable mutable max-heap. `enqueue`/`+=` add, `dequeue` removes and answers the greatest element, `head` peeks at it, `dequeueAll` drains into a sorted `ArraySeq`. Its `toString` and its iteration expose the RAW heap array, so only the head is ordered; `map` answers an `ArrayBuffer` (the result's element type has no implied `Ordering`) where `filter` stays a `PriorityQueue`.

mutable.PriorityQueue(e, …): PriorityQueue[A]
val q = mutable.PriorityQueue(3, 1, 4, 1, 5)
println(q)             // => PriorityQueue(5, 3, 4, 1, 1)
println(q.dequeue())   // => 5
println(q.dequeueAll)  // => ArraySeq(4, 3, 1, 1)

# Stack

The growable mutable LIFO, whose HEAD is its top: `push` prepends, `pop` takes the head and answers it, `top` peeks. `+=` is still `Growable.addOne`, so it APPENDS — `Stack(1,2,3) += 8` is `Stack(1, 2, 3, 8)` where `push(8)` would be `Stack(8, 1, 2, 3)`.

mutable.Stack(e, …): Stack[A]
val s = mutable.Stack(1, 2)
s.push(3)
println(s.pop())   // => 3
println(s)         // => Stack(1, 2)

# ArrayDeque

The mutable sequence that grows at BOTH ends: `append`/`+=`, `prepend`, `removeHead` and `removeLast`, plus indexed `d(i)` reads and `d(i) = v` writes.

mutable.ArrayDeque(e, …): ArrayDeque[A]
val d = mutable.ArrayDeque(1, 2)
d.prepend(0)
println(d.removeLast())   // => 2
println(d)                // => ArrayDeque(0, 1)

# LinkedHashSet

The mutable set that iterates and prints in INSERTION order rather than the hash table's. A re-added element keeps its original position; one removed and re-added moves to the end.

mutable.LinkedHashSet(e, …): LinkedHashSet[A]
val s = mutable.LinkedHashSet(3, 1, 2)
s += 9
println(s)   // => LinkedHashSet(3, 1, 2, 9)

# LinkedHashMap

The mutable map that iterates and prints in INSERTION order. A repeated key keeps its position and takes the later value; the mutators are `mutable.Map`'s.

mutable.LinkedHashMap(k -> v, …): LinkedHashMap[K, V]
val m = mutable.LinkedHashMap(3 -> "c", 1 -> "a")
m(2) = "b"
println(m)   // => LinkedHashMap(3 -> c, 1 -> a, 2 -> b)

# StringBuilder

The growable `Seq[Char]` whose `toString` is its CONTENTS rather than a rendered collection. `append` takes `String.valueOf` of any value, `+=` a `Char` and `++=` a `String` or `Char` sequence; `insert`, `setCharAt`, `deleteCharAt`, `setLength`, `clear` and `result()` mutate or freeze it, and it answers the `CharSequence` members `substring`/`indexOf`/`charAt` alongside every sequence one. A selecting op (`take`, `filter`, `reverse`) answers another `StringBuilder`; `map`, whose element type may change, answers an `ArrayBuffer`.

new StringBuilder(s?): StringBuilder
val b = new StringBuilder("ab")
b += 'c'
b.append(7)
println(b)   // => abc7

# Ordering

An explicit comparison for `sorted`/`sortBy`/`max`/`min`/`maxBy`/`minBy`. `Ordering.Int` and its siblings are the natural ordering, `.reverse` flips it, `Ordering.by(f)` sorts by `f`'s result, `Ordering.fromLessThan(lt)` builds one from a `<` test, and the value itself answers `compare`, `lt`, `gt`, `lteq`, `gteq`, `equiv`, `max`, `min` and `on`.

Ordering.Int | Ordering.by(f) | ord.reverse
println(List(3, 1, 2).sorted(Ordering.Int.reverse))   // => List(3, 2, 1)

# PartialFunction

A function defined only on some arguments — what a `{ case … }` literal builds. Beyond `apply` it answers `isDefinedAt`, which is what `collect`/`collectFirst` use to skip a non-matching element, and it composes through `applyOrElse`, `lift`, `orElse`, `andThen` and `compose`.

val pf: PartialFunction[A, B] = { case … => … }
val pf: PartialFunction[Int, String] = { case 1 => "one" }
println(pf.isDefinedAt(2))   // => false
println(pf.lift(1))          // => Some(one)

Sequence Methods

# length

The number of elements. `size` is the same method.

xs.length: Int
println(List(1, 2, 3).length)   // => 3

# size

The number of elements — the alias of `length` every collection kind answers.

xs.size: Int
println(Set(1, 2).size)   // => 2

# isEmpty

Whether the collection has no elements.

xs.isEmpty: Boolean
println(List().isEmpty)   // => true

# nonEmpty

Whether the collection has at least one element — the negation of `isEmpty`.

xs.nonEmpty: Boolean
println(List(1).nonEmpty)   // => true

# head

The first element. On an empty collection it raises `java.util.NoSuchElementException: head of empty list`.

xs.head: A
println(List(1, 2).head)   // => 1

# last

The final element. On an empty collection it raises `java.util.NoSuchElementException: last of empty list`.

xs.last: A
println(List(1, 2).last)   // => 2

# headOption

The first element as `Some(x)`, or `None` when the collection is empty. The total counterpart of `head`.

xs.headOption: Option[A]
println(List(1, 2).headOption)   // => Some(1)
println(List().headOption)      // => None

# lastOption

The final element as `Some(x)`, or `None` when the collection is empty.

xs.lastOption: Option[A]
println(List(1, 2).lastOption)   // => Some(2)

# tail

Every element but the first, in the receiver's own kind. On an empty collection it raises `UnsupportedOperationException: tail of empty list`.

xs.tail: Repr
println(List(1, 2, 3).tail)   // => List(2, 3)

# init

Every element but the last. Unlike `tail` it does not throw on an empty receiver — it answers the empty collection.

xs.init: Repr
println(List(1, 2, 3).init)   // => List(1, 2)

# apply

Index the sequence — the method `xs(i)` calls. An out-of-range index raises `java.lang.IndexOutOfBoundsException` carrying the bare index, which is `LinearSeqOps.apply`'s message.

xs.apply(i: Int): A
println(List(10, 20, 30)(1))   // => 20

# contains

Whether any element equals the argument, by structural equality.

xs.contains(v: Any): Boolean
println(List(1, 2, 3).contains(2))   // => true

# indexOf

The position of the first element equal to the argument, or `-1` when there is none.

xs.indexOf(v: Any): Int
println(List(1, 2, 1).indexOf(1))   // => 0

# lastIndexOf

The position of the last element equal to the argument, or `-1` when there is none.

xs.lastIndexOf(v: Any): Int
println(List(1, 2, 1).lastIndexOf(1))   // => 2

# indexWhere

The position of the first element satisfying the predicate, or `-1` when none does. It stops at the first hit.

xs.indexWhere(p: A => Boolean): Int
println(List(1, 2, 3).indexWhere(_ > 1))   // => 1

# take

The first `n` elements. A negative `n` answers the empty collection and an over-long `n` saturates — neither throws.

xs.take(n: Int): Repr
println(List(1, 2, 3).take(2))   // => List(1, 2)

# drop

Everything after the first `n` elements, with the same saturating bounds as `take`.

xs.drop(n: Int): Repr
println(List(1, 2, 3).drop(2))   // => List(3)

# takeRight

The last `n` elements.

xs.takeRight(n: Int): Repr
println(List(1, 2, 3).takeRight(2))   // => List(2, 3)

# dropRight

Everything but the last `n` elements.

xs.dropRight(n: Int): Repr
println(List(1, 2, 3).dropRight(2))   // => List(1)

# slice

The half-open index range `[from, until)`. Both bounds are clamped into the sequence and an inverted range answers empty, so it never throws.

xs.slice(from: Int, until: Int): Repr
println(List(1, 2, 3).slice(1, 3))   // => List(2, 3)

# splitAt

The pair `(take(n), drop(n))`, both halves in the receiver's kind.

xs.splitAt(n: Int): (Repr, Repr)
println(List(1, 2, 3).splitAt(1))   // => (List(1),List(2, 3))

# distinct

The elements with later duplicates removed, keeping the first occurrence of each and the original order.

xs.distinct: Repr
println(List(1, 2, 2, 3).distinct)   // => List(1, 2, 3)

# sorted

The elements in ascending natural order, stably. Numbers compare numerically across `Int`/`Double`, strings by UTF-16 code unit (Java's `compareTo`), `false` before `true`, tuples element by element. Any other pairing compares equal, so the input order survives.

xs.sorted: Repr
println(List(3, 1, 2).sorted)   // => List(1, 2, 3)

# reverse

The elements in the opposite order. On a `Range` the result is another `Range`, walked the other way with a negated step.

xs.reverse: Repr
println(List(1, 2, 3).reverse)   // => List(3, 2, 1)
println((1 to 3).reverse)      // => Range 3 to 1 by -1

# flatten

Concatenate a sequence of sequences (or of tuples) into one. A non-collection element makes the whole call fall through to a no-such-method error.

xs.flatten: Repr
println(List(List(1), List(2, 3)).flatten)   // => List(1, 2, 3)

# grouped

Split into consecutive non-overlapping chunks of `n` (the last one short). Scala answers an `Iterator`; here the materialized `List` of chunks is answered instead, so it prints directly. `n < 1` raises `IllegalArgumentException`.

xs.grouped(n: Int): List[Repr]
println(List(1, 2, 3).grouped(2))   // => List(List(1, 2), List(3))

# sliding

Every window of `n` consecutive elements, as a materialized `List` rather than Scala's `Iterator`. A receiver shorter than `n` answers one window holding all of it.

xs.sliding(n: Int): List[Repr]
println(List(1, 2, 3).sliding(2))   // => List(List(1, 2), List(2, 3))

# map

Apply the function to every element. The result keeps the receiver's kind, with Scala's own three exceptions: a `Set` re-deduplicates and re-orders, a `Range` answers a `Vector`, and a `Map`'s `values` view answers a `List`.

xs.map(f: A => B): Repr[B]
println(List(1, 2, 3).map(_ * 2))   // => List(2, 4, 6)
println((1 to 3).map(_ * 2))      // => Vector(2, 4, 6)

# flatMap

Apply a collection-valued function to every element and concatenate the results. A function that answers a non-collection is an error rather than a silent wrap.

xs.flatMap(f: A => Seq[B]): Repr[B]
println(List(1, 2).flatMap(x => List(x, x * 10)))   // => List(1, 10, 2, 20)

# filter

The elements the predicate answers true for.

xs.filter(p: A => Boolean): Repr
println(List(1, 2, 3).filter(_ > 1))   // => List(2, 3)

# filterNot

The elements the predicate answers false for — `filter` with the test inverted.

xs.filterNot(p: A => Boolean): Repr
println(List(1, 2, 3).filterNot(_ > 1))   // => List(1)

# withFilter

The desugar target of a `for` comprehension's `if` guard. It is a plain eager `filter` here — there is no lazy view, so the guard runs once over the whole receiver.

xs.withFilter(p: A => Boolean): Repr
println(List(1, 2, 3).withFilter(_ > 1))   // => List(2, 3)

# collect

`filter` and `map` in one pass over a partial function. An element the function is not defined at is skipped rather than raising `MatchError`, and the arm body never runs for it — Scala's `applyOrElse` protocol.

xs.collect(pf: PartialFunction[A, B]): Repr[B]
println(List(1, 2, 3, 4).collect { case x if x % 2 == 0 => x * 10 })   // => List(20, 40)

# collectFirst

The first result of a partial function over the elements, as `Some(v)`, or `None` when it is defined at none of them.

xs.collectFirst(pf: PartialFunction[A, B]): Option[B]
println(List(1, 2, 3).collectFirst { case x if x > 1 => x * 10 })   // => Some(20)

# foreach

Run the function for its effect on every element and answer Unit.

xs.foreach(f: A => Unit): Unit
List(1, 2).foreach(print)   // => 12

# zip

Pair each element with the element at the same position of the argument, stopping at the shorter of the two.

xs.zip(ys: Seq[B]): Repr[(A, B)]
println(List(1, 2, 3).zip(List("a", "b")))   // => List((1,a), (2,b))

# zipWithIndex

Pair each element with its own position, counting from zero.

xs.zipWithIndex: Repr[(A, Int)]
println(List("a", "b").zipWithIndex)   // => List((a,0), (b,1))

# unzip

Split a sequence of pairs into the pair of sequences. An element that is not a two-element tuple is an error.

xs.unzip: (Repr[A], Repr[B])
println(List((1, 2), (3, 4)).unzip)   // => (List(1, 3),List(2, 4))

# partition

Sort every element into the pair `(satisfying, failing)`. Unlike `span` it keeps testing after the first failure.

xs.partition(p: A => Boolean): (Repr, Repr)
println(List(1, 2, 3).partition(_ < 3))   // => (List(1, 2),List(3))

# span

The pair `(takeWhile(p), dropWhile(p))`: it stops testing at the first failure, so a later satisfying element still lands on the right.

xs.span(p: A => Boolean): (Repr, Repr)
println(List(1, 2, 1).span(_ < 2))   // => (List(1),List(2, 1))

# takeWhile

The longest leading run of elements satisfying the predicate.

xs.takeWhile(p: A => Boolean): Repr
println(List(1, 2, 3).takeWhile(_ < 3))   // => List(1, 2)

# dropWhile

Everything after the longest leading run satisfying the predicate.

xs.dropWhile(p: A => Boolean): Repr
println(List(1, 2, 3).dropWhile(_ < 3))   // => List(3)

# groupBy

Group the elements by the key the function computes, each group in the receiver's kind. The result is always a `HashMap`, however few groups there are, because Scala builds it through a `HashMap` builder.

xs.groupBy(f: A => K): HashMap[K, Repr]
println(List(1, 2, 3).groupBy(_ % 2))   // => HashMap(0 -> List(2), 1 -> List(1, 3))

# sortBy

Sort by the key the function computes, stably, under the same ordering as `sorted`. The key is computed once per element.

xs.sortBy(f: A => K): Repr
println(List("bbb", "a").sortBy(_.length))   // => List(a, bbb)

# sortWith

Sort under a user `lt` comparator, stably. It is an insertion merge rather than a library sort, because an inconsistent comparator must produce a nonsensical order rather than a panic.

xs.sortWith(lt: (A, A) => Boolean): Repr
println(List(1, 3, 2).sortWith((a, b) => a > b))   // => List(3, 2, 1)

# foldLeft

Fold left to right from an initial accumulator. The two argument lists of `foldLeft(z)(op)` are flattened into one call by the parser.

xs.foldLeft(z: B)(op: (B, A) => B): B
println(List(1, 2, 3).foldLeft(0)((a, b) => a + b))   // => 6

# foldRight

Fold right to left from an initial accumulator; the operator receives `(element, accumulator)` in that order.

xs.foldRight(z: B)(op: (A, B) => B): B
println(List(1, 2, 3).foldRight(0)((a, b) => a - b))   // => 2

# fold

Fold from an initial accumulator, left to right. Scala leaves the order unspecified; here it is the `foldLeft` order.

xs.fold(z: A)(op: (A, A) => A): A
println(List(1, 2, 3).fold(0)((a, b) => a + b))   // => 6

# scanLeft

The `foldLeft` that keeps every intermediate accumulator, so the result is one longer than the receiver and starts with the seed — an empty receiver still answers the one-element `List(z)`.

xs.scanLeft(z: B)(op: (B, A) => B): Repr[B]
println(List(1, 2, 3).scanLeft(0)((a, b) => a + b))   // => List(0, 1, 3, 6)

# scanRight

The `foldRight` that keeps every intermediate accumulator; the result ends with the seed.

xs.scanRight(z: B)(op: (A, B) => B): Repr[B]
println(List(1, 2, 3).scanRight(0)((a, b) => a + b))   // => List(6, 5, 3, 0)

# reduce

Combine the elements pairwise with no initial value, left to right. An empty receiver raises `UnsupportedOperationException: empty.reduceLeft`.

xs.reduce(op: (A, A) => A): A
println(List(1, 2, 3).reduce((a, b) => a + b))   // => 6

# reduceLeft

The explicit left-to-right `reduce`; the same implementation.

xs.reduceLeft(op: (A, A) => A): A
println(List(1, 2, 3).reduceLeft((a, b) => a - b))   // => -4

# reduceRight

Combine pairwise from the right, the operator receiving `(element, accumulator)`. An empty receiver raises `UnsupportedOperationException: empty.reduceRight`.

xs.reduceRight(op: (A, A) => A): A
println(List(1, 2, 3).reduceRight((a, b) => a - b))   // => 2

# sum

Add the elements. The result is an `Int` when every element is an `Int`, otherwise a `Double`. An empty receiver answers `0`.

xs.sum: A
println(List(1, 2, 3).sum)   // => 6

# product

Multiply the elements, with the same `Int`/`Double` result rule as `sum`. An empty receiver answers `1`.

xs.product: A
println(List(1, 2, 3).product)   // => 6

# min

The smallest element under the `sorted` ordering. An empty receiver raises `UnsupportedOperationException: empty.min`.

xs.min: A
println(List(3, 1, 2).min)   // => 1

# max

The largest element under the `sorted` ordering. An empty receiver raises `UnsupportedOperationException: empty.max`.

xs.max: A
println(List(3, 1, 2).max)   // => 3

# minBy

The element whose computed key is smallest; ties keep the earliest. An empty receiver raises `UnsupportedOperationException: empty.minBy`.

xs.minBy(f: A => K): A
println(List("bbb", "a").minBy(_.length))   // => a

# maxBy

The element whose computed key is largest; ties keep the earliest.

xs.maxBy(f: A => K): A
println(List("bbb", "a").maxBy(_.length))   // => bbb

# count

How many elements satisfy the predicate. It tests every element.

xs.count(p: A => Boolean): Int
println(List(1, 2, 3).count(_ > 1))   // => 2

# exists

Whether any element satisfies the predicate, short-circuiting on the first hit.

xs.exists(p: A => Boolean): Boolean
println(List(1, 2).exists(_ > 1))   // => true

# forall

Whether every element satisfies the predicate, short-circuiting on the first failure. An empty receiver answers true.

xs.forall(p: A => Boolean): Boolean
println(List(1, 2).forall(_ > 0))   // => true

# find

The first element satisfying the predicate as `Some(x)`, or `None`. It stops at the first hit.

xs.find(p: A => Boolean): Option[A]
println(List(1, 2, 3).find(_ > 1))   // => Some(2)

# mkString

Render the elements as one string. With no argument they are concatenated; with one they are separator-joined; with three the join is wrapped in a prefix and a suffix.

xs.mkString[(sep)|(pre, sep, post)]: String
println(List(1, 2, 3).mkString(","))            // => 1,2,3
println(List(1, 2, 3).mkString("[", ",", "]"))   // => [1,2,3]

# toList

The elements as a `List`, whatever the receiver's kind was.

xs.toList: List[A]
println(Set(1, 2).toList)   // => List(1, 2)

# toSeq

The elements as a `Seq`, which is a `List` here.

xs.toSeq: List[A]
println(Array(1, 2).toSeq)   // => List(1, 2)

# toIterable

The elements as an `Iterable`, which is also a `List` here — `immutable.Iterable`'s own factory is `List`.

xs.toIterable: List[A]
println(List(1, 2).toIterable)   // => List(1, 2)

# toVector

The elements as a `Vector`.

xs.toVector: Vector[A]
println(List(1, 2).toVector)   // => Vector(1, 2)

# toArray

The elements as a mutable `Array`, copied out of the receiver.

xs.toArray: Array[A]
println(List(1, 2).toArray)   // => Array(1, 2)

# toSet

The elements as an immutable `Set`, duplicates dropped and the representation chosen by size as for any `Set`.

xs.toSet: Set[A]
println(List(1, 2, 2).toSet)   // => Set(1, 2)

# toMap

A sequence of pairs as a `Map`, later duplicates of a key overwriting earlier ones. A non-pair element is an error.

xs.toMap: Map[K, V]
println(List((1, 2), (3, 4)).toMap)   // => Map(1 -> 2, 3 -> 4)

# union

The receiver's elements followed by the argument's. On a `Set` the result is re-deduplicated; on a sequence it is a plain concatenation.

xs.union(ys: Seq[A]): Repr
println(Set(1, 2).union(Set(2, 3)))   // => Set(1, 2, 3)

# intersect

The receiver's elements that also occur in the argument, in the receiver's order.

xs.intersect(ys: Seq[A]): Repr
println(Set(1, 2, 3).intersect(Set(2, 3, 4)))   // => Set(2, 3)

# diff

The receiver's elements that do not occur in the argument. Unlike a buffer's `-=`, it removes every occurrence.

xs.diff(ys: Seq[A]): Repr
println(List(1, 2, 3).diff(List(2)))   // => List(1, 3)

# subsetOf

Whether every element of the receiver occurs in the argument.

xs.subsetOf(ys: Set[A]): Boolean
println(Set(1, 2).subsetOf(Set(1, 2, 3)))   // => true

# incl

A `Set` with one element added — the method `set + e` calls. The result re-deduplicates and may change representation.

set.incl(e: A): Set[A]
println(Set(1, 2).incl(5))   // => Set(1, 2, 5)

# excl

A `Set` with one element removed — the method `set - e` calls.

set.excl(e: A): Set[A]
println(Set(1, 2).excl(1))   // => Set(2)

# removedAll

Every element of the argument removed — the same implementation as `diff` and `--`.

xs.removedAll(ys: Seq[A]): Repr
println(Set(1, 2, 3).removedAll(Set(2)))   // => Set(1, 3)

# concat

The receiver's elements followed by the argument's — the named form of `++`.

xs.concat(ys: Seq[A]): Repr
println(List(1, 2).concat(List(3)))   // => List(1, 2, 3)

# appended

A copy with one element added at the end — the named form of `:+`.

xs.appended(e: A): Repr
println(List(1, 2).appended(3))   // => List(1, 2, 3)

# prepended

A copy with one element added at the front — the named form of `+:`.

xs.prepended(e: A): Repr
println(List(1, 2).prepended(0))   // => List(0, 1, 2)

# by (Range)

Rebuild a `Range` with a new step. Only a `Range` receiver answers it; a zero step raises `IllegalArgumentException: step cannot be 0.`.

(a to b).by(step: Int): Range
println((1 to 10 by 3).toList)   // => List(1, 4, 7, 10)

# update

In-place element assignment — the desugar target of `xs(i) = v`. Only an `Array`, `ListBuffer` or `ArrayBuffer` accepts it; an out-of-range index raises `ArrayIndexOutOfBoundsException`.

xs.update(i: Int, v: A): Unit
val a = Array(1, 2, 3)
a(0) = 9
println(a.mkString(","))   // => 9,2,3

# += (mutable)

Add one element in place to a buffer or a `mutable.Set` and answer the receiver, so calls chain. On an immutable receiver `+` builds a new collection instead.

xs += (e: A): xs.type
val b = mutable.ListBuffer(1, 2)
b += 3
println(b)   // => ListBuffer(1, 2, 3)

# ++= (mutable)

Add every element of the argument in place and answer the receiver.

xs ++= (ys: Seq[A]): xs.type
val a = mutable.ArrayBuffer(1, 2)
a ++= List(3, 4)
println(a)   // => ArrayBuffer(1, 2, 3, 4)

# -= (mutable)

Remove one element in place. A buffer drops only the first occurrence; a `mutable.Set` drops the element outright.

xs -= (e: A): xs.type
val b = mutable.ArrayBuffer(1, 2, 1)
b -= 1
println(b)   // => ArrayBuffer(2, 1)

# --= (mutable)

Remove every element of the argument in place, one occurrence each for a buffer.

xs --= (ys: Seq[A]): xs.type
val b = mutable.ListBuffer(1, 2, 3)
b --= List(1, 3)
println(b)   // => ListBuffer(2)

# +=:

Prepend in place, the right-associative operator form of `prepend`. It is implemented but unreachable from source: the lexer reads `+=` as its own token, so `0 +=: b` does not parse. Use `b.prepend(0)`.

b.prepend(e: A): b.type   // the reachable spelling
val b = mutable.ListBuffer(1, 2)
b.prepend(0)
println(b)   // => ListBuffer(0, 1, 2)

# add

Add one element to a `mutable.Set` and answer whether it was absent — unlike `+=`, which answers the set.

s.add(e: A): Boolean
val s = mutable.Set(1, 2)
println(s.add(3))   // => true

# addOne

The named form of `+=`: add one element in place and answer the receiver.

xs.addOne(e: A): xs.type
val b = mutable.ListBuffer(1)
b.addOne(2)
println(b)   // => ListBuffer(1, 2)

# addAll

The named form of `++=`: add every element of the argument in place.

xs.addAll(ys: Seq[A]): xs.type
val b = mutable.ListBuffer(1)
b.addAll(List(2, 3))
println(b)   // => ListBuffer(1, 2, 3)

# append

Add one element at the end of a buffer in place.

b.append(e: A): b.type
val b = mutable.ListBuffer(1)
b.append(2)
println(b)   // => ListBuffer(1, 2)

# appendAll

Add every element of the argument at the end of a buffer in place.

b.appendAll(ys: Seq[A]): b.type
val b = mutable.ListBuffer(1, 2)
b.appendAll(List(3))
println(b)   // => ListBuffer(1, 2, 3)

# prepend

Add one element at the front of a buffer in place. This is the reachable spelling of `+=:`.

b.prepend(e: A): b.type
val b = mutable.ArrayBuffer(1, 2)
b.prepend(0)
println(b)   // => ArrayBuffer(0, 1, 2)

# prependAll

Add every element of the argument at the front of a buffer in place, keeping their order.

b.prependAll(ys: Seq[A]): b.type
val b = mutable.ListBuffer(3)
b.prependAll(List(1, 2))
println(b)   // => ListBuffer(1, 2, 3)

# insert

Insert one element at an index, shifting the rest right. An index past the end raises `IndexOutOfBoundsException`; an index equal to the length appends.

b.insert(i: Int, e: A): Unit
val b = mutable.ListBuffer(1, 2)
b.insert(1, 9)
println(b)   // => ListBuffer(1, 9, 2)

# insertAll

Insert every element of the argument at an index, keeping their order.

b.insertAll(i: Int, ys: Seq[A]): Unit
val b = mutable.ListBuffer(1, 2)
b.insertAll(1, List(7, 8))
println(b)   // => ListBuffer(1, 7, 8, 2)

# remove

On a buffer, remove the element at an index and answer it. On a `mutable.Set`, remove the element and answer whether it was present.

b.remove(i: Int): A   |   s.remove(e: A): Boolean
val b = mutable.ListBuffer(1, 2)
println(b.remove(0))   // => 1

# subtractOne

The named form of `-=`: remove one element (one occurrence, on a buffer) in place.

xs.subtractOne(e: A): xs.type
val b = mutable.ListBuffer(1, 2)
b.subtractOne(1)
println(b)   // => ListBuffer(2)

# subtractAll

The named form of `--=`: remove every element of the argument in place.

xs.subtractAll(ys: Seq[A]): xs.type
val b = mutable.ListBuffer(1, 2, 3)
b.subtractAll(List(1, 2))
println(b)   // => ListBuffer(3)

# clear

Drop every element in place. A `mutable.Set` keeps the hash-table length it had grown to, matching the JVM's `Arrays.fill`, so later insertion order is unaffected by the clear.

xs.clear(): Unit
val b = mutable.ListBuffer(1, 2)
b.clear()
println(b)   // => ListBuffer()

# enqueue

Append to a `mutable.Queue` and answer it. `enqueueAll` appends a whole collection.

q.enqueue(e: A): q.type
val q = mutable.Queue(1)
q.enqueue(2)
println(q)   // => Queue(1, 2)

# dequeue

Remove a `mutable.Queue`'s head and answer it. Raises `java.util.NoSuchElementException: empty collection` on an empty queue.

q.dequeue(): A
val q = mutable.Queue(1, 2)
println(q.dequeue())   // => 1

# push

PREPEND to a `mutable.Stack` and answer it — a `Stack`'s head is its top, which is why this is not the same as `+=`.

s.push(e: A): s.type
val s = mutable.Stack(1)
s.push(2)
println(s)   // => Stack(2, 1)

# pop

Remove a `mutable.Stack`'s head (its top) and answer it. Raises `java.util.NoSuchElementException: empty collection` on an empty stack.

s.pop(): A
val s = mutable.Stack(1, 2)
println(s.pop())   // => 1

# top

Peek at a `mutable.Stack`'s top without removing it; `front` is the `mutable.Queue` spelling. Raises `head of empty Stack`/`head of empty Queue` when there is nothing to peek at.

s.top: A
println(mutable.Stack(1, 2).top)   // => 1

# removeHead

Remove a `mutable.ArrayDeque`'s first element and answer it; `removeLast` takes the last one instead.

d.removeHead(): A
val d = mutable.ArrayDeque(1, 2)
println(d.removeLast())   // => 2

# result

Freeze a `StringBuilder`'s contents into a `String`.

b.result(): String
println(new StringBuilder("ab").result())   // => ab

# setCharAt

Replace one character of a `StringBuilder` and answer the builder; `deleteCharAt` removes one and `setLength` truncates (or pads with NUL). An out-of-range index raises `java.lang.StringIndexOutOfBoundsException: index i, length n`.

b.setCharAt(i: Int, c: Char): b.type
val b = new StringBuilder("abc")
b.setCharAt(0, 'Q')
println(b)   // => Qbc

# getClass

The receiver's runtime class, answering `getName` and `getSimpleName`. Modeled for the receivers whose JVM class can be named faithfully — `String`, the primitives, a user `class`/`case class`/`object`, and a throwable (the usual reason to call it). A collection's runtime class is a private implementation detail, so it stays an error rather than a plausible-looking guess.

x.getClass: Class[_]
try { 1 / 0 } catch { case e: Throwable => println(e.getClass.getSimpleName) }   // => ArithmeticException

# toString

The Scala rendering of the collection, which is what `println` prints: `List(1, 2)`, `Set(…)`/`HashSet(…)` by representation, `Range a to b by s` for a range, `(a,b)` for a tuple.

xs.toString: String
println(List(1, 2).toString)   // => List(1, 2)

# equals

Structural equality — the method `==` calls. Two collections are equal when their elements are pairwise equal; a plain (non-case) class instance compares by identity instead.

xs.equals(other: Any): Boolean
println(List(1, 2) == List(1, 2))   // => true

# hashCode

The MurmurHash3 sequence, set or map hash Scala computes — the same value that decides a `HashSet`'s print order. An `Array` and a function value keep an identity hash instead, which is not reproducible across runs.

xs.hashCode: Int
println(List(1, 2).hashCode == List(1, 2).hashCode)   // => true

Map Methods

# size

The number of entries.

m.size: Int
println(Map("a" -> 1, "b" -> 2).size)   // => 2

# isEmpty

Whether the map has no entries.

m.isEmpty: Boolean
println(Map().isEmpty)   // => true

# nonEmpty

Whether the map has at least one entry.

m.nonEmpty: Boolean
println(Map("a" -> 1).nonEmpty)   // => true

# apply

Look up a key — the method `m(k)` calls. A missing key raises `key not found: k`, so prefer `get` or `getOrElse` when absence is expected.

m.apply(k: K): V
println(Map("a" -> 1)("a"))   // => 1

# get

The value for a key as `Some(v)`, or `None` when the key is absent.

m.get(k: K): Option[V]
println(Map("a" -> 1).get("z"))   // => None

# getOrElse

The value for a key, or the supplied default when the key is absent. The default is evaluated eagerly here, not by name.

m.getOrElse(k: K, default: V): V
println(Map("a" -> 1).getOrElse("z", 0))   // => 0

# contains

Whether the map holds the key, by structural equality of keys.

m.contains(k: K): Boolean
println(Map("a" -> 1).contains("a"))   // => true

# keys

The keys. Scala prints both key views as `Set(…)` whatever the map's size — they are a `HashKeySet`, not a `HashSet` — and in the map's own order, which this reproduces.

m.keys: Set[K]
println(Map("a" -> 1, "b" -> 2).keys)   // => Set(a, b)

# keySet

The same key view as `keys`, under Scala's other name for it.

m.keySet: Set[K]
println(Map("a" -> 1).keySet)   // => Set(a)

# values

The values as an `Iterable`, in the map's own order. Mapping over that view answers a `List`, since `immutable.Iterable`'s factory is `List`.

m.values: Iterable[V]
println(Map("a" -> 1).values)   // => Iterable(1)

# updated

A copy with one key set to a value. An existing key keeps its position and takes the new value; the receiver is unchanged even when it is mutable.

m.updated(k: K, v: V): Map[K, V]
println(Map("a" -> 1).updated("b", 2))   // => Map(a -> 1, b -> 2)

# removed

A copy with one key dropped — the named form of `m - k`.

m.removed(k: K): Map[K, V]
println(Map("a" -> 1, "b" -> 2).removed("a"))   // => Map(b -> 2)

# +

A copy with one `k -> v` pair added. The argument must be a pair; adding a bare key is an error.

m + (kv: (K, V)): Map[K, V]
println(Map("a" -> 1) + ("b" -> 2))   // => Map(a -> 1, b -> 2)

# -

A copy with one key dropped.

m - (k: K): Map[K, V]
println(Map("a" -> 1, "b" -> 2) - "a")   // => Map(b -> 2)

# ++

A copy with every pair of the argument added; the argument may be another map or a sequence of pairs. A repeated key keeps its position and takes the later value.

m ++ (other: Map[K, V] | Seq[(K, V)]): Map[K, V]
println(Map("a" -> 1) ++ Map("b" -> 2))   // => Map(a -> 1, b -> 2)

# concat

The named form of `++`.

m.concat(other: Map[K, V]): Map[K, V]
println(Map("a" -> 1).concat(Map("b" -> 2)))   // => Map(a -> 1, b -> 2)

# head

The first entry as a `(k, v)` tuple, in the map's own order. An empty map raises `NoSuchElementException: head of empty map`.

m.head: (K, V)
println(Map("a" -> 1, "b" -> 2).head)   // => (a,1)

# last

The final entry as a `(k, v)` tuple, in the map's own order.

m.last: (K, V)
println(Map("a" -> 1, "b" -> 2).last)   // => (b,2)

# headOption

The first entry as `Some((k, v))`, or `None` on an empty map.

m.headOption: Option[(K, V)]
println(Map("a" -> 1).headOption)   // => Some((a,1))

# lastOption

The final entry as `Some((k, v))`, or `None` on an empty map.

m.lastOption: Option[(K, V)]
println(Map("a" -> 1).lastOption)   // => Some((a,1))

# map

Transform every entry. The result is a `Map` when the function answers pairs and a `List` otherwise — Scala picks that builder from the function's static result type, which does not exist here, so the results themselves decide. Over an empty map, or a `collect` that matched nothing, the decision falls back to whether every value the body can answer is a pair literal.

m.map(f: ((K, V)) => B): Map[K2, V2] | List[B]
val m = Map("a" -> 1, "b" -> 2)
println(m.map { case (k, v) => (k, v * 2) })   // => Map(a -> 2, b -> 4)
println(m.map { case (k, v) => v })           // => List(1, 2)

# flatMap

Transform every entry into zero or more results and concatenate them, with the same pair-or-not builder rule as `map`.

m.flatMap(f: ((K, V)) => Seq[B]): Map[K2, V2] | List[B]
println(Map("a" -> 1).flatMap { case (k, v) => List((k, v), (k + "!", v)) })   // => Map(a -> 1, a! -> 1)

# collect

`filter` and `map` in one pass over a partial function on entries; an entry no arm matches is skipped. Same builder rule as `map`.

m.collect(pf: PartialFunction[(K, V), B]): Map[K2, V2] | List[B]
println(Map("a" -> 1, "b" -> 2).collect { case (k, v) if v > 1 => (k, v) })   // => Map(b -> 2)

# collectFirst

The first result of a partial function over the entries as `Some(v)`, or `None`.

m.collectFirst(pf: PartialFunction[(K, V), B]): Option[B]
println(Map("a" -> 1).collectFirst { case (k, v) => v })   // => Some(1)

# filter

The entries whose `(k, v)` pair satisfies the predicate, as a map of the receiver's representation — a `HashMap` stays hashed however few entries survive.

m.filter(p: ((K, V)) => Boolean): Map[K, V]
println(Map("a" -> 1, "b" -> 2).filter { case (k, v) => v > 1 })   // => Map(b -> 2)

# filterNot

The entries whose pair fails the predicate.

m.filterNot(p: ((K, V)) => Boolean): Map[K, V]
println(Map("a" -> 1, "b" -> 2).filterNot { case (k, v) => v > 1 })   // => Map(a -> 1)

# withFilter

The `for`-comprehension guard's target on a map; an eager `filter` here, not a lazy view.

m.withFilter(p: ((K, V)) => Boolean): Map[K, V]
println(Map("a" -> 1, "b" -> 2).withFilter { case (k, v) => v > 1 })   // => Map(b -> 2)

# takeWhile

The leading run of entries satisfying the predicate, in the map's own order.

m.takeWhile(p: ((K, V)) => Boolean): Map[K, V]
println(Map("a" -> 1, "b" -> 2).takeWhile { case (k, v) => v < 2 })   // => Map(a -> 1)

# dropWhile

Everything after the leading run satisfying the predicate.

m.dropWhile(p: ((K, V)) => Boolean): Map[K, V]
println(Map("a" -> 1, "b" -> 2).dropWhile { case (k, v) => v < 2 })   // => Map(b -> 2)

# partition

The pair of maps `(satisfying, failing)`, both keeping the receiver's representation.

m.partition(p: ((K, V)) => Boolean): (Map[K, V], Map[K, V])
println(Map("a" -> 1, "b" -> 2).partition { case (k, v) => v > 1 })   // => (Map(b -> 2),Map(a -> 1))

# foreach

Run the function on every entry for its effect and answer Unit.

m.foreach(f: ((K, V)) => Unit): Unit
Map("a" -> 1).foreach { case (k, v) => print(k + v) }   // => a1

# exists

Whether any entry satisfies the predicate.

m.exists(p: ((K, V)) => Boolean): Boolean
println(Map("a" -> 1).exists { case (k, v) => v == 1 })   // => true

# forall

Whether every entry satisfies the predicate.

m.forall(p: ((K, V)) => Boolean): Boolean
println(Map("a" -> 1).forall { case (k, v) => v > 0 })   // => true

# count

How many entries satisfy the predicate.

m.count(p: ((K, V)) => Boolean): Int
println(Map("a" -> 1, "b" -> 2).count { case (k, v) => v > 1 })   // => 1

# find

The first entry satisfying the predicate as `Some((k, v))`, or `None`.

m.find(p: ((K, V)) => Boolean): Option[(K, V)]
println(Map("a" -> 1).find { case (k, v) => v == 1 })   // => Some((a,1))

# foldLeft

Fold the entries left to right from an initial accumulator; the operator receives `(acc, (k, v))`.

m.foldLeft(z: B)(op: (B, (K, V)) => B): B
println(Map("a" -> 1, "b" -> 2).foldLeft(0) { (acc, kv) => acc + kv._2 })   // => 3

# foldRight

Fold the entries right to left; the operator receives `((k, v), acc)`.

m.foldRight(z: B)(op: ((K, V), B) => B): B
println(Map("a" -> 1).foldRight(0) { (kv, acc) => acc + kv._2 })   // => 1

# fold

Fold the entries from an initial accumulator, in the `foldLeft` order.

m.fold(z: B)(op: (B, (K, V)) => B): B
println(Map("a" -> 1).fold(0) { (acc, kv) => acc + kv._2 })   // => 1

# reduce

Combine the entries pairwise with no initial value. An empty map raises `UnsupportedOperationException: empty.reduceLeft`.

m.reduce(op: ((K, V), (K, V)) => (K, V)): (K, V)
println(Map("a" -> 1, "b" -> 2).reduce { (x, y) => (x._1 + y._1, x._2 + y._2) })   // => (ab,3)

# maxBy

The entry whose computed key is largest, as a `(k, v)` tuple.

m.maxBy(f: ((K, V)) => C): (K, V)
println(Map("a" -> 1, "b" -> 2).maxBy { case (k, v) => v })   // => (b,2)

# minBy

The entry whose computed key is smallest, as a `(k, v)` tuple.

m.minBy(f: ((K, V)) => C): (K, V)
println(Map("a" -> 1, "b" -> 2).minBy { case (k, v) => v })   // => (a,1)

# groupBy

Group the entries by a computed key. As on a sequence the result is a `HashMap`, and each group is a `List` of entry tuples.

m.groupBy(f: ((K, V)) => C): HashMap[C, List[(K, V)]]
println(Map("a" -> 1, "b" -> 2).groupBy { case (k, v) => v % 2 })   // => HashMap(0 -> List((b,2)), 1 -> List((a,1)))

# sortBy

Sort the entries by a computed key. It answers a `List` of tuples, not a map — a map has no element order to impose.

m.sortBy(f: ((K, V)) => C): List[(K, V)]
println(Map("a" -> 2, "b" -> 1).sortBy { case (k, v) => v })   // => List((b,1), (a,2))

# unzip

Split the entries into the pair `(keys, values)`, both as `List`s.

m.unzip: (List[K], List[V])
println(Map("a" -> 1, "b" -> 2).unzip)   // => (List(a, b),List(1, 2))

# zipWithIndex

Pair each entry with its position in the map's own order.

m.zipWithIndex: List[((K, V), Int)]
println(Map("a" -> 1).zipWithIndex)   // => List(((a,1),0))

# mkString

Render the entries as one string. Each entry renders as its tuple, `(k,v)` — not as `k -> v`, which is the map's own `toString` form.

m.mkString[(sep)|(pre, sep, post)]: String
println(Map("a" -> 1, "b" -> 2).mkString(";"))   // => (a,1);(b,2)

# toList

The entries as a `List` of `(k, v)` tuples.

m.toList: List[(K, V)]
println(Map("a" -> 1).toList)   // => List((a,1))

# toSeq

The entries as a `Seq` of tuples, which is a `List` here.

m.toSeq: List[(K, V)]
println(Map("a" -> 1).toSeq)   // => List((a,1))

# toVector

The entries as a `Vector` of tuples.

m.toVector: Vector[(K, V)]
println(Map("a" -> 1).toVector)   // => Vector((a,1))

# toArray

The entries as an `Array` of tuples.

m.toArray: Array[(K, V)]
println(Map("a" -> 1).toArray)   // => Array((a,1))

# toSet

The entries as a `Set` of tuples.

m.toSet: Set[(K, V)]
println(Map("a" -> 1).toSet)   // => Set((a,1))

# toMap

The receiver itself — a map is already a map, so this is the identity.

m.toMap: Map[K, V]
println(Map("a" -> 1).toMap)   // => Map(a -> 1)

# +=

Add one `k -> v` pair to a `mutable.Map` in place and answer the receiver. On an immutable map `+` builds a copy instead.

m += (kv: (K, V)): m.type
val m = mutable.Map("a" -> 1)
m += ("b" -> 2)
println(m)   // => HashMap(a -> 1, b -> 2)

# ++=

Add every pair of the argument to a `mutable.Map` in place; the argument may be a map or a sequence of pairs.

m ++= (other: Map[K, V] | Seq[(K, V)]): m.type
val m = mutable.Map("a" -> 1)
m ++= Map("b" -> 2)
println(m)   // => HashMap(a -> 1, b -> 2)

# -=

Remove one key from a `mutable.Map` in place. The hash table keeps the length it had grown to, so the surviving entries keep their order.

m -= (k: K): m.type
val m = mutable.Map("a" -> 1, "b" -> 2)
m -= "a"
println(m)   // => HashMap(b -> 2)

# --=

Remove every key of the argument from a `mutable.Map` in place.

m --= (ks: Seq[K]): m.type
val m = mutable.Map("a" -> 1, "b" -> 2)
m --= List("a", "b")
println(m)   // => HashMap()

# addOne

The named form of `+=`.

m.addOne(kv: (K, V)): m.type
val m = mutable.Map("a" -> 1)
m.addOne("b" -> 2)
println(m)   // => HashMap(a -> 1, b -> 2)

# addAll

The named form of `++=`.

m.addAll(other: Seq[(K, V)]): m.type
val m = mutable.Map("a" -> 1)
m.addAll(List("b" -> 2))
println(m)   // => HashMap(a -> 1, b -> 2)

# subtractOne

The named form of `-=`.

m.subtractOne(k: K): m.type
val m = mutable.Map("a" -> 1, "b" -> 2)
m.subtractOne("a")
println(m)   // => HashMap(b -> 2)

# subtractAll

The named form of `--=`.

m.subtractAll(ks: Seq[K]): m.type
val m = mutable.Map("a" -> 1, "b" -> 2)
m.subtractAll(List("a"))
println(m)   // => HashMap(b -> 2)

# put

Set a key in a `mutable.Map` and answer the value it displaced as `Some(old)`, or `None` when the key was absent.

m.put(k: K, v: V): Option[V]
val m = mutable.Map("a" -> 1)
println(m.put("a", 2))   // => Some(1)

# update

Set a key in a `mutable.Map`, discarding any displaced value — the desugar target of `m(k) = v`.

m.update(k: K, v: V): Unit
val m = mutable.Map("a" -> 1)
m("b") = 2
println(m)   // => HashMap(a -> 1, b -> 2)

# getOrElseUpdate

The value for a key, inserting the supplied default first when the key is absent. The default is evaluated eagerly, so it is computed even for a present key.

m.getOrElseUpdate(k: K, default: V): V
val m = mutable.Map("a" -> 1)
println(m.getOrElseUpdate("b", 5))   // => 5
println(m)                          // => HashMap(a -> 1, b -> 5)

# remove

Remove a key from a `mutable.Map` and answer the value it held as `Some(old)`, or `None`.

m.remove(k: K): Option[V]
val m = mutable.Map("a" -> 1)
println(m.remove("a"))   // => Some(1)

# clear

Drop every entry of a `mutable.Map` in place, keeping the hash table's grown length.

m.clear(): Unit
val m = mutable.Map("a" -> 1)
m.clear()
println(m)   // => HashMap()

String Methods

# length

The number of characters.

s.length: Int
println("abc".length)   // => 3

# size

The number of characters — `StringOps`'s alias for `length`.

s.size: Int
println("abc".size)   // => 3

# isEmpty

Whether the string has no characters.

s.isEmpty: Boolean
println("".isEmpty)   // => true

# nonEmpty

Whether the string has at least one character.

s.nonEmpty: Boolean
println("a".nonEmpty)   // => true

# toUpperCase

The string with every character upper-cased, under Unicode's full case mapping.

s.toUpperCase: String
println("abc".toUpperCase)   // => ABC

# toLowerCase

The string with every character lower-cased.

s.toLowerCase: String
println("ABC".toLowerCase)   // => abc

# trim

The string with leading and trailing whitespace removed.

s.trim: String
println(" a ".trim)   // => a

# concat

The string with the argument appended — the method form of `+`.

s.concat(other: String): String
println("abc".concat("d"))   // => abcd

# split

Split on a REGULAR EXPRESSION, answering an `Array[String]`. `java.lang.String.split`'s rule exactly: trailing empty fields are dropped, and a zero-width match at position 0 produces no leading empty field.

s.split(regex: String): Array[String]
println("a1b22c".split("[0-9]+").mkString("/"))   // => a/b/c

# matches

Whether the regular expression matches the WHOLE string (`java.lang.String.matches` anchors both ends, unlike a search).

s.matches(regex: String): Boolean
println("a1".matches("[a-z][0-9]"))   // => true

# replaceAll

Replace every match of a regular expression. `$N` in the replacement splices capture group `N`; `\\x` is a literal `x`.

s.replaceAll(regex: String, repl: String): String
println("a1b2".replaceAll("[0-9]", "#"))   // => a#b#

# replaceFirst

As `replaceAll`, but only the first match is replaced.

s.replaceFirst(regex: String, repl: String): String
println("a1b2".replaceFirst("[0-9]", "#"))   // => a#b2

# r

Compile the string as a `scala.util.matching.Regex`, which answers `findFirstIn`, `findAllIn`, `findFirstMatchIn`, `findAllMatchIn`, `replaceAllIn`, `replaceFirstIn`, `matches`, `split` and `regex`.

s.r: Regex
println("(\\d+)".r.findFirstIn("ab12"))   // => Some(12)

# toList

The characters as a `List[Char]`. The elements are real `Char`s, so they answer `Char`'s numeric surface (`_.toInt` is the code point, not a parse).

s.toList: List[Char]
println("abc".toList)   // => List(a, b, c)
println("abc".toList.map(_.toInt))   // => List(97, 98, 99)

# toSeq

The characters as a `Seq` — Scala's `WrappedString` view over the same string, which prints as the string itself.

s.toSeq: Seq[Char]
println("ab".toSeq)   // => ab

# reverse

The characters in the opposite order.

s.reverse: String
println("abc".reverse)   // => cba

# toInt

Parse the string as an `Int`. This is `java.lang.Integer.parseInt`, so it does NOT trim — `" 42".toInt` raises where `" 42".trim.toInt` answers 42 — and a value outside an `Int`'s range raises even though its digits are legal. Both failures are `java.lang.NumberFormatException: For input string: "…"`.

s.toInt: Int
println("42".toInt + 1)   // => 43

# toByte

Parse the string as a `Byte`. The digits are read as for `toInt` and then range-checked, so a string that parses but does not fit raises the different `java.lang.NumberFormatException: Value out of range. Value:"…" Radix:10`.

s.toByte: Byte
println("127".toByte)   // => 127

# toShort

Parse the string as a `Short` — `toByte`'s range check one width up.

s.toShort: Short
println("-32768".toShort)   // => -32768

# toBoolean

Parse `"true"` or `"false"`, ignoring case and WITHOUT trimming. Anything else raises `java.lang.IllegalArgumentException: For input string: "…"` — not the `NumberFormatException` the numeric conversions raise.

s.toBoolean: Boolean
println("TRUE".toBoolean)   // => true

# toDouble

Parse the string as a floating-point number. `java.lang.Double.parseDouble` DOES accept surrounding whitespace, which is the asymmetry with `toInt`. A malformed string raises `NumberFormatException`.

s.toDouble: Double
println("1.5".toDouble * 2)   // => 3.0

# charAt

The character at an index, as a one-character string. Out of range it raises `StringIndexOutOfBoundsException` with the JDK's own message.

s.charAt(i: Int): String
println("abc".charAt(1))   // => b

# contains

Whether the argument occurs as a substring.

s.contains(sub: String): Boolean
println("abc".contains("bc"))   // => true

# startsWith

Whether the string begins with the argument.

s.startsWith(prefix: String): Boolean
println("abc".startsWith("a"))   // => true

# endsWith

Whether the string ends with the argument.

s.endsWith(suffix: String): Boolean
println("abc".endsWith("c"))   // => true

# substring

The characters in the half-open range `[begin, end)`, or from `begin` to the end with one argument. An out-of-range or inverted range raises `StringIndexOutOfBoundsException`.

s.substring(begin: Int[, end: Int]): String
println("abc".substring(1))      // => bc
println("abc".substring(1, 2))   // => b

Char Methods

# toInt

The character's code point. This is `Char`'s conversion, not `String`'s parse: `'5'.toInt` is 53 where `"5".toInt` is 5.

c.toInt: Int
println('a'.toInt)   // => 97
println('5'.toInt)   // => 53

# toChar

The `Char` for a code point, truncated to 16 bits — the round trip back from `Char`'s arithmetic, which produces an `Int`.

n.toChar: Char
println(('a' + 1).toChar)   // => b

# asDigit

The numeric value of a digit character (`Character.digit` at radix 36, so the hex letters count too), or -1 when it is not one.

c.asDigit: Int
println('5'.asDigit)   // => 5

# toUpper

The upper-case `Char`. Answers a `Char`, which is what keeps `s.map(_.toUpper)` a `String`.

c.toUpper: Char
println('a'.toUpper)   // => A
println("abc".map(_.toUpper))   // => ABC

# toLower

The lower-case `Char`.

c.toLower: Char
println('Z'.toLower)   // => z

# isDigit

Whether the character is an ASCII decimal digit. `isLetter`, `isLetterOrDigit`, `isUpper`, `isLower` and `isWhitespace` are the companions.

c.isDigit: Boolean
println('5'.isDigit)   // => true
println('a'.isLetter)   // => true

Int Methods

# abs

The magnitude of the integer.

n.abs: Int
println(-3.abs)   // => 3

# MaxValue

A Scala value-class companion's bound: `Int`, `Long`, `Short`, `Byte`, `Char`, `Double` and `Float` all answer `MaxValue`/`MinValue`, and the two floating ones add `MinPositiveValue`, `PositiveInfinity`, `NegativeInfinity` and `NaN`. `Float`'s are rendered at single precision (`Float.MaxValue` is `3.4028235E38`). These are `scala.Int`'s members, NOT `java.lang.Integer`'s — the two namespaces stay apart, so `Double.parseDouble` is an error here exactly as it is in Scala.

Int.MaxValue: Int
println(Int.MaxValue)   // => 2147483647

# parseInt

A `java.lang.Integer` static: the parses (`parseInt`/`parseLong`/`parseByte`/`parseShort`/`parseUnsignedInt`/`decode`/`valueOf`, most taking an optional radix), the renderings (`toString`, `toUnsignedString`, `toUnsignedLong`), the comparisons (`compare`, `compareUnsigned`, `max`, `min`, `sum`, `signum`, `hashCode`), the unsigned arithmetic (`divideUnsigned`, `remainderUnsigned`) and the bit twiddling (`bitCount`, `reverse`, `reverseBytes`, `highestOneBit`, `lowestOneBit`, `numberOfLeadingZeros`, `numberOfTrailingZeros`, `rotateLeft`, `rotateRight`), plus `MAX_VALUE`/`MIN_VALUE`. Every one of them works at the BOX's own width, so the `java.lang.Long` spelling of the same call can answer differently. A malformed input raises `java.lang.NumberFormatException`; a radix outside 2..36 raises with its own `Character.MIN_RADIX`/`MAX_RADIX` message. `java.lang.Double.parseDouble` and `java.lang.Boolean.parseBoolean` are the other boxes' parsers.

Integer.parseInt(s: String, radix?: Int): Int
println(Integer.parseInt("ff", 16))   // => 255

# toHexString

The two's-complement bit pattern in base 16, at the BOX's width: `Integer.toHexString(-1)` is 8 digits and `java.lang.Long.toHexString(-1L)` is 16. `toBinaryString` and `toOctalString` are the other two, and all three are also `RichInt` methods (`(-1).toHexString`), where the width comes from the receiver's own type. The signed `Integer.toString(i, radix)` renders a `-` instead; `toUnsignedString` renders the same bits with no sign at all.

Integer.toHexString(i: Int): String
println(Integer.toHexString(-1))   // => ffffffff
println((-1L).toHexString)         // => ffffffffffffffff

# isDigit

A `java.lang.Character` static: `isDigit`, `isLetter`, `isLetterOrDigit`, `isWhitespace`, `isUpperCase`, `isLowerCase`, `toUpperCase`, `toLowerCase` and `getNumericValue`.

Character.isDigit(c: Char): Boolean
println(Character.isDigit('5'))   // => true

# valueOf

`java.lang.String.valueOf` — any value's `toString`, which is what `String.valueOf(x)` answers. `String.format(fmt, …)` is the other `String` static.

String.valueOf(x: Any): String
println(String.valueOf(42))   // => 42

# toInt

The receiver unchanged — the identity conversion.

n.toInt: Int
println(5.toInt)   // => 5

# toLong

The receiver as a `Long`. Integers are already held at 64 bits here, so this is the identity.

n.toLong: Long
println(5.toLong)   // => 5

# toDouble

The integer widened to a `Double`, which is how it then prints.

n.toDouble: Double
println(7.toDouble)   // => 7.0

# toFloat

The integer narrowed to a 32-bit `Float`, which rounds: `Int.MaxValue.toFloat` is `2.1474836E9`, not `2.147483647E9`. Distinct from `toDouble`, which is exact for every `Int`.

n.toFloat: Float
println(7.toFloat)          // => 7.0
println(Int.MaxValue.toFloat)   // => 2.1474836E9

# toByte

The low eight bits, sign-extended — the JVM's `i2b`. It TRUNCATES rather than clamping, so the sign can change; the result re-enters arithmetic as an `Int`. A `Double` receiver saturates to an `Int` first and then truncates.

n.toByte: Byte
println(300.toByte)        // => 44
println(128.toByte)        // => -128
println(128.toByte + 1)    // => -127

# toShort

The low sixteen bits, sign-extended — `toByte` one width up.

n.toShort: Short
println(70000.toShort)   // => 4464

# max

The larger of the receiver and the argument, staying an `Int`.

n.max(other: Int): Int
println(5.max(9))   // => 9

# min

The smaller of the receiver and the argument, staying an `Int`.

n.min(other: Int): Int
println(5.min(9))   // => 5

# & (Int)

Bitwise AND of two integers.

n & (other: Int): Int
println(6 & 3)   // => 2

# | (Int)

Bitwise OR of two integers.

n | (other: Int): Int
println(6 | 3)   // => 7

# ^ (Int)

Bitwise XOR of two integers.

n ^ (other: Int): Int
println(6 ^ 3)   // => 5

# unary_~

Bitwise complement, computed at 32-bit width as Scala does. Parenthesize a negative operand — Scala lexes `~-` as a single operator name.

~n: Int
println(~6)   // => -7

# << (Int)

Left shift at `Int` width: the distance masks to five bits and the result wraps at 32 bits, so `1 << 33` is `2`, not `8589934592`.

n << (dist: Int): Int
println(1 << 4)    // => 16
println(1 << 33)   // => 2

# >> (Int)

Arithmetic right shift at `Int` width: the sign bit is replicated, so a negative value stays negative.

n >> (dist: Int): Int
println(-16 >> 2)   // => -4

# >>> (Int)

Logical right shift at `Int` width: zeros are shifted in, so a negative value becomes a large positive one.

n >>> (dist: Int): Int
println(-16 >>> 2)   // => 1073741820

Double Methods

# abs (Double)

The magnitude of the value.

d.abs: Double
println(-2.5.abs)   // => 2.5

# toInt (Double)

Truncate toward zero to an integer — it does not round.

d.toInt: Int
println(2.7.toInt)   // => 2

# toLong (Double)

Truncate toward zero to a `Long`; the same conversion as `toInt` here.

d.toLong: Long
println(2.7.toLong)   // => 2

# toDouble (Double)

The receiver unchanged.

d.toDouble: Double
println(2.5.toDouble)   // => 2.5

# toFloat (Double)

The receiver rounded to 32-bit `Float` precision. The rounding is real and observable by widening it back: `0.1.toFloat.toDouble` is `0.10000000149011612`, not `0.1`. A value that fits exactly is unchanged.

d.toFloat: Float
println(2.5.toFloat)              // => 2.5
println(0.1.toFloat.toDouble)   // => 0.10000000149011612

# isNaN

Whether the value is the not-a-number result of an undefined floating-point operation.

d.isNaN: Boolean
println((0.0 / 0.0).isNaN)   // => true

# isInfinity

Whether the value is positive or negative infinity.

d.isInfinity: Boolean
println((1.0 / 0.0).isInfinity)   // => true

# isInfinite

The `java.lang.Double` spelling of `isInfinity`; the same test.

d.isInfinite: Boolean
println((1.0 / 0.0).isInfinite)   // => true

# round (Double)

Round to the nearest integer, halves away from zero. This is Rust's rounding, not `math.round`'s floor-of-x-plus-a-half — the two differ on a negative half, where `(-2.5).round` is `-3` and `math.round(-2.5)` is `-2`.

d.round: Long
println(2.7.round)   // => 3

Boolean Methods

# & (Boolean)

Non-short-circuiting AND: both operands are evaluated, unlike `&&`.

b & (other: Boolean): Boolean
println(true & false)   // => false

# | (Boolean)

Non-short-circuiting OR: both operands are evaluated, unlike `||`.

b | (other: Boolean): Boolean
println(true | false)   // => true

# ^ (Boolean)

Exclusive OR: true when exactly one operand is true.

b ^ (other: Boolean): Boolean
println(true ^ false)   // => true

# unary_!

Logical negation — the method `!b` calls.

!b: Boolean
println(!true)   // => false

Tuples and Records

# _1

The first element of a tuple. `_1` through `_N` read the elements positionally, and an index past the arity is an error.

t._1: A
println((1, "x")._1)   // => 1

# _2

The second element of a tuple; `_3`, `_4` and so on follow the same rule for as many elements as the tuple has.

t._2: B
println((1, "x")._2)   // => x

# apply (Tuple)

Index a tuple positionally from zero — the method `t(i)` calls. Note this counts from zero while `_1` counts from one.

t.apply(i: Int): Any
println((1, "x")(0))   // => 1

# productArity

How many elements the tuple has.

t.productArity: Int
println((1, 2, 3).productArity)   // => 3

# copy

A case-class instance with named fields replaced and the rest carried over. Named arguments are supported only here, not on general method calls.

c.copy(field = v, …): C
case class P(x: Int, y: Int)
println(P(1, 2).copy(y = 9))   // => P(1,9)

# field access

A paren-less access naming a field of a class instance reads that field. A `val` constructor parameter and a `val` in the body are both reachable this way; an unknown name is `value … is not a member of …`.

instance.field: T
class Box(val n: Int)
println(new Box(3).n)   // => 3

# value

The payload field of a `Some`, and of a `Left`/`Right`. It is the record's field rather than an `Option` method: `get`, `getOrElse`, `map` and `isDefined` all work too, so a field read is the low-level way to open one and `case Some(v)` the idiomatic one.

some.value: A
println(List(1, 2).find(_ > 1).value)   // => 2

# left

The LEFT-biased view of an `Either`. Scala's `Either` is right-biased — `map`, `getOrElse` and the rest operate on the `Right` and pass a `Left` through — so this projection is how the `Left` is reached without a `match`. It answers `get` (which throws `Either.left.get on Right`), `getOrElse`, `map`, `flatMap`, `foreach`, `exists`/`forall`, `toOption`, `toSeq`/`toList` and `filterToOption`, each the mirror of the right-biased member.

e.left: LeftProjection
val e: Either[String, Int] = Left("bad")
println(e.left.getOrElse("none"))   // => bad
println(e.left.map(_.length))       // => Left(3)

# toString (record)

A `case class` renders `Name(f0,f1)` over its primary-constructor parameters only, comma-joined with no space; a plain class renders `Name@<hex>` from its heap handle rather than a JVM identity hash.

c.toString: String
case class P(x: Int, y: Int)
println(P(1, 2))   // => P(1,2)

# equals (record)

A `case class` compares structurally, field by field. A plain class compares by identity, so two separately constructed instances are never equal.

c.equals(other: Any): Boolean
case class P(x: Int)
println(P(1) == P(1))   // => true

# hashCode (record)

A `case class` and a tuple both use the MurmurHash3 product hash, so equal values hash equally and reproduce Scala's own numbers. A plain class uses its heap handle.

c.hashCode: Int
case class P(x: Int)
println(P(1).hashCode == P(1).hashCode)   // => true

Function Values

# =>

The function-literal arrow: `(params) => body`. A single untyped parameter needs no parentheses, and the body may be a block. The value is a closure over the enclosing locals.

(p: T, …) => body
val add = (a: Int, b: Int) => a + b
println(add(1, 2))   // => 3

# _ (placeholder)

The placeholder that makes an expression a one-argument function: `_ * 2` is `x => x * 2`. Each `_` stands for a distinct successive parameter. It expands at the smallest expression that properly CONTAINS it, so it works inside a brace argument (`xs.map { _ * 2 }`) and as a `val`'s initializer (`val f: Int => Int = _ + 1`), while a bare `_` argument expands its enclosing call (`xs.map(f(_))` is `xs.map(x => f(x))`). `(_: Int) + 1` is the typed form — the parentheses carry the ascription, not the boundary.

expr containing _
println(List(1, 2).map(_ * 2))     // => List(2, 4)
println(List(1, 2).map { _ * 2 })  // => List(2, 4)
println(List(1, 2, 3).foldLeft(0) { _ + _ })   // => 6

# { … } (argument)

A brace group standing in for a parenthesized argument clause. It is a BLOCK whose value is the argument, so it may hold several statements and is evaluated once — to produce the function, not once per element. Works on a method (`xs.map { … }`), on a plain call (`once { 7 }`), and on the trailing clause of a curried `def` (`use(3) { _ + 1 }`).

recv.m { … }
println(List(1, 2, 3).filter { _ > 1 })          // => List(2, 3)
println(List(1, 2).map { x => if (x > 1) "hi" else "lo" })   // => List(lo, hi)

# eta-expansion

Naming a `def` where a function value is expected wraps it in a closure automatically, so a method can be passed to `map`, `filter` or any other combinator.

xs.map(namedDef)
def inc(x: Int) = x + 1
println(List(1, 2).map(inc))   // => List(2, 3)

# apply (function)

Invoke a function value — the method `f(x)` calls.

f.apply(args): R
val f = (x: Int) => x + 1
println(f.apply(1))   // => 2

# call

An alias for `apply` on a function value.

f.call(args): R
val f = (x: Int) => x + 1
println(f.call(1))   // => 2

# isDefinedAt

Whether a partial function has an arm matching the argument. A plain lambda is total, so it answers true for everything — matching Scala's implicit `Function1` to `PartialFunction` lift.

pf.isDefinedAt(x: A): Boolean
val pf: PartialFunction[Int, String] = { case 1 => "one" }
println(pf.isDefinedAt(2))   // => false

# applyOrElse

Apply the partial function, or the default when it is not defined at the argument. One `isDefinedAt` test runs and then exactly one body, so no arm runs twice. The default is itself a function of the argument.

pf.applyOrElse(x: A, default: A => B): B
val pf: PartialFunction[Int, String] = { case 1 => "one" }
println(pf.applyOrElse(2, (x: Int) => "no"))   // => no

# lift

Turn a partial function into a total one answering `Some(v)` where it is defined and `None` where it is not. A trailing application is folded into the same call, so `pf.lift(x)` both builds and applies it.

pf.lift: A => Option[B]
val pf: PartialFunction[Int, Int] = { case 1 => 10 }
println(pf.lift(2))   // => None

# orElse

A partial function that tries the receiver and falls back to the argument where the receiver is not defined.

pf.orElse(other: PartialFunction[A, B]): PartialFunction[A, B]
val a: PartialFunction[Int, Int] = { case 1 => 10 }
val b: PartialFunction[Int, Int] = { case 2 => 20 }
println((a orElse b)(2))   // => 20

# andThen

Compose left to right: `(f andThen g)(x)` is `g(f(x))`.

f.andThen(g: B => C): A => C
val f = (x: Int) => x + 1
val g = (x: Int) => x * 2
println((f andThen g)(3))   // => 8

# compose

Compose right to left: `(f compose g)(x)` is `f(g(x))`.

f.compose(g: C => A): C => B
val f = (x: Int) => x + 1
val g = (x: Int) => x * 2
println((f compose g)(3))   // => 7

scala.math

# math.Pi

The ratio of a circle's circumference to its diameter. `Math.PI` is the same constant under the Java spelling.

math.Pi: Double
println(math.Pi)   // => 3.141592653589793

# math.E

The base of the natural logarithm.

math.E: Double
println(math.E)   // => 2.718281828459045

# math.abs

The magnitude of the argument. It stays an `Int` for an integral argument and answers a `Double` otherwise, matching Scala's overload set.

math.abs(x: Int): Int   |   math.abs(x: Double): Double
println(math.abs(-3))     // => 3
println(math.abs(-3.5))   // => 3.5

# math.signum

The sign as `-1`, `0` or `1`. `scala.math.signum` keeps an integral argument integral; `java.lang.Math` has no integer overload, so `Math.signum(-5)` widens to `-1.0` — and this frontend reproduces that split.

math.signum(x: Int): Int   |   Math.signum(x): Double
println(math.signum(-5))   // => -1
println(Math.signum(-5))   // => -1.0

# math.max

The larger of two arguments, staying an `Int` when both are integral and promoting to `Double` otherwise.

math.max(a, b)
println(math.max(2, 3))     // => 3
println(math.max(2, 3.0))   // => 3.0

# math.min

The smaller of two arguments, under the same promotion rule as `max`.

math.min(a, b)
println(math.min(2, 3))   // => 2

# math.round

Round to the nearest integer as the JVM does — floor of `x + 0.5`, so a negative half rounds toward positive infinity. `math.round(-2.5)` is `-2`, where the `Double` method `(-2.5).round` is `-3`.

math.round(x: Double): Long
println(math.round(2.5))    // => 3
println(math.round(-2.5))   // => -2

# math.floor

The largest integral `Double` not greater than the argument.

math.floor(x: Double): Double
println(math.floor(2.7))   // => 2.0

# math.ceil

The smallest integral `Double` not less than the argument.

math.ceil(x: Double): Double
println(math.ceil(2.1))   // => 3.0

# math.rint

Round half to even, which is what `Math.rint` does and what plain rounding does not: `rint(2.5)` is `2.0` and `rint(3.5)` is `4.0`.

math.rint(x: Double): Double
println(math.rint(2.5))   // => 2.0

# math.sqrt

The square root. A negative argument answers NaN rather than raising.

math.sqrt(x: Double): Double
println(math.sqrt(16.0))   // => 4.0

# math.cbrt

The cube root, defined for negative arguments too.

math.cbrt(x: Double): Double
println(math.cbrt(27.0))   // => 3.0

# math.exp

`e` raised to the argument.

math.exp(x: Double): Double
println(math.exp(0.0))   // => 1.0

# math.log

The natural logarithm. Zero answers negative infinity and a negative argument answers NaN.

math.log(x: Double): Double
println(math.log(1.0))   // => 0.0

# math.log10

The base-10 logarithm.

math.log10(x: Double): Double
println(math.log10(100.0))   // => 2.0

# math.pow

The first argument raised to the second. The result is always a `Double`, even for two integral arguments.

math.pow(x: Double, y: Double): Double
println(math.pow(2, 10))   // => 1024.0

# math.hypot

The length of the hypotenuse, computed without intermediate overflow.

math.hypot(x: Double, y: Double): Double
println(math.hypot(3, 4))   // => 5.0

# math.sin

The sine of an angle in radians.

math.sin(x: Double): Double
println(math.sin(0.0))   // => 0.0

# math.cos

The cosine of an angle in radians.

math.cos(x: Double): Double
println(math.cos(0.0))   // => 1.0

# math.tan

The tangent of an angle in radians.

math.tan(x: Double): Double
println(math.tan(0.0))   // => 0.0

# math.asin

The arc sine in radians. An argument outside `[-1, 1]` answers NaN.

math.asin(x: Double): Double
println(math.asin(0.0))   // => 0.0

# math.acos

The arc cosine in radians.

math.acos(x: Double): Double
println(math.acos(1.0))   // => 0.0

# math.atan

The arc tangent in radians, in the range `(-Pi/2, Pi/2)`.

math.atan(x: Double): Double
println(math.atan(0.0))   // => 0.0

# math.atan2

The angle of the point `(x, y)` from the positive x-axis, taking the quadrant from both signs. The arguments are `(y, x)` in that order.

math.atan2(y: Double, x: Double): Double
println(math.atan2(0.0, 1.0))   // => 0.0

# math.toRadians

Convert degrees to radians.

math.toRadians(deg: Double): Double
println(math.toRadians(180.0))   // => 3.141592653589793

# math.toDegrees

Convert radians to degrees.

math.toDegrees(rad: Double): Double
println(math.toDegrees(math.Pi))   // => 180.0

Throwables

# Throwable

The root of the modelled hierarchy, printed `java.lang.Throwable`. `case e: Throwable` catches everything — including a thrown user object that is outside this hierarchy.

new Throwable([msg: String])
try { throw new RuntimeException("x") } catch { case e: Throwable => println("caught") }   // => caught

# Exception

The recoverable branch of the hierarchy, printed `java.lang.Exception`. Note that a user class declared `extends Exception` is NOT caught by `case e: Exception`: a user class joins the class registry, not the throwable hierarchy, so only its own name (or a bare `case e`) catches it.

new Exception([msg: String])
try { throw new IllegalStateException("x") } catch { case e: Exception => println("caught") }   // => caught

# Error

The unrecoverable branch, printed `java.lang.Error`. It is a sibling of `Exception`, so `case e: Exception` does not catch it.

new Error([msg: String])
try { throw new Error("boom") } catch { case e: Error => println(e.getMessage) }   // => boom

# RuntimeException

The unchecked branch under `Exception`, and the parent of most exceptions the runtime raises on its own.

new RuntimeException([msg: String])
try { throw new RuntimeException("m") } catch { case e: RuntimeException => println(e) }   // => java.lang.RuntimeException: m

# ArithmeticException

Raised by integer `/` and `%` with a zero divisor, carrying the JVM's `/ by zero` message. Floating-point division by zero answers infinity instead and never throws.

new ArithmeticException([msg: String])
println(try { 1 / 0 } catch { case _: ArithmeticException => -1 })   // => -1

# IllegalArgumentException

Raised by a zero range step (`step cannot be 0.`) and by `grouped`/`sliding` with a size below one (`requirement failed: size=n`).

new IllegalArgumentException([msg: String])
println(try { (1 to 3 by 0).toList } catch { case e: IllegalArgumentException => e.getMessage })   // => step cannot be 0.

# IllegalStateException

A constructible member of the hierarchy under `RuntimeException`. The runtime never raises it on its own.

new IllegalStateException([msg: String])
try { throw new IllegalStateException("bad") } catch { case e: RuntimeException => println(e) }   // => java.lang.IllegalStateException: bad

# NumberFormatException

Raised by `toInt` and `toDouble` on a string they cannot parse, with the JDK's `For input string: "…"` message. It sits under `IllegalArgumentException`, so that arm catches it too.

new NumberFormatException([msg: String])
try { "z".toInt } catch { case e: NumberFormatException => println(e.getMessage) }   // => For input string: "z"

# IndexOutOfBoundsException

Raised by sequence and tuple `apply` with the bare index as the message, and by a buffer's `remove`/`insert` with the JDK's longer form.

new IndexOutOfBoundsException([msg: String])
println(try { List(1, 2)(5) } catch { case e: IndexOutOfBoundsException => e.getMessage })   // => 5

# StringIndexOutOfBoundsException

Raised by `charAt` out of range and by `substring` on an out-of-range or inverted range, each with the JDK's exact message.

new StringIndexOutOfBoundsException([msg: String])
println(try { "abc".charAt(9) } catch { case e: IndexOutOfBoundsException => "oob" })   // => oob

# ArrayIndexOutOfBoundsException

Raised by an out-of-range `Array` write (`a(i) = v`), carrying `Index i out of bounds for length n`.

new ArrayIndexOutOfBoundsException([msg: String])
val a = Array(1)
println(try { a(5) = 0; "ok" } catch { case e: IndexOutOfBoundsException => "oob" })   // => oob

# NullPointerException

A constructible member under `RuntimeException`. Null is a plain value here rather than a trapped dereference, so the runtime does not raise this on its own.

new NullPointerException([msg: String])
try { throw new NullPointerException() } catch { case e: RuntimeException => println(e) }   // => java.lang.NullPointerException

# ClassCastException

A constructible member under `RuntimeException`. `asInstanceOf` is a no-op here, so no cast raises it — only an explicit `throw` does.

new ClassCastException([msg: String])
try { throw new ClassCastException("x") } catch { case e: ClassCastException => println(e.getMessage) }   // => x

# UnsupportedOperationException

Raised by `min`, `max`, `minBy`, `maxBy`, `reduce*` and `tail` on an empty collection, with the `empty.<op>` message Scala uses.

new UnsupportedOperationException([msg: String])
println(try { List().max } catch { case e: UnsupportedOperationException => e.getMessage })   // => empty.max

# NoSuchElementException

Raised by `head` and `last` on an empty collection. Its package is `java.util`, not `java.lang`, which is observable through `toString`.

new NoSuchElementException([msg: String])
println(try { List().head } catch { case e: NoSuchElementException => e.getMessage })   // => head of empty list

# MatchError

Raised when no `match` arm accepts the scrutinee, carrying `<value> (of class <boxed JVM class>)`. Its package is `scala`, and it sits under `RuntimeException`.

new MatchError([msg: String])
println(try { 2 match { case 1 => "one" } } catch { case e: MatchError => "no arm" })   // => no arm

# getMessage

The message a throwable was constructed with, or `null` for the no-argument constructor.

e.getMessage: String
println(new RuntimeException("m").getMessage)   // => m

# getLocalizedMessage

The same message as `getMessage`; there is no localization layer.

e.getLocalizedMessage: String
println(new RuntimeException("m").getLocalizedMessage)   // => m

# toString (throwable)

The fully-qualified class name, followed by `: message` when there is one. This is what `println(e)` prints.

e.toString: String
println(new IllegalStateException("x"))   // => java.lang.IllegalStateException: x

# user exception class

A user class may be thrown and caught, but it does not join the modelled throwable hierarchy even when it is declared `extends Exception`. Only its own name or a bare `case e` catches it, and `case e: Exception` lets it escape.

class MyErr(msg: String) extends Exception(msg)
class MyErr(msg: String) extends Exception(msg)
object T extends App {
  try { throw new MyErr("boom") } catch { case e: MyErr => println("caught") }   // => caught
}

Operators

# +

Numeric addition, or String concatenation when either operand is a String. On a `Set` it is `incl`; on a `Map` it adds a pair.

a + b
println("n=" + 41)   // => n=41

# -

Numeric subtraction, and as a prefix the negation. On a `Set` it is `excl`; on a `Map` it removes a key. A prefix `-` on a numeric literal folds into the value, so `-3.abs` is `3`.

a - b   |   -a
println(3 - 1)   // => 2

# *

Numeric multiplication.

a * b
println(3 * 2)   // => 6

# /

Division: truncating toward zero for two `Int`s, floating when either operand is a `Double`. Integer division by zero raises `ArithmeticException: / by zero`.

a / b
println(7 / 2)     // => 3
println(7 / 2.0)   // => 3.5

# %

Remainder of division, taking its sign from the dividend as on the JVM.

a % b
println(7 % 3)   // => 1

# ==

Structural equality. Scala's `==` is value `equals`, so strings and case classes compare by content; a plain class compares by identity.

a == b
println("a" == "a")   // => true

# !=

The negation of `==`.

a != b
println(1 != 2)   // => true

# <

Numeric less-than.

a < b
println(1 < 2)   // => true

# >

Numeric greater-than.

a > b
println(2 > 1)   // => true

# <=

Numeric less-than-or-equal.

a <= b
println(1 <= 1)   // => true

# >=

Numeric greater-than-or-equal.

a >= b
println(2 >= 3)   // => false

# &&

Short-circuiting logical AND: the right operand is not evaluated when the left is false.

a && b
println(true && false)   // => false

# ||

Short-circuiting logical OR: the right operand is not evaluated when the left is true.

a || b
println(false || true)   // => true

# !

Prefix logical negation.

!a
println(!true)   // => false

# &

Bitwise AND on `Int`, non-short-circuiting AND on `Boolean`, intersection on `Set`. It binds tighter than `^` and `|`.

a & b
println(6 & 3)                          // => 2
println(Set(1, 2, 3) & Set(2, 3, 4))   // => Set(2, 3)

# |

Bitwise OR on `Int`, non-short-circuiting OR on `Boolean`, union on `Set`. It is the loosest-binding symbolic operator, which is where `||` gets its precedence.

a | b
println(6 | 3)       // => 7
println(5 & 3 | 2)   // => 3

# ^

Bitwise XOR on `Int`, exclusive OR on `Boolean`. It binds between `|` and `&`.

a ^ b
println(6 ^ 3)   // => 5

# ~

Prefix bitwise complement of an `Int`, at 32-bit width. Parenthesize a negative operand — Scala lexes `~-` as one operator name.

~a
println(~6)   // => -7

# <<

Left shift, evaluated at `Int` width: the distance masks to five bits and the result wraps at 32 bits, so `1 << 33` is `2`. It binds looser than `+`, so `1 << 2 + 1` is `8`.

a << b
println(1 << 4)   // => 16

# >>

Arithmetic right shift at `Int` width, replicating the sign bit.

a >> b
println(-16 >> 2)   // => -4

# >>>

Logical right shift at `Int` width, shifting in zeros.

a >>> b
println(-16 >>> 2)   // => 1073741820

# ::

Cons: prepend an element to a `List`. Its name ends in `:`, so it is right-associative and dispatches on its right operand — `1 :: 2 :: Nil` is `1 :: (2 :: Nil)`.

e :: xs
println(1 :: 2 :: Nil)   // => List(1, 2)

# :+

Append one element to a sequence, answering a copy in the receiver's kind.

xs :+ e
println(List(1, 2) :+ 3)   // => List(1, 2, 3)

# +:

Prepend one element to a sequence. Its name ends in `:`, so it is right-associative and dispatches on the sequence.

e +: xs
println(0 +: List(1, 2))   // => List(0, 1, 2)

# ++

Concatenate two collections, keeping the receiver's kind. On a `Set` the result is re-deduplicated; on a `Map` it merges the entries.

xs ++ ys
println(List(1, 2) ++ List(3))   // => List(1, 2, 3)

# --

Remove every element of the argument — the operator form of `diff`.

xs -- ys
println(List(1, 2, 3) -- List(2))   // => List(1, 3)

# &~

Set difference: the receiver's elements that are not in the argument. It binds at `&`'s level, since the first character decides precedence.

s &~ t
println(Set(1, 2, 3) &~ Set(2))   // => Set(1, 3)

# ->

Build a two-element tuple. It is what a `Map` literal's entries are made of, and it binds looser than every symbolic operator and than alphanumeric infix.

k -> v
println("a" -> 1)   // => (a,1)

# =

Assignment to a `var`, or an element write through `xs(i) = v` (which calls `update`). Assigning to a `val` is rejected at compile time.

name = expr   |   xs(i) = v
var n = 1
n = 2
println(n)   // => 2

# +=

Compound add-assign on a `var`, and in-place addition on a mutable collection.

n += e
var n = 0
n += 5
println(n)   // => 5

# -=

Compound subtract-assign on a `var`, and in-place removal on a mutable collection.

n -= e
var n = 5
n -= 2
println(n)   // => 3

# *=

Compound multiply-assign on a `var`.

n *= e
var n = 3
n *= 4
println(n)   // => 12

# /=

Compound divide-assign on a `var`, truncating for two `Int`s.

n /= e
var n = 12
n /= 4
println(n)   // => 3

# %=

Compound remainder-assign on a `var`.

n %= e
var n = 7
n %= 3
println(n)   // => 1

# alphanumeric infix

A one-argument method may be written without a dot: `a m b` is `a.m(b)`. It binds looser than every symbolic operator and is left-associative, so `xs map f filter g` is `(xs.map(f)).filter(g)`. A line break between receiver and name rules the infix reading out, and Scala's soft keywords are excluded from it.

a method b
println(List(1, 2) map (_ * 2))   // => List(2, 4)

Predef and Interpolation

# println

Print one Scala-formatted argument followed by a newline, and answer Unit. A `Double` prints with a trailing `.0` when it is integral, as Scala does.

println(x: Any): Unit
println(3.0)   // => 3.0

# print

Print one Scala-formatted argument with no trailing newline.

print(x: Any): Unit
print("a"); print("b")   // => ab

# s"…"

The standard interpolator: `$name` and `${expr}` splices are evaluated and rendered with the same formatting `println` uses. Backslash escapes are decoded.

s"text $name text ${expr}"
println(s"a${1 + 1}b")   // => a2b

# f"…"

The formatting interpolator: each splice may carry a trailing `%…` conversion, applied through the same formatter `String.format` would use.

f"${expr}%spec"
println(f"${3.14159}%.2f")   // => 3.14

# raw"…"

The raw interpolator: splices are still evaluated but backslash escapes are kept literal, so `raw"\n"` is a backslash followed by `n`.

raw"text\n$name"
println(raw"a\nb")   // => a\nb

# format specs

The conversions an `f"…"` splice accepts: `%d` integer, `%f` fixed-point (default six decimals), `%e` scientific, `%s` string, `%x`/`%o` radix, `%%` a literal percent — with the usual width, `-` left-justify, `0` zero-pad and `.n` precision flags. Note that `String.format` as a method is not implemented; use an `f` interpolator.

f"${x}%[flags][width][.prec]conv"
println(f"${7}%05d")   // => 00007

# rust { … }

An inline Rust block: its body is compiled to a cdylib and its `extern "C"` functions become callable from Scala code. The compile result is cached, so only the first run pays for it.

rust { pub extern "C" fn name(x: i64) -> i64 { … } }
rust { pub extern "C" fn triple(x: i64) -> i64 { x * 3 } }
println(triple(5))   // => 15

More