06/27/22 1 Programming Languages and Compilers (CS 421) Dennis Griffith 0207 SC, UIUC http://www.cs.illinois.edu/c lass/cs421/ Based in part on slides by Mattox Beckman, as updated by Vikram Adve, Gul Agha, and Elsa Gunter
Jan 03, 2016
04/20/23 1
Programming Languages and Compilers (CS 421)
Dennis Griffith
0207 SC, UIUC
http://www.cs.illinois.edu/class/cs421/
Based in part on slides by Mattox Beckman, as updated by Vikram Adve, Gul Agha, and Elsa Gunter
04/20/23 2
Why Data Types?
Data types play a key role in: Data abstraction in the design of
programs Type checking in the analysis of
programs Compile-time code generation in the
translation and execution of programs
04/20/23 3
Terminology
Type: A type t defines a set of possible data values E.g. short in C is {x| 215 - 1 x -
215} A value in this set is said to have type
t
Type system: rules of a language assigning types to expressions
04/20/23 4
Types as Specifications
Types describe properties Different type systems describe different
properties, eg Data is read-write versus read-only Operation has authority to access data Data came from “right” source Operation might or could not raise an
exception Common type systems focus on types describing
same data layout and access methods
04/20/23 5
Sound Type System
If an expression is assigned type t, and it evaluates to a value v, then v is in the set of values defined by t
SML, OCAML, Scheme and Ada have sound type systems
Most implementations of C and C++ do not
04/20/23 6
Strongly Typed Language
When no application of an operator to arguments can lead to a run-time type error, language is strongly typed Eg: 1 + 2.3;;
Depends on definition of “type error”
04/20/23 7
Strongly Typed Language
C++ claimed to be “strongly typed”, but Union types allow creating a value at
one type and using it at another Type coercions may cause
unexpected (undesirable) effects No array bounds check (in fact, no
runtime checks at all) SML, OCAML “strongly typed” but still
must do dynamic array bounds checks, runtime type case analysis, and other checks
04/20/23 8
Static vs Dynamic Types
• Static type: type assigned to an expression at compile time
• Dynamic type: type assigned to a storage location at run time
• Statically typed language: static type assigned to every expression at compile time
• Dynamically typed language: type of an expression determined at run time
04/20/23 9
Type Checking
When is op(arg1,…,argn) allowed? Type checking assures that operations
are applied to the right number of arguments of the right types Right type may mean same type as
was specified, or may mean that there is a predefined implicit coercion that will be applied
Used to resolve overloaded operations
04/20/23 10
Type Checking
Type checking may be done statically at compile time or dynamically at run time
Dynamically typed languages (e.g., LISP, Python) do only dynamic type checking
Statically typed languages can do most type checking statically
04/20/23 11
Dynamic Type Checking
Performed at run-time before each operation is applied
Types of variables and operations left unspecified until run-time Same variable may be used at
different types
04/20/23 12
Dynamic Type Checking
Data object must contain type information
Errors aren’t detected until violating application is executed (maybe years after the code was written)
04/20/23 13
Static Type Checking
Performed after parsing, before code generation
Type of every variable and signature of every operator must be known at compile time
04/20/23 14
Static Type Checking
Can eliminate need to store type information in data object if no dynamic type checking is needed
Catches many programming errors at earliest point
Can’t check types that depend on dynamically computed values Eg: array bounds
04/20/23 15
Static Type Checking
Typically places restrictions on languages Garbage collection References instead of pointers All variables initialized when created Variable only used at one type
Union types allow for work-arounds, but effectively introduce dynamic type checks
04/20/23 16
Type Declarations
Type declarations: explicit assignment of types to variables (signatures to functions) in the code of a program Must be checked in a strongly typed
language Often not necessary for strong
typing or even static typing (depends on the type system)
04/20/23 17
Type Inference
Type inference: A program analysis to assign a type to an expression from the program context of the expression Fully static type inference first
introduced by Robin Miller in ML Haskell, OCAML, SML use type inference
Records are a problem for type inference
04/20/23 18
Format of Type Judgments
A type judgement has the form |- exp :
is a typing environment Supplies the types of variables and
functions is a list of the form [ x : , . . . ]
exp is a program expression is a type to be assigned to exp |- pronounced “turnstyle”, or “entails”
(or “satisfies”)
04/20/23 19
Example Valid Type Judgments
[ ] |- true or false : bool [ x : int] |- x + 3 : int [ p : int -> string ] |- p(5) : string
04/20/23 20
Format of Typing Rules
Assumptions 1 |- exp1 : 1 . . . n |- expn : n
|- exp : Conclusion Idea: Type of expression determined by
type of components Rule without assumptions is called an
axiom may be omitted when empty
04/20/23 21
Format of Typing Rules
Assumptions 1 |- exp1 : 1 . . . n |- expn : n
|- exp : Conclusion
, exp, are parameterized environments, expressions and types - i.e. may contain meta-variables
04/20/23 22
Axioms - Constants
|- n : int (assuming n is an integer constant)
|- true : bool |- false : bool
These rules are true with any typing environment
n is a meta-variable
04/20/23 23
Axioms - Variables
Notation: Let (x) = if x : and there is no x : to the left of x : in
Variable axiom:
|- x : if (x) =
04/20/23 24
Simple Rules - Arithmetic
Primitive operators ( { +, -, *, …}):
|- e1 : int |- e2 : int
|- e1 e2 : int
Relations ( ˜ { < , > , =, <=, >= }):
|- e1 : int |- e2 : int
|- e1 ˜ e2 :bool
04/20/23 25
Simple Rules - Booleans
Connectives |- e1 : bool |- e2 : bool
|- e1 && e2 : bool
|- e1 : bool |- e2 : bool
|- e1 || e2 : bool
04/20/23 26
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Start building the proof tree
from the bottom up
? |- y || (x + 3 > 6) : bool
04/20/23 27
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Which rule has this as a
conclusion?
? |- y || (x + 3 > 6) : bool
04/20/23 28
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Booleans: ||
|- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 29
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Pick an assumption to prove
? |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 30
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Which rule has this as a
conclusion?
? |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 31
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Axiom for variables
|- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 32
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Pick an assumption to prove
? |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 33
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Which rule has this as a
conclusion?
? |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 34
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Arithmetic relations
|- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 35
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Pick an assumption to prove
? |- x + 3 : int |- 6 : int
|- y : bool |- x + 3 > 6 : bool |- y || (x + 3 > 6) : bool
04/20/23 36
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Which rule has this as a conclusion?
? |- x + 3 : int |- 6 : int
|- y : bool |- x + 3 > 6 : bool |- y || (x + 3 > 6) : bool
04/20/23 37
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Axiom for constants
|- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 38
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Pick an assumption to prove
? |- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 39
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Which rule has this as a conclusion?
? |- x + 3 : int |- 6 : int
|- y : bool |- x + 3 > 6 : bool |- y || (x + 3 > 6) : bool
04/20/23 40
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Arithmetic operations
|- x : int |- 3 : int |- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 41
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Pick an assumption to prove ? |- x : int |- 3 : int |- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 42
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Which rule has this as a
conclusion? ? |- x : int |- 3 : int |- x + 3 : int |- 6 : int
|- y : bool |- x + 3 > 6 : bool |- y || (x + 3 > 6) : bool
04/20/23 43
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Axiom for constants |- x : int |- 3 : int |- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 44
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Pick an assumption to prove ? |- x : int |- 3 : int |- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 45
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Which rule has this as a
conclusion? ? |- x : int |- 3 : int |- x + 3 : int |- 6 : int
|- y : bool |- x + 3 > 6 : bool |- y || (x + 3 > 6) : bool
04/20/23 46
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool Axiom for variables
|- x : int |- 3 : int |- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 47
Simple Example
Let = [ x:int ; y:bool] Show |- y || (x + 3 > 6) : bool No more assumptions! DONE!
|- x : int |- 3 : int |- x + 3 : int |- 6 :
int |- y : bool |- x + 3 > 6 : bool
|- y || (x + 3 > 6) : bool
04/20/23 48
Type Variables in Rules
If_then_else rule: |- e1 : bool |- e2 : |- e3 :
|- (if e1 then e2 else e3) :
is a type variable (meta-variable) Can take any type at all All instances in a rule application must
get same type Then branch, else branch and
if_then_else must all have same type
04/20/23 49
Function Application
Application rule: |- e1 : 1 2 |- e2 : 1
|- (e1 e2) : 2
If you have a function expression e1 of type 1 2 applied to an argument of type 1, the resulting expression has type 2
04/20/23 50
Application Examples
|- print_int : int unit |- 5 : int |- (print_int 5) : unit
e1 = print_int, e2 = 5, 1 = int, 2 = unit
|- map print_int : int list unit list |- [3;7] : int list |- (map print_int [3; 7]) : unit list
e1 = map print_int, e2 = [3; 7], 1 = int list, 2 = unit list
04/20/23 51
Fun Rule
Rules describe types, but also how the environment may change
Can only do what rule allows! fun rule:
[x : 1 ] + |- e : 2
|- fun x -> e : 1 2
04/20/23 52
Fun Examples
[y : int ] + |- y + 3 : int
|- fun y -> y + 3 : int int
[f : int bool] + |- f 2 :: [true] : bool list
|- (fun f -> f 2 :: [true])
: (int bool) bool list
04/20/23 53
(Monomorphic) Let and Let Rec
let rule: |- e1 : 1 [x : 1 ] + |- e2 : 2
|- (let x = e1 in e2 ) : 2
let rec rule: [x: 1 ] + |- e1:1 [x: 1 ] + |- e2:2
|- (let rec x = e1 in e2 ) : 2
04/20/23 54
Example
Which rule do we apply?
? |- (let rec one = 1 :: one in let x = 2 in fun y -> (x :: y :: one) ) : int int
list
04/20/23 55
Example
Let rec rule: 2 [one : int list] |- 1 (let x = 2 in[one : int list] |- fun y -> (x :: y ::
one)) (1 :: one) : int list : int int list |- (let rec one = 1 :: one in let x = 2 in fun y -> (x :: y :: one) ) : int int list
04/20/23 56
Proof of 1
Which rule?
[one : int list] |- (1 :: one) : int list
04/20/23 57
Proof of 1
Application
3 4 [one : int list] |- [one : int
list] |- ((::) 1): int list int list one : int
list[one : int list] |- (1 :: one) : int list
04/20/23 58
Proof of 3
Constants Rule Constants Rule
[one : int list] |- [one : int list] |-
(::) : int int list int list 1 : int[one : int list] |- ((::) 1) : int list int list
04/20/23 59
Proof of 4
Rule for variables
[one : int list] |- one:int list
04/20/23 60
Proof of 2
5 [x:int; one : int list] |-
Constant fun y -> (x :: y :: one))[one : int list] |- 2:int : int int list [one : int list] |- (let x = 2 in
fun y -> (x :: y :: one)) : int int list
04/20/23 61
Proof of 5
?
[x:int; one : int list] |- fun y -> (x :: y :: one)) : int int list
04/20/23 62
Proof of 5
?[y:int; x:int; one : int list] |- (x :: y :: one) : int
list[x:int; one : int list] |- fun y -> (x :: y :: one))
: int int list
04/20/23 63
Proof of 5
6 7 [y:int; x:int; one : int list] |- [y:int; x:int; one :
int list] |- ((::) x):int list int list (y :: one) : int list[y:int; x:int; one : int list] |- (x :: y :: one) : int
list[x:int; one : int list] |- fun y -> (x :: y :: one))
: int int list
04/20/23 64
Proof of 6
Constant Variable
[…] |- (::): int int list int list […; x:int;…] |-
x:int [y:int; x:int; one : int list] |- ((::) x) :int list int list
04/20/23 65
Proof of 7
Pf of 6 [y/x] Variable
[y:int; …] |- ((::) y) […; one: int list]
|- :int list int list one: int list[y:int; x:int; one : int list] |- (y :: one) :
int list
04/20/23 66
Curry - Howard Isomorphism
Type Systems are logics; logics are type systems
Types are propositions; propositions are types
Terms are proofs; proofs are terms
Functions space arrow corresponds to implication; application corresponds to modus ponens
04/20/23 67
Curry - Howard Isomorphism
Modus Ponens
A B A
B
• Application |- e1 : |- e2 :
|- (e1 e2) :
04/20/23 68
Remaining Problems
The above system can’t handle polymorphism as in OCAML
No type variables in type language (only meta-variable in the logic)
Would need: Object level type variables and some kind
of type quantification let and let rec rules to introduce
polymorphism Explicit rule to eliminate (instantiate)
polymorphism
Support for Polymorphic Types
Monomorpic Types (): Basic Types: int, bool, float, string, unit, … Type Variables: , , Compound Types: , int * string, bool list,
… Polymorphic Types:
Monomorphic types Universally quantified monomorphic types 1, … , n . Can think of as same as .
04/20/23 69
A
A
Support for Polymorphic Types
Typing Environment supplies polymorphic types (which will often just be monomorphic) for variables
Free variables of monomorphic type just type variables that occur in it Write FreeVars()
Free variables of polymorphic type removes variables that are universally quantified FreeVars( 1, … , n . ) = FreeVars() – {1, … , n }
FreeVars() = all FreeVars of types in range of
04/20/23 70
A
Monomorphic to Polymorphic
Given: type environment monomorphic type shares type variables with
Want most polymorphic type for that doesn’t break sharing type variables with
Gen(, ) = 1, … , n . where
{1, … , n} = freeVars() – freeVars()
04/20/23 71
A