Type Inference - Programming Languages - Study Guide | COMP 311, Papers of Programming Languages

Material Type: Paper; Professor: Cartwright; Class: PROGRAMMING LANGUAGES; Subject: Computer Science; University: Rice University; Term: Fall 2005;

Typology: Papers

Pre 2010

Uploaded on 08/19/2009

koofers-user-2oz-3
koofers-user-2oz-3 🇺🇸

5

(1)

10 documents

1 / 6

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Comp 311 Type Inference Study Guide
Corky Cartwright
Produced: December 2, 2005
1 Synopsis of Implicitly Polymorphic Jam
The syntax of (Implicitly) Polymorphic Jam is a restriction of the syntax of untyped Jam.
Every legal Polymorphic Jam program is also a legal untyped Jam Program. But the converse
is false, because there may not be a valid typing for a given untyped Jam program.
1.1 Abstract Syntax
The following grammar describes the abstract syntax of Polymorphic Jam. Each clause in the
grammar corresponds directly to a node in the abstract syntax tree. The let construction has
been limited to a single binding for the sake of notational simplicity. It is straightforward to
generalize the rule to multiple bindings (with mutual recursion). Note that let is recursive.
M::= M(M· · · M)|P(M· · · M)|if Mthen Melse M|let x:= Min M
|V
V::= map x· · · xto M|x|n|true |false |null
n::= 1|2|. . .
P::= cons |first |rest |null? |cons? |+|-|/|*|=|<|<= |<-
|+|-|~|ref |!
x::= variable names
In the preceding grammar, unary and binary operators are treated exactly like primitive
functions.
Monomorphic types in the language are defined by τ, below. Polymorphic types are
defined by σ. The corresponds to a function type, whose inputs are to the left of the
arrow and whose output is to the right of the arrow.
σ::= α1· · · αn. τ
τ::= int |bool |unit |τ1× · · · × τnτ|α|list τ|ref τ
α::= type variable names (usually greek letters)
1
pf3
pf4
pf5

Partial preview of the text

Download Type Inference - Programming Languages - Study Guide | COMP 311 and more Papers Programming Languages in PDF only on Docsity!

Comp 311 – Type Inference Study Guide

Corky Cartwright

Produced: December 2, 2005

1 Synopsis of Implicitly Polymorphic Jam

The syntax of (Implicitly) Polymorphic Jam is a restriction of the syntax of untyped Jam.

Every legal Polymorphic Jam program is also a legal untyped Jam Program. But the converse

is false, because there may not be a valid typing for a given untyped Jam program.

1.1 Abstract Syntax

The following grammar describes the abstract syntax of Polymorphic Jam. Each clause in the

grammar corresponds directly to a node in the abstract syntax tree. The let construction has

been limited to a single binding for the sake of notational simplicity. It is straightforward to

generalize the rule to multiple bindings (with mutual recursion). Note that let is recursive.

M ::= M (M · · · M ) | P (M · · · M ) | if M then M else M | let x := M in M | V V ::= map x · · · x to M | x | n | true | false | null n ::= 1 | 2 |... P ::= cons | first | rest | null? | cons? | + | - | / | * | = | < | <= | <- | + | - | ~ | ref |! x ::= variable names

In the preceding grammar, unary and binary operators are treated exactly like primitive

functions.

Monomorphic types in the language are defined by τ , below. Polymorphic types are

defined by σ. The → corresponds to a function type, whose inputs are to the left of the

arrow and whose output is to the right of the arrow.

σ ::= ∀α 1 · · · αn. τ τ ::= int | bool | unit | τ 1 × · · · × τn → τ | α | list τ | ref τ α ::= type variable names (usually greek letters)

1.2 Type Checking Rules

In the following rules, the notation Γ[x 1 : τ 1 ,... , xn : τn] means the Γ \ {x 1 ,... , xn} ∪

{x 1 : τ 1 ,... , xn : τn} and Γ′^ abbreviates Γ[x 1 : τ 1 ′,... , xn : τ n′]. Note that Γ \ {x 1 ,... , xn}

means Γ less the type assertions (if any) for {x 1 ,... , xn}.

Γ[x 1 : τ 1 ,... , xn : τn] M : τ Γ map x 1... xn to M : τ 1 × · · · × τn → τ

[abs]

Γ M : τ 1 × · · · × τn → τ Γ M 1 : τ 1 · · · Γ Mn : τn Γ M (M 1 · · · Mn) : τ

[app]

Γ M 1 : bool Γ M 2 : τ Γ M 3 : τ Γ if M 1 then M 2 else M 3 : τ

[if]

Note that there are two rules for let expressions. The [letmono] rule corresponds to the

let rule of Typed Jam; it places no restriction on the form of the right-hand side M 1 of the

let binding. The [letpoly] rule generalizes the free type variables (not occurring in the type

environment Γ) in the type inferred for the right-hand-side of a let binding – provided that

the right-hand-side M 1 is a syntactic value: a constant like null or cons, a map expression, or

a variable. Syntactic values are expressions whose evaluation is trivial, excluding evaluations

that allocate storage.

