James Earl Douglas
August 29, 2021
Linear types ensure that values are "used" exactly once. More on this later.
Enforcing single-usage can prevent certain kinds of runtime errors.
x
is which?x
is 8
, but is it meant to be 6
?
8*7
, but is it meant to produce
6*7
?
x
bindings be deleted?
How can we catch this shadowing bug at compile time?
for {
x <- Some(6.asInstanceOf[Int with Linear])
y <- Some(7.asInstanceOf[Int with Linear])
x <- Some(8.asInstanceOf[Int with Linear])
} yield x * y
The Linear
interface comes from linear-scala.
Linear types ensure that values are used exactly once.
What does "used" mean?
For our purposes, "used" simply means "dereferenced".
Other definitions, such as Linear Haskell, are more sophisticated.
(f x)
is "consumed" exactly once, then x
is
consumed exactly once
f
can only be called once
We can write custom linting rules with Scalafix to access to our code's AST through the Scalameta Trees API.
For implementation, see LinearTypes.scala in linear-scala.
For examples, see input/src/main/scala/fix/ in linear-scala.
Linear types can help us write code with fewer bugs.