ppl applicative and normal form verification, type checking and inference
TRANSCRIPT
PPL
Applicative and Normal FormVerification, Type Checking and
Inference
2
Applicative order vs. Normal OrderEvaluation
To Evaluate a combination: (other than special form)Evaluate all of the sub-expressions in any orderApply the procedure that is the value of the leftmost sub-expression to the arguments (the values of the other sub-expressions)
3
Applicative order evaluation rulesCombination... (<operator> <operand1> …… <operand n>)
• Evaluate <operator> to get the procedure and evaluate <operands> to get the arguments
• If <operator> is primitive: do whatever magic it does
• If <operator> is compound: evaluate body with formal parameters replaced by arguments
4
Normal order evaluationCombination … (<operator> <operand1> …… <operand n>)
• Evaluate <operator> to get the procedure and evaluate <operands> to get the arguments
• If <operator> is primitive: do whatever magic it does
• If <operator> is compound: evaluate body with formal parameters replaced by arguments
5
The DifferenceApplicative
((lambda (x) (+ x x))
(* 3 4))
(+ 12 12)
24
Normal
((lambda (x) (+ x x))
(* 3 4))
(+ (* 3 4) (* 3 4))
(+ 12 12)
24
This may matter in some cases:
((lambda (x y) (+ x 2)) 3 (/ 1 0))
Scheme is an Applicative Order Language!
Using let to define functions
• Can we use let to define functions?
• What about recursive functions?
Type Checking and Inference
• Based on
S. Krishnamurthi. Programming Languages: Application and Interpretation 2007.
Chapters 24-26
Verification• Type correctness
– Verify that the types of expressions in the program are “correct”
– E.g. + is applied to numbers– In other languages: we should also check that the
type of value stored in a variable correspond to the variable declared type
• Program Verification– Verify that the program halts and produces the
“correct” output– Somewhat easier with design-by-contract, where it
can be done in a modular fashion
Languages and Types
• Fully typed– C, Pascal, Java..
• Semi-typed– Scheme
• Untyped– Prolog
• Well-typing rules– Define relationships between types
Type Checking and Inference
Type Checking. Given an expression, and a “goal” type T, verify that the expression type is T
Example: Given the expression (+ (f 3) 7), we need to verify that (f 3) is
a number
Type Inference. Infer the type of an expressionExample: (define x (f 3))
Types in Scheme
• Numbers, booleans, symbols…• Union:
– No value constructor– Type Constrcutor is union– Simplification rules
• S union S = S• S union T = T union S
• Unit Type– “Void”
Procedures and Type Polymorphism
• What is the type of:– (lambda (x) x)– (lambda (f x) (f x))– (lambda (f x) ( (f x) x))
• Instantiations, type variables renaming...
• Next we construct a static type inference system
Type assignment and Typing statement
• Type assignment– Mapping variables to types– Example: TA= {x<-Number, y<-[Number –> T]}– Notation: TA(x) = Number
• Typing statement– TA |- e:T– Under TA, the expression e has the type T
• {x<-Number} |- (+ x 5):Number– Type variables (as well as unbound variables) used in such
statements are defined to be universally quantified• {x<-[T1 –> T2]} |- (x y):T2
Type assignment extension
{x<-Number, y<-[Number –> T]}°{z<-Boolean}= {x<-Number, y<-[Number –> T], z<-Boolean}
EMPTY° {x1<-T1, ..., xn<- Tn} ={x1<-T1, ..., xn<- Tn}
Extension pre-condition: new variables are different from old ones.
Restricted Scheme (syntax)
<scheme-exp> -> <exp><exp> -> <atomic> | <composite><atomic> -> <number> | <boolean> | <variable><composite> -> <special> | <form><number> -> Numbers<boolean> -> ’#t’ | ’#f’<variable> -> Restricted sequences of letters, digits, punctuation marks<special> -> <lambda> | <quote>
<form> -> ’(’ <exp>+ ’)’<lambda> -> ’(’ ’lambda’ ’(’ <variable>* ’)’ <exp>+ ’)’<quote> -> ’(’ ’quote’ <variable> ’)’
Typing axioms• Typing axiom Boolean :For every type assignment TA and boolean b:TA |- b:BooleanTyping axiom Variable :For every type assignment TA and variable v:TA |- v:TA(v)Typing axioms Primitive procedure :TA |- +:[Number* ... *Number -> Number]TA |- not:[S -> Boolean] where S is a type variable. For every type assignment TA:TA |- display:[S -> Unit] S is a type variable. That is, display is a polymorphic primitive procedure.
Cont.
• Typing rule Procedure :If TA{x1<-S1, ..., xn<-Sn} |- bi:Ui for all i=1..m,Then TA |- (lambda (x1 ... xn) b1 ... bm):[S1*...*Sn -> Um]
Parameter-less Procedure:If TA |- bi:Ui for all i=1..m,Then TA |- (lambda ( ) b1 ... bm):[Unit -> Um]
Typing rule Application :If TA |- f:[S1*...*Sn -> S],TA |- e1:S1, ..., TA |- en:SnThen TA |- (f e1 ... en):S
Expression Trees
The nesting of expressions can be viewed as a tree
Sub-trees correspond to composite expressions
Leaves correspond to atomic ones.
Type Inference AlgorithmAlgorithm Type-derivation:Input: A language expression eOutput: A type expression t or FAILMethod:1. For every leaf sub-expression of e, apart from procedure parameters, derive a typing statement by instantiating a typing axiom.Number the derived typing statements.2. For every sub-expression e’ of e (including e):Apply a typing rule whose support typing statements are already derived, and it derives a typing statement for e’.Number the newly derived typing statement.3. If there is a derived typing statement for e of the form e:t, Output = t.Otherwise, Output = FAIL