David Evans http://www.cs.virginia.edu/~evans Lecture 28: Types of Types “It would appear that we have reached the limits of what it is possible to achieve with computer technology, although one should be careful with such statements, as they tend to sound pretty silly in five years.” John Von Neumann, 1949 CS200: Computer Science University of Virginia Computer Science David Evans http://www.cs.virginia.edu/~evans
Menu Types and Type Checking Typed Scheme 1 April 2002 CS 200 Spring 2002
Types Type is a (possibly infinite) set of values Strings Numbers programs that halt Colors Beatle’s Songs that don’t end on the Tonic lists of lists of lists of anything Type is a (possibly infinite) set of values You can do some things with some types, but not others 1 April 2002 CS 200 Spring 2002
Why have types? Detecting program errors Better to notice error than report incorrect result Better to find error in development then in execution Make programs easier to read, understand and maintain Better than comments if they are checked and can be trusted Security Can use types to constrain the behavior of programs (not in CS200) 1 April 2002 CS 200 Spring 2002
Types of Types Does regular Scheme have types? > (car 3) car: expects argument of type <pair>; given 3 > (+ (cons 1 2)) +: expects argument of type <number>; given (1 . 2) Yes, without types (car 3) would produce some silly result. Because of types, it produces a type error. 1 April 2002 CS 200 Spring 2002
Type Taxonomy Latent vs. Manifest Are types visible in the program text? Checked statically vs. checked dynamically Do you have to run the program to know if it has type errors? Checked weakly vs. strongly How strict are the rules for using types? Meaningless (just matter of degree) 1 April 2002 CS 200 Spring 2002
Scheme Java Scheme has Latent, Dynamic types Java has Manifest, Static types 1 April 2002 CS 200 Spring 2002
Java Example class Test { int tester (String s) { int x; x = s; return "okay"; } javac types.java types.java:5: Incompatible type for =. Can't convert java.lang.String to int. x = s; ^ types.java:6: Incompatible type for return. Can't convert java.lang.String to int. return "okay"; 2 errors The result is an integer x is an integer 1 April 2002 CS 200 Spring 2002
Java Example class Test { int tester (String s) { int x; tester (“hello”); x = s; return "okay"; } javac types.java types.java:6: Incompatible type for =. Can't convert java.lang.String to int. x = s; ^ types.java:7: Incompatible type for return. Can't convert java.lang.String to int. return "okay"; 2 errors 1 April 2002 CS 200 Spring 2002
What do we need to do change our Mini-Scheme evaluator to provide Java-like type checking? 1 April 2002 CS 200 Spring 2002
Types in Mini-Scheme Type ::= PrimitiveType Type ::= ProcedureType Type ::= ProductType ProcedureType ::= Type Type ProductType ::= Type x Type PrimitiveType ::= Number | String 1 April 2002 CS 200 Spring 2002
Examples 3 Number + Number x Number Number (+ 3 3) Type ::= PrimitiveType | ProcedureType | ProductType ProcedureType ::= Type Type ProductType ::= Type x Type PrimitiveType ::= Number | String Examples 3 Number + Number x Number Number (+ 3 3) (lambda ((x number) (y number)) (+ x y)) Changed lambda form: Expression ::= (lambda (((Name Type))*) Expr*) 1 April 2002 CS 200 Spring 2002
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 1 April 2002 CS 200 Spring 2002
Representing Types Type ::= PrimitiveType | ProcedureType | ProductType ProcedureType ::= Type Type ProductType ::= Type x Type PrimitiveType ::= 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-boolean-type) (make-primitive-type 'boolean)) (define (boolean-type? type) (and (primitive-type? type) (eq? (cadr type) 'boolean))) (define (make-string-type) (make-primitive-type 'string)) (define (string-type? type) (and (primitive-type? type) (eq? (cadr type) 'string))) 1 April 2002 CS 200 Spring 2002
Representing Types (define (make-procedure-type params result) Type ::= PrimitiveType | ProcedureType | ProductType ProcedureType ::= Type Type ProductType ::= Type x Type PrimitiveType ::= Number | String (define (make-procedure-type params result) (list 'procedure-type params result)) (define (procedure-type? type) (tagged-list? type 'procedure-type)) (define (procedure-type-result type) (assert (procedure-type? type)) (caddr type)) (define (procedure-type-params type) (cadr type)) (define (assert pred) (if (not pred) (error "Assertion failed!"))) 1 April 2002 CS 200 Spring 2002
Type of + (make-procedure-type (make-product-type (make-number-type) 1 April 2002 CS 200 Spring 2002
Changing Frames parameters: x body: (lambda (x) (+ x x)) global environment global environment +: (-> (x Number Number) Number) #<primitive:+> + : #<primitive:+> double: x: 3 double: (-> Number Number) x: Number 3 parameters: x body: (lambda (x) (+ x x)) parameters: x Number body: (lambda (x) (+ x x)) 1 April 2002 CS 200 Spring 2002
Changing Frames (define (extend-environment names values env) (make-new-environment (map (lambda (name value) (cons name value)) names values) env)) (define (extend-environment names types values env) (make-new-environment (map (lambda (name type value) (list name type value)) names types values) env)) 1 April 2002 CS 200 Spring 2002
Looking Up Variables (define (environment-lookup-name name env) (if (null? env) (error "No binding for" name) (if (frame-contains? name (first-frame env)) (frame-lookup-name name (first-frame env)) (environment-lookup-name name (enclosing-environment env))))) (define (environment-lookup-value name env) (if (null? env) (error "No binding for" name) (if (frame-contains? name (first-frame env)) (frame-lookup-value name (environment-lookup-value name (enclosing-environment env))))) (define (typeof-variable name env) (if (null? env) (error "No binding for" name) (if (frame-contains? name (first-frame env)) (frame-lookup-type name (typeof-variable name (enclosing-environment env))))) 1 April 2002 CS 200 Spring 2002
Frame Lookups (define (frame-lookup-value name frame) (if (null? frame) (error "Name not found in frame:" name) (if (eq? (car (car frame)) name) (caddr (car frame)) (frame-lookup-value name (cdr frame))))) (define (frame-lookup-type name frame) (cadr (car frame)) (frame-lookup-type name (cdr frame))))) 1 April 2002 CS 200 Spring 2002
Charge Wednesday: Finish TypedScheme Friday: PS7 Due Handling lambda Friday: PS7 Due Exam 2 out Friday or Monday (class choice), due Weds next week Classify problems (undecidable, NP, P, etc.) Modify TypedScheme 1 April 2002 CS 200 Spring 2002