Definitions
- Substitution in term:
- Beta = eval, alpha = rename arg
- Call-by-name, i.e., lazy: no reductions inside abstractions.
- Call-by-value, i.e., strict: outermost application reduced, application only occurs if right-hand side is value (var or lambda, not another application).
- Y combinator:
fix = λf. (λx. f (x x)) (λx. f (x x))
- de Brujin indices:
becomes . - Non-value normal forms are stuck. Run-time error.
- A well-typed term is normalizing iff it’s guaranteed to halt in finite steps.
Simply-typed lambda calculus
- Type safety = progress (well-typed term not stuck) + preservation (after eval, still well-typed)
- Well-typed term can make eval progress, well-typedness is preserved in eval
- Curry-Howard: types are propositions, programs are proofs.
Eval: evaluate either side of application, then do substitution
Typing: variable type, lambda introduction and elimination
Big step eval
Link to original\begin{prooftree} \AXC{$t_{1} \Downarrow true$} \AXC{$t_{2} \Downarrow v_{2}$} \BIC{$\verb|if t1 then t2 else t3| \Downarrow v_{3}$} \end{prooftree}
Extensions
Simple ones
- Derived forms & elaboration:
iff , iff . - Type ascription (
x as T
): evaluation removes ascription, introduction rule gives expr typeT
. - Let binding: evals as substitution. Can be defined as sugar on typing derivation (transform into application of function), since we need extra info about type of let-bound var
- Tuples: records w/ projection. Eval rules for projection and if subpart of record evals. Typing for introduction and delimination.
- Variants: tag
<l = t> as T
and pattern match. Intro and elim (pattern match) - Recursion:
- Diverges!
References
- Introduction with
ref val
, elimination with dereferencing!val
- Internally, we have a new location value
, used for type-checking and eval. - Evaluation is with respect to a store
- Substitution for stores:
-
Typing with respect to
and .
- Do this for performance (don't need to typecheck reference every time) and to enable cyclic refs.
Exceptions
- Multiple ways of modeling:
- Panic:
, - try-catch: standard
- exceptions with values:
instead of .
- Panic:
See 2024-06-26 • type system extensions.
Java-type beat
Subtyping
- Subsumption:
- Records: width (records with more fields), depth (subtype between same field), permutation (order doesn’t matter)
- Functions: contravariant (reversed) on first arg, covariant on second
must be usable at least wherever is.
- Ascription: upcast to supertype, downcast to subtype (assume during typechecking, evaluation only works if the type matches the downcast)
- References: invariant (both contra- and covariant on argument). Need covariance on read, contravariance on write.
- Coercion: maybe
even if they have different reprs, values. We can define a function that transforms typing derivations into terms with runtime coercions. - Make sure we have coherence: different coercion paths yield same behavior
- Intersection, union types
See 2024-06-26 • type system extensions.
Imperative objects in STLC
- What the fuck is OOP
- Multiple representations: An abstract data type (ADT) has an interface. Different classes can implement that interface, even if they have different internals.
- Encapsulation: hide object’s internals, only expose
public
operations. - Open recursion via
self
and inheritance.
- We store instance variables with a representation type: a record with instance variables. Each instance variable maps to a reference containing that var’s state.
- A class is represented as a function that takes the instance variables, returning a record of functions that act on those vars.
- A class instance is that class function applied to a representation type.
- We can call superclass methods by let-binding to a superclass instance in the subclass
- Constructors create a new repr type and class and return the package.
- We can get
self
by adding an argumentself
to our class functions.self
must have typeUnit -> Class
, to avoid diverging.- We create an initially empty reference
cAux : Ref (Unit -> Class)
to the current class instance, bindingcAux := (whateverClass vars cAux)
in the constructor for the class.