Lecture 7, July 3
The lecture notes I post serve two purposes: to remind you of the topics we discussed and to provide any interesting code examples I did during lecture. I would describe these notes as an outline, not a summary, of what I talked about during lecture. You are not expected to be able to learn the material simply from examining these notes, nor is reading these notes a reasonable substitute for attending lecture.
Local
We started by discussing local definitions. You can put multiple definitions in each local. You can shadow other variables with local definitions.
(: x Real) (define x 8) (: f (Real -> Real)) (define (f x) (+ x (local {(: x Real) (define x 5) (: y Real) (define y 10)} (+ x y)))) (+ x (f 4))
Types
We discussed subtypes and singleton types. We also discussed the difference between the Listof type and the List type.
Zero inputs to a function
Functions can take zero inputs and structures can have zero parts. This is unusual, but inportant.
Recursive Structures
We modified the russian doll example from the text book for typed racket.
(define-type RD (U String Layer)) (define-struct Layer ([color : String] [doll : RD])) (Layer "yellow" (Layer "red" "blue")) (: num-layers (RD -> Positive-Integer)) ; Computes number of layers in a RD ; (num-layers "blue") -> 1 ; (num-layers (Layer "yellow" (Layer "red" "blue"))) -> 3 (define (num-layers rd) (cond [(Layer? rd) (+ 1 (num-layers (Layer-doll rd)))] [else 1]))
We also formulated a structure for representing natural numbers.
(define-type Nat (U Zero Add1)) (define-struct Zero ()) (define-struct Add1 ([n : Nat])) (: zero Nat) (define zero (Zero)) (: one Nat) (define one (Add1 (Zero))) (: two Nat) (define two (Add1 (Add1 (Zero)))) (: three Nat) (define three (Add1 two)) ; Sub1 subtracts one from a natural number ; It is a type error to attempt to subtract 1 from 0 (: Sub1 (Add1 -> Nat)) (define (Sub1 n) (Add1-n n)) ; add-nat adds two natural numbers together (: add-nat (Nat Nat -> Nat)) (define (add-nat a b) (cond [(Zero? a) b] [else (add-nat (Sub1 a) (Add1 b))])) ; gt-nat takes two natural numbers and outputs a boolean ; It outputs true if the first input is greater than the second (: gt-nat (Nat Nat -> Boolean)) (define (gt-nat a b) (cond [(and (Zero? a) (Zero? b)) false] [(Zero? a) false] [(Zero? b) true] [else (gt-nat (Sub1 a) (Sub1 b))])) ; even-nat? takes one natural number and outputs a boolean ; It outputs true if the number is even (: even-nat? (Nat -> Boolean)) (define (even-nat? a) (cond [(Zero? a) true] [else (not (even-nat? (Sub1 a)))])) ; prod-nat takes two natural numbers as inputs and outputs a natural number ; It computes the product of the two inputs (: prod-nat (Nat Nat -> Nat)) (define (prod-nat a b) (cond [(Zero? a) (Zero)] [else (add-nat b (prod-nat (Sub1 a) b))])) ; sub-nat takes two natural numbers as inputs and outputs a natural number ; It subtracts the second from the first ; It is an error to subtract a larger number from a smaller one (: sub-nat (Nat Nat -> Nat)) (define (sub-nat a b) (cond [(Zero? b) a] [(Zero? a) (error "Cannot subtract larger nat from smaller nat")] [else (sub-nat (Sub1 a) (Sub1 b))]))