Lecture 29 Typed Scheme MC Escher Liberation CS
Lecture 29: Typed Scheme MC Escher, Liberation CS 200: Computer Science David Evans University of Virginia 3 April 2002 CS 200 Spring 2002 http: //www. cs. virginia. edu/~evans Computer Science
Changing Evaluator • Divide evaluation into two steps: – Checking types – Evaluating (essentially as before) • How do we implement check-type? [Represent types [Put types in frame – Change meval into typeof 3 April 2002 CS 200 Spring 2002 2
Representing Type : : = Primitive. Type | Procedure. Type | Product. Types Procedure. Type : : = Type Product. Type : : = Type x Type Primitive. Type : : = Number | String (define (make-primitive-type) (list 'primitive-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 3
global environment Changing global Frames environment +: (-> (x Number) #<primitive: +> + : #<primitive: +> x: 3 double: x: Number 3 double: (-> Number) parameters: x body: (lambda (x) (+ x x)) parameters: x Number body: (lambda (x) (+ x x)) 3 April 2002 CS 200 Spring 2002 4
Defining typeof 3 April 2002 CS 200 Spring 2002 5
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 6
Start with meval (define (meval expr env) (cond ((self-evaluating? 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 7
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 8
typeof-self-evaluating (define (self-evaluating? expr) (or (number? expr) (string? expr) (primitive-procedure? expr))) (define (typeof-self-evaluating expr) (cond ((number? expr) (make-number-type)) ((string? expr) (make-string-type)) ((primitive-procedure? expr) (error “Bad typeof-self-evaluating”))) 3 April 2002 CS 200 Spring 2002 9
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)) 3 April 2002 CS 200 Spring 2002 10
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 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)) (else (error "Unknown expression: " exp)))) 3 April 2002 CS 200 Spring 2002 12
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 The type of an application of an operator (map (lambda (operand) of type params result (typeof operand is the result type ofenv)) the operator (application-operands expr))))) (if (type-match argument-types (procedure-type-params operator)) (procedure-type-result operator) (begin (printf "Type mismatch…") (make-error-type))))))) 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))))) But, also check (if (type-match argument-types the parameter (procedure-type-params operator)) types match! (procedure-type-result operator) (begin (printf "Type mismatch…") (make-error-type))))))) 3 April 2002 CS 200 Spring 2002 14
typelist-to-product-type (define (typelist-to-product-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 15
type-match (define (type-match t 1 t 2) (cond ((or (error-type? t 1) (error-type? t 2)) #t) ; ; error types match anything ((number-type? t 1) (number-type? t 2)) ((string-type? t 1) (string-type? t 2)) ((procedure-type? t 1) (and (procedure-type? t 2) (type-match (procedure-type-params t 1) (procedure-type-params t 2)) (type-match (procedure-type-result t 1) (procedure-type-result t 2)))) ((product-type? t 1) (and (product-type? t 2) (type-match (product-type-first t 1) (product-type-first t 2)) (type-match (product-type-second t 1) (product-type-second t 2)))) (else (error "Bad type: " t 1)))) 3 April 2002 CS 200 Spring 2002 16
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 17
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 18
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))" 3 April 2002 CS 200 Spring 2002 19
(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 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)))) 3 April 2002 CS 200 Spring 2002 21
typeof Examples > (check-type '(lambda ((x number)) (lambda ((y number)) (+ x y)))) "(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 22
What’s in the-global-environment? (define the-global-environment (make-new-environment (list '+ (make-procedure-type (make-product-type (make-number-type)) (make-primitive-procedure +)) the-empty-environment)) 3 April 2002 CS 200 Spring 2002 23
Charge • Friday: PS 7 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! 3 April 2002 CS 200 Spring 2002 24
- Slides: 24