Let us take a brief excursion and apply the skills and techniques learned so far to analysing the notion of “dynamic typing”.
- model a dynamic language (remember: syntax, statics, dynamics). PFPL 18.
- consider correspondence to the typing approrach we’ve seen so far. PFPL 19.
What is “dynamic typing”?
- “safe” (for some value of the word “safe”).
- just runs – syntax (all but) defines the language (minimal or no statics).
- values cary their classification at runtime.
Let’s model a dynamic language!
A Theory of Dynamic Typing
language: PCF with one type:
Two classes of values: numbers and functions.
are not values.
Statics: trivial, just check for erroneous free variables.
x1 ok, ..., xn ok |- d ok
Dynamics: see book (rules 18.1 - 18.4).
what is guaranteed by this language?
Lemma: class checking
d val then
- either d
is_numn for some n, or d
- either d
is_funx.d’, or d
Pf: shallow case analysis of the rules for d
Theorem: Progress (=safety).
If d ok, then either d val or d err, or there exists d’ such that d
Case d = succ(d’). Need to use Lemma 18.1.
Meaning… execution is well defined! This is the essential differentiation between safe and unsafe. Even though errors can occur in Dynamic PCF, executation is fully defined.
d ::= nil | cons(d1;d2) | ifnil(d; d0; x,y.d1)
What should the dynamics be? Can we take the same approach as for numbers where we have a class of actual numbers? Doesn’t scale. So, need to weaken
ifnil to delay error checking. We can now
easily form nonsensical lists and
ifnil won’t catch the error right away.
cons(zero; cons(zero; \(x) x))
Dynamic language designers are not “lazy type theorists” – type theorists who didn’t want to bother building a proper type checker. They think about languages differently.
Specifically, tagged values, or classes – no canonical forms lemma. So, we drop specialized “if” constructs in favor of a general conditional, predicates and deconstructors:
d ::= cond(d; d0; d1) | zero?(d) | succ(d)? | nil?(d) | cons?(d) | pred(d) | car(d) | cdr(d)
Conditional distinguishes between
nil and anything else, where
nil corresponds to “false”.
Example: list append function.
fix append is \(x) \(y) cond(x; cons(car(x); append(cdr(x))(y)); y)
WARNING: discussions of static vs. dynamic typing are littered with strawman arguments (on both sides!). Unfortunately, few actually understand the underlying theory well enough to make an informed argument.
Disadvantages of dynamic typing:
- Late debugging
- Cost of tags and/or cost of “smart” compiler which can optimize to (somewhat) make up for the cost of the language design.
Example: addition function (section 18.3)
Some related reading:
- Abada et al. Dynamic Typing in a Statically Typed Language
- Henglein. Dynamic Typing: Syntax and Proof Theory