6 001 SICP September 29 6001 Types and
6. 001 SICP – September 29 6001 -Types and HOPs Trevor Darrell trevor@csail. mit. edu 32 -D 512 Office Hour: W 11 6. 001 web page: http: //sicp. csail. mit. edu/ section web page: http: //www. csail. mit. edu/~trevor/6001/ • Types • Higher-order procedures 6. 001 SICP 1
Type examples • expression: evaluates to a value of type: 15 number "hi" string square number > number, number boolean (> 5 4) ==> #t • The type of a procedure is a contract: • If the operands have the specified types, the procedure will result in a value of the specified type • otherwise, its behavior is undefined – maybe an error, maybe random behavior 6. 001 SICP 2
Types, precisely • A type describes a set of scheme values • number describes the set: all procedures, whose result is a number, which require one argument that must be a number • Every scheme value has a type • Some values can be described by multiple types • If so, choose the type which describes the largest set • Special form keywords like define do not name values • therefore special form keywords have no type 6. 001 SICP 3
Procedure Types • procedure types (types which include ) indicate • number of arguments required • type of each argument • type of result of the procedure • Types: a mathematical theory for reasoning efficiently about programs • useful for preventing certain common types of errors • basis for many analysis and optimization algorithms 6. 001 SICP 4
Generic Type Variables Consider: (define identity (lambda (x) x)) (identity 10) ==> 10, etc…. what is it’s type? number -> number ? string -> string ? We use Generic Type Variables when any type is possible: The correct type of identity is: A -> A 6. 001 SICP 5
Example Abstraction using Higher-order procedures Basic idea: use procedural abstraction to capture regular patterns: (* 3 8) (* 2 8) (* 3 29) (* 2 29) (* 3 55) (* 2 55) (triple 8) (double 8) (triple 29) (double 29) (triple 55) (double 55) (define double (lambda (x) (* 2 x))) (define triple (lambda (x) (* 3 x))) 6. 001 SICP 6
Example Abstraction using Higher-order procedures (define double (lambda (x) (* 2 x))) (define triple (lambda (x) (* 3 x))) (define double (make-mult 2)) (define triple (make-mult 3)) (define make-mult (lambda (n) (lambda (x) (* n x)))) 6. 001 SICP 7
Example Abstraction using Higher-order procedures Define a procedure swap that takes a single argument whose type is a function that takes two arguments, and returns a function that acts as the input function but with its argument positions swapped. E. g. , (- 5 4) 1, ((swap -) 5 4) -1. (define swap (lambda (f) (lambda (x y) (f y x)))) 6. 001 SICP 8
Define a composing function Write a procedure composef that takes two arguments (eg. f and g), whose type is a function, and returns a function that first apply g to the input, then f to the result – i. e. ((composef f g) x) should be the same as (f (g x)). (define composef (lambda (f g) (lambda (x) (f (g x)))) ) 6. 001 SICP 9
composef example (define composef (lambda (f g) (lambda (x) (f (g x)))) ) ((composef double cube) 3) (((lambda (f g) (lambda (x) (f (g x)))) double cube) 3) ; ; if double and cube were primitive: ((lambda (x) (double (cube x))) 3) (double (cube 3)) (double 27) 6. 001 SICP 54 10
composef example (define composef (lambda (f g) (lambda (x) (f (g x)))) ) ((composef double cube) 3) (((lambda (f g) (lambda (x) (f (g x)))) double cube) 3) ; ; now expand double and cube: (((lambda (f g) (lambda (x) (f (g x)))) (lambda (x) (* x 2)) (lambda (x) (* x x x))) 3) ; ; continue on next slide 6. 001 SICP 11
composef example (((lambda (f g) (lambda (x) (f (g x)))) (lambda (x) (* x 2)) (lambda (x) (* x x x))) 3) ; ; note how confusing it is to have many different lambdas all with the same parameter name “x” ; ; we can use the “lambda parameter renaming trick”, and rename some of the x’s to unused names when we copy in double and cube: (((lambda (f g) (lambda (x) (f (g x)))) (lambda (y) (* y 2)) (lambda (z) (* z z z))) 3) ; ; now turn the crank! apply the composef lambda to the double and cube lambdas: ; ; here’s the body of composef lambda: (lambda (x) (f (g x))) ; ; f and g are replaced with the double and cube definitions, so ((lambda (x) ((lambda (y) (* y 2)) ((lambda (z) (* z z z)) x))) 3 ) ; ; now apply the composed lambda ((lambda (y) (* y 2)) ((lambda (z) (* z z z)) 3)) ((lambda (y) (* y 2)) (* 3 3 3)) ((lambda (y) (* y 2)) 27) (* 27 2) 54 6. 001 SICP ; ; !!! 12
Type of composef (define composef (lambda (f g) (lambda (x) (f (g x))))) (define myfunc (composef square double)) (myfunc 3) ==> 36 The value of a lambda expression is a procedure The body of composef is a lambda expression Therefore, the result value of composef is a procedure 6. 001 SICP 13
Type of composef The result value of composef is a procedure composef: ? … (? ? ) It has two arguments, both procedures composef: (? ? ), (? ? ) The first arguent is the function f(), the second g(), and composef computes f(g(x)), so we realize that the output type of f is the output type of the composed function composef: (? C), (? ? ) (? C) Similarly the input is the same as the input of g composef: (? C), (A ? ) (A C) and the output of g goes into f! composef: (B C), (A B) (A C) 6. 001 SICP ; ; done! 14
Remember… • calendar… 6. 001 SICP 15
- Slides: 15