# Lecture 010

## Static and Dynamic Typing

Soundness Theorem: for all expression $E$,

• dynamic_type(E) = static_type(E) (if no inheritance)

• for all E, dynamic_type(E) <= static_type(E) (if inheritance, one consequence is that you can only add methods to children types and can only override methods without changing its type)

Dynamic Typing: one symbol can be different types at different time during the execution of the program.

A symbol will have both a static type that is decided at compile time and a dynamic type that is decided at runtime.

## Self-Type

Consider the following code

class Count {
i : int <- 0;
int () : Count {
{
i <- i + 1;
self;
}
}
}

class Stock inherits Count {
name : String;
}

class Main {
Stock a <- (new Stock).inc()
}


In above code, when (new Stock).inc() is run, it return an object that has static type Count and not the type Stock. Therefore this line will not type check although the dynamic type is correct. We can fix this issue by letting .inc() return a SELF_TYPE.

SELF_TYPE is a static type and not a class name

If a SELF_TYPE appear in the Class C, then we can say $\text{SELF\_TYPE}_C \leq C$

Rules for SELF_TYPE

• $\text{SELF\_TYPE}_C \leq \text{SELF\_TYPE}_C$

• $\text{SELF\_TYPE}_C \leq T$ if $C \leq T$

• $T \leq \text{SELF\_TYPE}_C$ is always false (because $T$ might not be the child of child of $C$)

• $\text{lub}(T, \text{SELF\_TYPE}_C) = \text{lub}(C, T)$

SELF_TYPE appear

• cannot write class SELF_TYPE inherits T {...}

• cannot write class T inherits SELF_TYPE {...}

• can write X : SELF_TYPE

• can write let x : SELF_TYPE in E

• can write new : SELF_TYPE (create an object that has same dynamic type of self)

• cannot write [email protected]_TYPE(E1, ..., En)

• can write m(x : T) : SELF_TYPE {...}

• cannot write m(x : SELF_TYPE) : SELF_TYPE {...}

To see why the last statement is true, consider the following code:

Note that the return type is T0 not T in static dispatch.

### Error Recovery

To Recover: A simple solution might be to assign type Object to any type that is undefined or error. However, this will lead to cascading error.

Another method is to introduce Notype by define Notype < C for every type C and all operation is defined on Notype. So only the first error will be generated. Note that the introduction of Notype will make our type system not a tree, which will be harder to implement.

Table of Content