david evans evans cs200: computer science university of virginia computer science lecture 29: typed...
TRANSCRIPT
David Evanshttp://www.cs.virginia.edu/~evans
CS200: Computer ScienceUniversity of VirginiaComputer Science
Lecture 29: Typed Scheme
MC Escher, Liberation
3 April 2002 CS 200 Spring 2002 2
Changing Evaluator
• Divide evaluation into two steps:– Checking types– Evaluating (essentially as before)
• How do we implement check-type?Represent typesPut types in frame– Change meval into typeof
3 April 2002 CS 200 Spring 2002 3
Representing Types
Type ::= PrimitiveType | ProcedureType | ProductTypeProcedureType ::= Type TypeProductType ::= Type x TypePrimitiveType ::= Number | String
(define (make-primitive-type type) (list 'primitive-type type))(define (primitive-type? type) (tagged-list? type 'primitive-type))
(define (make-number-type) (make-primitive-type 'number))(define (number-type? type) (and (primitive-type? type) (eq? (cadr type) 'number)))
(define (make-procedure-type inputs outputs) (list ‘procedure-type inputs outputs)
3 April 2002 CS 200 Spring 2002 4
Changing Framesglobalenvironment
+ : #<primitive:+>
double: x: 3
parameters: xbody: (lambda (x) (+ x x))
globalenvironment
+: (-> (x Number Number) Number) #<primitive:+>
double: (-> Number Number)
x: Number 3
parameters: x Numberbody: (lambda (x) (+ x x))
3 April 2002 CS 200 Spring 2002 5
Defining typeof
3 April 2002 CS 200 Spring 2002 6
typeof Examples> (typeof '(+ 3 4) the-global-environment)(primitive-type number)> (typeof '(+ 3 +) the-global-environment)Type mismatch. Application (+ 3 +) parameter types are (Number x Number) -> (Number) x Number, should be Number x Number.(error-type)> (typeof '(+ 3) the-global-environment)Type mismatch. Application (+ 3) parameter types are Number, should be Number x Number.(error-type)
3 April 2002 CS 200 Spring 2002 7
Start with meval(define (meval expr env) (cond ((self-evaluating? expr) expr) ((variable? expr) (environment-lookup-name expr env)) ((lambda? expr) (make-procedure (lambda-parameters expr)
(lambda-body expr) env)) ((application? expr) (mapply (meval (application-operator expr) env) (map (lambda (subexpr) (meval subexpr env)) (application-operands expr)))) (else (error "Unknown expression: " exp))))
3 April 2002 CS 200 Spring 2002 8
typeof
(define (typeof expr env) (cond ((self-evaluating? expr) (typeof-self-evaluating expr) ((variable? expr) (typeof-variable expr env)) ((lambda? expr) (typeof-procedure expr env)) ((application? expr) (typeof-application expr env)) (else (error "Unknown expression: " exp))))
3 April 2002 CS 200 Spring 2002 9
typeof-self-evaluating
(define (typeof-self-evaluating expr) (cond ((number? expr) (make-number-type)) ((string? expr) (make-string-type)) ((primitive-procedure? expr)
(error “Bad typeof-self-evaluating”)))
(define (self-evaluating? expr) (or (number? expr) (string? expr) (primitive-procedure? expr)))
3 April 2002 CS 200 Spring 2002 10
Testing 1 2 3…
> (typeof '3 the-global-environment)(primitive-type number)> (typeof '"test" the-global-environment)(primitive-type string)> (typeof '+ the-global-environment)(procedure-type (product-type (primitive-type number) (primitive-type number)) (primitive-type number))
3 April 2002 CS 200 Spring 2002 11
typeof
(define (typeof expr env) (cond ((self-evaluating? expr) (typeof-self-evaluating expr) ((variable? expr) (typeof-variable expr env)) ((lambda? expr) (typeof-procedure expr env)) ((application? expr) (typeof-application expr env)) ((definition? expr) (typeof-definition expr env)) (else (error "Unknown expression: " exp))))
This is why (typeof ‘+ the-global-environment) worked!
3 April 2002 CS 200 Spring 2002 12
typeof
(define (typeof expr env) (cond ((self-evaluating? expr) (typeof-self-evaluating expr) ((variable? expr) (typeof-variable expr env)) ((lambda? expr) (typeof-procedure expr env)) ((application? expr) (typeof-application expr env)) (else (error "Unknown expression: " exp))))
3 April 2002 CS 200 Spring 2002 13
typeof-application(define (typeof-application expr env) (let ((operator (typeof (application-operator expr) env))) (if (procedure-type? operator) (let ((argument-types (typelist-to-product-type (map (lambda (operand) (typeof operand env)) (application-operands expr))))) (if (type-match argument-types (procedure-type-params operator)) (procedure-type-result operator) (begin (printf "Type mismatch…") (make-error-type)))))))
The type of an application of an operatorof type params result is the result type of the operator
3 April 2002 CS 200 Spring 2002 14
typeof-application(define (typeof-application expr env) (let ((operator (typeof (application-operator expr) env))) (if (procedure-type? operator) (let ((argument-types (typelist-to-product-type (map (lambda (operand) (typeof operand env)) (application-operands expr))))) (if (type-match argument-types (procedure-type-params operator)) (procedure-type-result operator) (begin (printf "Type mismatch…") (make-error-type)))))))
But, also checkthe parametertypes match!
3 April 2002 CS 200 Spring 2002 15
typelist-to-product-type
(define (typelist-to-product-type typelist) (if (null? typelist) (make-empty-type) (if (eq? (length typelist) 1) (car typelist) (make-product-type (car typelist) (typelist-to-product-type (cdr typelist))))))
3 April 2002 CS 200 Spring 2002 16
type-match(define (type-match t1 t2) (cond ((or (error-type? t1) (error-type? t2)) #t) ;; error types match anything ((or (error-type? t1) (error-type? t2)) #t) ;; error types match anything ((number-type? t1) (number-type? t2)) ((string-type? t1) (string-type? t2)) ((procedure-type? t1) (and (procedure-type? t2) (type-match (procedure-type-params t1) (procedure-type-params t2)) (type-match (procedure-type-result t1) (procedure-type-result t2)))) ((product-type? t1) (and (product-type? t2) (type-match (product-type-first t1) (product-type-first t2)) (type-match (product-type-second t1) (product-type-second t2)))) (else (error "Bad type: " t1))))
3 April 2002 CS 200 Spring 2002 17
Testing 1 2 3…> (typeof '(+ 3 4) the-global-environment)(primitive-type number)> (typeof '(+ 3 +) the-global-environment)Type mismatch. Application (+ 3 +) parameter types are (Number x Number) -> (Number) x Number, should be Number x Number.(error-type)> (typeof '(+ 3) the-global-environment)Type mismatch. Application (+ 3) parameter types are Number, should be Number x Number.(error-type)
3 April 2002 CS 200 Spring 2002 18
typeof
(define (typeof expr env) (cond ((self-evaluating? expr) (typeof-self-evaluating expr) ((variable? expr) (typeof-variable expr env)) ((lambda? expr) (typeof-procedure expr env)) ((application? expr) (typeof-application expr env)) (else (error "Unknown expression: " exp))))
3 April 2002 CS 200 Spring 2002 19
Examples(define (check-type expr) (display-type (typeof expr the-global-environment)))
> (check-type '(lambda ((x number) (y number)) (+ x y)))"(Number x Number) -> (Number)"> (check-type '(lambda ((x number) (y number)) (+ x)))Type mismatch. Application (+ x) parameter types are Number, should be Number x Number."(Number x Number) -> (Error)"> (check-type '(lambda ((x number) (y number)) +))"(Number x Number) -> ((Number x Number) -> (Number))"
3 April 2002 CS 200 Spring 2002 20
(define (typeof-procedure expr env) (let* ((params (lambda-parameters expr)) (body (lambda-body expr)) (param-types (map (lambda (param)
(parse-type (cadr param))) params)) (restype (typeof-sequence body (extend-environment (map (lambda (param) (car param)) params) ;; names param-types (map (lambda (param) 'unknown) params) ;; values env)))) (make-procedure-type (typelist-to-product-type param-types) restype))))
Figure out the type of the body
3 April 2002 CS 200 Spring 2002 21
(define (typeof-procedure expr env) (let* ((params (lambda-parameters expr)) (body (lambda-body expr)) (param-types (map (lambda (param)
(parse-type (cadr param))) params)) (restype (typeof-sequence body (extend-environment (map (lambda (param) (car param)) params) ;; names param-types (map (lambda (param) 'unknown) params) ;; values env)))) (make-procedure-type (typelist-to-product-type param-types) restype))))
3 April 2002 CS 200 Spring 2002 22
typeof Examples> (check-type '(lambda ((x number)) (lambda ((y number)) (+ x y))))"(Number) -> ((Number) -> (Number))"> (check-type '((lambda ((x number)) (lambda ((y number)) (+ x y))) 1))"(Number) -> (Number)"> (check-type '(((lambda ((x number)) (lambda ((y number)) (+ x y))) 1) 2))"Number"> (check-type '(((lambda ((x number)) (lambda ((y number)) (+ x y))) 1) "test"))Type mismatch. Application (((lambda ((x number)) (lambda ((y number)) (+ x y))) 1) test) parameter types are String, should be Number."Error"
3 April 2002 CS 200 Spring 2002 23
What’s in the-global-environment?
(define the-global-environment (make-new-environment (list (list '+ (make-procedure-type (make-product-type (make-number-type) (make-number-type)) (make-number-type)) (make-primitive-procedure +)) the-empty-environment))
3 April 2002 CS 200 Spring 2002 24
Charge• Friday: PS7 Due
• Friday: Exam 2 Out (due Wednesday) Mutation and Environmental Model of Evaluation– Classifying Problems– Evaluators (final question will involve modifying
typed Scheme, so make sure you understand everything in today’s code)
• I will answer questions about it Friday, but not after handing out the exam!