Professional Documents
Culture Documents
Types For Units of Measure: Andrew Kennedy Microsoft Research
Types For Units of Measure: Andrew Kennedy Microsoft Research
Motivation
Types catch errors in programs Programs written in type-safe programming languages cannot crash the system But there are errors that (currently) they dont catch:
out-of-bounds array accesses division by zero taking the head of an empty list adding a kilogram to a metre
Better: add special units types to the language and type-check w.r.t. algebraic properties of units.
But what about generic functions (e.g. mean and standard deviation of a list of quantities). What types do they have?
Units vs Dimensions
Dimensions are classes of interconvertible units e.g.
lb, kg, tonne are all instances of mass m, inch, chain are all instances of length
Polymorphism
Take ML/Haskell as our model, where functions are parametric in their types e.g.
length map : 'a list -> int : ('a -> 'b) -> ('a list -> 'b list)
Arithmetic
Now the built-in arithmetic functions can be assigned polymorphic types:
+ * / < sqrt sin : : : : : : : 'u num * 'u num -> 'u num 'u num * 'u num -> 'u num 'u num * 'v num -> ('u*'v) num 'u num * 'v num -> ('u/'v) num 'u num * 'u num -> bool ('u^2) num -> 'u num 1 num -> 1 num (angles are dimensionless ratios)
Curiosity: zero should be polymorphic (it can have any units), all other constants are dimensionless (they have no units).
where =E is the equational theory of Abelian groups over units of measure lifted to type expressions.
Extend the usual rules for polymorphism introduction & elimination to quantify over unit variables.
Type inference
ML and Haskell have the convenience of decidable type inference: if the programmer omits types then the type checker can infer them e.g.
fun head (x::xs) = x
Principal types
The units type system has the principal types property: if e is typeable there exists type such that all valid types can be derived by substituting unit expressions for unit variables in .
moreover, the inference algorithm will find the principal type.
Fix: first normalise the types in the type environment, a procedure akin to a change of basis.
Principal units types can have many non-trivial equivalent forms e.g.
'u num * ('u num -> 'v num) -> ('u num -> ('v/'u) num) 'u num * ('u num -> ('u*'v) num) -> ('u num -> 'v num)
Its desirable to present types consistently to the programmer. Fortunately every type has a normal form that corresponds to the Hermite Normal Form from linear algebra.
Semantics of polymorphism
The polymorphic type of a function says something about the behaviour of the function. This is idea has become known as parametricity and is very powerful. Examples:
if f : 'a list -> int then f cannot look at the elements of the list, so f (xs) = g (length(xs)) for some g : int -> int. if f : 'a -> 'a then f must be the identity function (or else it diverges or raises an exception). there are no total functions with type int -> 'a in the polymorphic lambda calculus, T is isomorphic to (T -> 'a) -> 'a.
Consequences
Theorems for free e.g.
if f : 'u num -> ('u^2) num then f (k*x) = k*k*f(x) for any positive k
There are types for which no non-trivial expressions can be defined e.g.
if only the usual arithmetic primitives are available (+ - * /), then any expression of type ('u^2) num -> 'u num does not return a non-zero result for any argument.
Dimensional analysis
Old idea: given some physical system with known variables but unknown equations, use the dimensions of the variables to determine the form of the equations. Example: a pendulum.
l m g period t
l ( ) for some g
Worked example
Pendulum has five variables: mass m length l gravity g angle time period t
M L LT-2 none T
Assume some relation f(m, l, g, , t) = 0 Then by dimensional invariance f(Mm, Ll, LT-2g, , Tt) = 0 for any "scale factors" M,L,T Let M=1/m, L=1/l, T=1/t, so f(1,1,t2g/l, , 1) = 0 Assuming a functional relationship, we obtain
l ( ) for some g
Dimensional analysis
New idea: express Pi Theorem by isomorphisms between polymorphic functions of several arguments and dimensionless functions of fewer arguments. e.g.
'M num * 'L num * ('L/'T^2) num * 1 num -> ('T^2) num
is isomorphic to
1 num -> 1 num
What's left?
Extending the system to support multiple systems of units and automatic insertion of unit conversions Generalising some of the semantic results (e.g. a Pi Theorem at higher types)
Using the parametric relations to construct a model of the language that accurately reflects semantic equivalences (i.e. is fully abstract wrt underlying semantics) Practical implementaion in real languages