Dynamic Typing

Let us take a brief excursion and apply the skills and techniques learned so far to analysing the notion of “dynamic typing”.

Two steps:

What is “dynamic typing”?

  1. “safe” (for some value of the word “safe”).
  2. just runs – syntax (all but) defines the language (minimal or no statics).
  3. values cary their classification at runtime.

Let’s model a dynamic language!

A Theory of Dynamic Typing

language: PCF with one type: dyn.

Syntax:

Two classes of values: numbers and functions. zero and succ(d) 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).

Properties

what is guaranteed by this language?

Lemma: class checking

If d val then

  1. either d is_num n for some n, or d isnt_num.
  2. either d is_fun x.d’, or d isnt_fun.

Pf: shallow case analysis of the rules for d val.

Theorem: Progress (=safety).

If d ok, then either d val or d err, or there exists d’ such that d -> 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.

Extension: lists

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.

Example

cons(zero; cons(zero; \(x) x))

Reality check

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)

Critique

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:

  1. Late debugging
  2. 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)

Notes:

Some related reading:

  1. Abada et al. Dynamic Typing in a Statically Typed Language
  2. Henglein. Dynamic Typing: Syntax and Proof Theory
Edit