Matthew Pickering & Arnaud Spiwack

Linearity on the arrow

a \rightarrow b\\ a \multimap b

type of linear functions

can be any type

$$f$$ linear
$$\iff$$

$$f u$$ consumed once $$\Rightarrow$$ $$u$$ consumed once

Linearity, not uniqueness

Backwards compatible

## Multiplicity polymorphism

a \rightarrow_\pi b

$$a \rightarrow b = a \rightarrow_\omega b$$

$$a \multimap b = a \rightarrow_1 b$$

$$a \rightarrow_p b$$: polymorphic

Instances

Properties

Semiring ( e.g. $$a*(b+c) = a*b + a*c$$)
Ordered ( e.g. $$a\leqslant c \Rightarrow a+b\leqslant c+b$$)

Joins ( i.e. $$a\vee b\leqslant c \iff a\leqslant c \wedge b\leqslant c$$)

$$\pi \leqslant \omega$$

## Typing rules

\cfrac { \Gamma \vdash f : \alpha \rightarrow_{\color{blue}\pi} \tau \quad \Delta \vdash u : \alpha } { \Gamma \mathbin{\color{darkorange}+} {\color{blue}\pi} \mathbin{\color{darkorange}*} \Delta \vdash f\,u : \tau }
\cfrac { \Gamma, x:_{\color{blue}\pi} \alpha \vdash u : \tau } { \Gamma \vdash \lambda x:_{\color{blue}\pi} \alpha. u : \alpha \rightarrow_{\color{blue}\pi} \tau }

## A type-checking algorithm

\cfrac { \Gamma \vdash f : \alpha \rightarrow_{\color{blue}\pi} \tau \leadsto U \quad \Gamma \vdash u : \alpha \leadsto V} { \Gamma \vdash f\,u : \tau \leadsto U \mathbin{\color{darkorange}+} {\color{blue}\pi} \mathbin{\color{darkorange}*} V}
\cfrac { \Gamma, x:\alpha \vdash u : \tau \leadsto (x\mapsto{\color{blue}\rho}, U) \quad {\color{blue}\rho} \mathrel{\color{darkorange}\leqslant}{\color{blue}\pi} } { \Gamma \vdash \lambda x:_{\color{blue}\pi} \alpha. u : \alpha \rightarrow_{\color{blue}\pi} \tau \leadsto U}

## Multiplicity data type

data Mult
= Zero
| One
| Omega
| Mult MultAdd Mult
| Mult MultMul Mult
| MultTy Type
data Weighted a
= Weighted Mult a
Weighted Type
Type

often

variables are mere type variables

data Multiplicity
= Omega
| One

Multiplicities as a type

## FunTy

(\rightarrow_\cdot)
FunTyCon :: Type
FunTy :: Mult -> Type -> Type -> Type
a \rightarrow_\pi b

Arguments:

RuntimeRep*2, Mult, Type*2

## Propagating to Core

data Var
= …
| Id {…
varType :: Type,
varMult :: Mult }

This is new

data Coercion
= …
| FunCo Role Coercion Coercion Coercion


New: multiplicity coercion

## Core transformations

\def\let{\mathop{\color{teal}\mathsf{let}}} \def\in{\mathbin{\color{darkmagenta}\mathsf{in~}}} \def\mult{\color{blue}} \let x_{\mult\pi} = \let y_{\mult\rho} = u \in v \in e\\ \Longrightarrow \phantom{a}\\ \let y_{\mult\pi*\rho} = u \in \let x_{\mult\pi} = v \in e
\def\let{\mathop{\color{teal}\mathsf{let}}} \def\in{\mathbin{\color{darkmagenta}\mathsf{in~}}} \def\mult{\color{blue}} \let x_{\phantom{\mult\pi}} = \let y_{\phantom{\mult\rho}} = u \in v \in e\\ \Longrightarrow \phantom{a}\\ \let y_{\phantom{\mult\pi*\rho}} = u \in \let x_{\phantom{\mult\pi}} = v \in e

## The Float Out incident

\def\let{\mathop{\color{teal}\mathsf{let}}} \def\in{\mathbin{\color{darkmagenta}\mathsf{in~}}} \def\case{\mathop{\color{teal}\mathsf{case}}} \def\of{\mathbin{\color{darkmagenta}\mathsf{of~}}} \def\mult{\color{blue}} \case u \of x_{\mult\pi}~\{ … ; pat \rightarrow \let y_{\mult\rho} = v \in e; … \} \\ \Longrightarrow \phantom{a}\\ \let y_{\mult??} = v \in \case u \of x_{\mult\pi}~\{ … ; pat \rightarrow e; … \}

(and inlining, and CSE,…)

\def\let{\mathop{\color{teal}\mathsf{let}}} \def\in{\mathbin{\color{darkmagenta}\mathsf{in~}}} \def\case{\mathop{\color{teal}\mathsf{case}}} \def\of{\mathbin{\color{darkmagenta}\mathsf{of~}}} \def\mult{\color{blue}} \case u \of x_{\phantom{\mult\pi}}~\{ … ; pat \rightarrow \let y_{\phantom{\mult\rho}} = v \in e; … \} \\ \Longrightarrow \phantom{a}\\ \let y_{\phantom{\mult??}} = v \in \case u \of x_{\phantom{\mult\pi}}~\{ … ; pat \rightarrow e; … \}

## Alias-like binders

\def\let{\mathop{\color{teal}\mathsf{let}}} \def\in{\mathbin{\color{darkmagenta}\mathsf{in~}}} \def\case{\mathop{\color{teal}\mathsf{case}}} \def\of{\mathbin{\color{darkmagenta}\mathsf{of~}}} \def\mult{\color{blue}} \dfrac { \Gamma \vdash u : \alpha \leadsto {\mult U} \quad \Gamma, x:_{\mult U} \alpha \vdash e: \tau \leadsto {\mult V} } { \Gamma \vdash \let x : \alpha = u \in e : \tau \leadsto {\mult V}}

## Pushing coercions

\def\let{\mathop{\color{teal}\mathsf{let}}} \def\in{\mathbin{\color{darkmagenta}\mathsf{in~}}} \def\case{\mathop{\color{teal}\mathsf{case}}} \def\of{\mathbin{\color{darkmagenta}\mathsf{of~}}} \def\mult{\color{blue}} (f \rhd co)\,u \Longrightarrow (f\,(u \rhd co_{arg})) \rhd co_{res}

What happened to $$co_{mult}$$‽ Bad! bad! bad!

Only push coercion when $$co_{mult} = \mathsf{refl}$$.

data Coercion
= …
| FunCo Role Coercion Coercion Coercion


## Wrapper for all

\mathsf{Just} : \forall a. a \multimap \mathsf{Maybe}\,a
\mathsf{Just} : \forall p\,a. a \rightarrow_p \mathsf{Maybe}\,a

This is key!

When used as a term.
Crucial for backwards compatibility

"inferred": doesn't affect visible type applications

Implemented as a wrapper

## Strictness analysis: CPR

$wf :: A -> (# C, D #) f :: A -> B f x = case$wf x of
(# y, z #) -> B y z

Linear: $$\verb|wf x|$$ is consumed exactly once.

But what if $$\mathsf{B} : a \multimap b \rightarrow B$$ ?

Then we need $$\verb|(#,#)| : a \multimap b \rightarrow \verb|(#|a,b\verb|#)|$$

Later! For now, deactivate CPR when not all fields linear

https://github.com/tweag/ghc/tree/linear-types

https://github.com/ghc-proposals/ghc-proposals/pull/111