Γ[x : τ ] ` x : τ

Γ′^ M 1 : τ 1 ′... Γ′^ Mn : τ (^) n′ Γ′^ M : τ Γ let x 1 := M 1 ;.. .; xn := Mn; in M : τ

[letmono]

Γ′^ M 1 : τ 1 ′... Γ′^ Mn : τ (^) n′ Γ[x 1 : CM 1 (τ 1 ′, Γ),... , xn : CMn (τ (^) n′, Γ)] M : τ Γ let x 1 := M 1 ;.. .; xn := Mn; in M : τ

[letpoly]

Γ[x : ∀α 1 ,... , αn. τ ] ` x : O(∀α 1 ,... , αn. τ, τ 1 ,... , τn)

The functions O(·, ·) and C·(·, ·) are the keys to polymorphism. Here is how C·(·, ·) is

defined:

CV (τ, Γ) := ∀{FTV(τ ) − FTV(Γ)}. τ

CN (τ, Γ) := τ

where V is a syntactic value, N is an expression that is not a syntactic value, and FTV(α)

means the “free type variables in the expression (or type environment) α”.

When closing over a type, you must find all of the free variables in τ that are not free

in any of the types in the environment Γ. Then, build a polymorphic type by quantifying τ

over all of those type variables.

To open a polymorphic type

∀α 1 ,... , αn. τ,

substitute any type terms τ 1 ,... , τn for the quantified type variables α 1 ,... , αn:

O(∀α 1 ,... , αn. τ, τ 1 ,... , τn) = τ[α 1 :=τ 1 ,...,αn:=τn]

which creates a monomorphic type from a polymorphic type. For example,

O(∀α. α → α, τ ) = τ → τ

Task 2: Are the following Polymorphic Jam programs typable? Justify your answer either

by giving a proof tree (constructed using the inference rules for PolyJam) or by showing a

conflict in the type constraints generated by matching the inference rules against the program

text.

1. let listMap := map f,l to

if null?(l) then null else cons(f(first(l)), listMap(f, rest(l))) in listMap(first,null);

let length := map l to if null?(l) then 0 else 1 + length(rest(l)); l := cons(cons(1,null),cons(cons(2,cons(3,null)),null)); in length(l)+length(first(l))

Task 3: Give a simple example of an untyped Jam expression that is not typable in Typed

Jam but is typable in Polymorphic Jam.

3 Solutions to Selected Exercises

Task 1 : The first four expressions are typable in Typed Jam, but the fifth is not.

  1. Tree 1: Γ 0 [f:int → int] 10:int Γ 0 [f:int → int] f:int → int Γ 0 [f:int → int] ` f(10):int

[app]

Γ 0 ` map f to f(10):(int → int) → int

[abs]

Tree 2: Tree 1

Γ 0 [x:int] x:int Γ 0 map x to x:int → int

[abs]

Γ 0 ` (map f to f(10))(map x to x):int

[app]

  1. Type Inference Proof Omitted.
  2. Tree 1: Γ 0 [x:int] /:int × int → int Γ 0 [x:int] 1:int Γ 0 [x:int] x:int Γ 0 [x:int] 1/x:int]

[app]

Tree 2: Γ 0 [x:int] +:int × int → int Γ 0 [x:int] 1:int Tree 1 Γ 0 [x:int] ` (1 + (1/x)):int

[app]

Γ 0 ` (map x to 1 + (1/x)):int → int

[abs]

Tree 3: Tree 2 Γ 0 0:int Γ 0 (map x to 1 + (1 /x))(0):int

[app]

  1. Tree 1: Γ 0 [x:int → int] x:int → int Γ 0 (map x to x):(int → int) → (int → int)

[abs]

Tree 2: Γ 0 [y:int] y:int Γ 0 (map y to y):int → int

[abs]

Tree 3: Tree 1 Tree 2 Γ 0 ` (map x to x)(map y to y):int → int

[app]

  1. This example is almost identical to the previous one, but the identity function id is defined only once in a let binding and then applied to itself. Since Typed Jam does not support polymorphism, we can only assign one typing to id. But we needed two different typings for the identity in the preceding example, so we cannot type this program.

Task 2: Both programs are typable in Polymorphic Jam. In fact the first program is

typable in Typed Jam because the length function is only applied to one type of list. Hence

the letmono rule can be used to type the let expression in this program instead of the more

general letpoly rule.

1. Type Inference Proof Omitted.

2. Let Γ 1 abbreviate Γ 0 [length : list α → int, l : list list int];

let Γ 2 abbreviate Γ 0 [length : ∀α. (list α → int), l : list list int];

and let Γ 3 abbreviate Γ 1 [l : list α].

Tree 1: Γ 3 rest : list α → list α Γ 3 l : list α Γ 3 ` rest(l) : list α

[app] Γ 3 ` length : list α → int

Γ 3 ` length(rest(l)) : int

[app]

Tree 2: Γ 3 + : int × int → int Γ 3 1:int Tree 1 Γ 3 ` 1+length(rest(l)) : int

[app]

Tree 3: Γ 3 null? : list α → bool Γ 3 l : list α Γ 3 ` null?(l) : bool

[app] Γ 3 ` 0 : int Tree 2

Γ 3 ` if null?(l) then 0 else 1+length(rest(l)) : int

[if]

Γ 2 ` map l to if null?(l) then 0 else 1+length(rest(l)) : int

[abs]