CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
e:env-get and e:env-put. (Exercise 3)CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(define-type s:value (U s:number s:lambda))
(define-type s:expression (U s:value s:variable s:apply))
(struct s:number ([value : Number]))
(struct s:variable ([name : Symbol]))
(struct s:lambda ([param : s:variable] [body : s:expression]))
(struct s:apply ([func : s:expression] [arg : s:expression]))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(define-type e:value (U e:number e:closure))
; n
(struct e:number ([value : Number]))
; {E,λx.e}
(struct e:closure (
[env : e:environ] ; E
[param : e:variable] ; x
[body : e:expression] ; e
)
)
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(define-type e:expression (U e:value e:variable e:apply e:lambda))
; x
(struct e:variable ([ name : Symbol ]))
; (e1 e2)
(struct e:apply (
[func : e:expression] ; e1
[arg : e:expression] ; e2
))
; λx.e
(struct e:lambda (
[param : e:variable] ; x
[body : e:expression] ; e
))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(hash)CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(hash)(e:env-get E x)CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(hash)(e:env-get E x)(e:env-put E x v)CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
Function (check-e:eval? env exp val) is given in the template to help you test
your code effectively.
The use of
check-e:eval?is optional. You are encouraged to play around withe:evaldirectly.
[] ; `The empty environment`
[ (x . 1) ] ; `An environment where x is bound to 1`
[ (x . 1) (y . 2) ] ; `An environment where x is bound to 1 and y is bound to 2`
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
Each line represents a quoted expression as a parameter of function
e:parse-ast. For instance,(e:parse-ast '(x y))should return(e:apply (e:variable 'x) (e:variable 'y)).
1 ; `(e:number 1)`
x ; `(e:variable 'x)`
(closure [(y . 20)] (lambda (x) x))
; `(e:closure`
; `(hash (e:variable 'y) (e:number 20))`
; `(e:variable 'x)`
; `(e:variable 'x))`
(lambda (x) x) ; `(e:lambda (e:variable 'x) (e:variable 'x))`
(x y) ; `(e:apply (e:variable 'x) (e:variable 'y))`
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
; `x is bound to 1, so x evaluates to 1`
(check-e:eval? '[(x . 1)] 'x 1)
; `20 evaluates to 20`
(check-e:eval? '[(x . 2)] 20 20)
; `a function declaration evaluates to a closure`
(check-e:eval? '[] '(lambda (x) x) '(closure [] (lambda (x) x)))
; `a function declaration evaluates to a closure; notice the environment change`
(check-e:eval? '[(y . 3)] '(lambda (x) x) '(closure [(y . 3)] (lambda (x) x)))
; `because we use an S-expression we can use brackets, curly braces, or parentheses`
(check-e:eval? '{(y . 3)} '(lambda (x) x) '(closure [(y . 3)] (lambda (x) x)))
; `evaluate function application`
(check-e:eval? '{} '((lambda (x) x) 3) 3)
; `evaluate function application that returns a closure`
(check-e:eval? '{} '((lambda (x) (lambda (y) x)) 3) '(closure {[x . 3]} (lambda (y) x)))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
Disciplining an ambiguous presentation medium to communicate a precise mathematical meaning (notation and convention)
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
cond represents a ruleCS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
cond represents a rule(define (M n)
(cond
[(> n 100) (- n 10)]
[(<= n 100) (M (M (+ n 11)))]))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(define (M n)
(cond
[(> n 100) (- n 10)]
[(<= n 100) (M (M (+ n 11)))]))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
x must be defined before y)CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
x must be defined before y)(define (M n)
(cond
[(> n 100) (- n 10)]
[(<= n 100)
(define x (M (+ n 11)))
(define y (M x))
y]))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
Let us define the $M$ function with the 📻 symbol. The intent of notation is to aid the reader and reduce verbosity.
$$\frac{ n > 100 }{ n\ 📻\ n - 10 } \qquad \frac{ n + 11 \ 📻\ x \qquad x \ 📻\ y \qquad n \le 100 }{ n \ 📻\ y } $$How do we write $M(M(n + 11))$?
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(define (qs l)
(cond [(empty? l) empty] ; `qs([]) = []`
[else
; `Input: p :: r `
(define p (first l))
(define r (rest l))
; `qs([ x | x < p /\ x \in l]) = l1`
(define l1 (qs (filter (lambda (x) (< x p)) r)))
; `qs([ x | x >= p /\ x \in l]) = l2`
(define l2 (qs (filter (lambda (x) (>= x p)) r)))
; `l1 . p . l2`
(append l1 (cons p l2))]))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
Exercise 1. Function $e[x := v]$ is (s:subst exp var val),
where $e$ is exp, $x$ is var, and $v$ is val.
Exercise 2. Function $e \Downarrow v$ is (s:eval subst exp),
where $e$ is exp, $v$ is the return value (not displayed in the function signature).
In the exercise, parameter
substrepresents the substitution function (local tests use your own implementation, remote tests use a correct implementation of subst).
Exercise 3. Function $e \Downarrow_{E} v$ is (e:eval env exp),
where $e$ is exp, $E$ is env, $v$ is the return value (not displayed in the function signature).
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
Why? Because you will be needing test-cases.
(require rackunit)
(define ns (make-base-namespace))
(define (run-bool b) (((eval b ns) #t) #f))
; True
(define TRUE '(lambda (a) (lambda (b) a)))
(define FALSE '(lambda (a) (lambda (b) b)))
(define (OR a b) (list (list a TRUE) b))
(define (AND a b) (list (list a b) FALSE))
(define (NOT a) (list (list a FALSE) TRUE))
(define (EQ a b) (list (list a b) (NOT b)))
; Test
(check-equal?
(run-bool (EQ TRUE (OR (AND FALSE TRUE) TRUE)))
(equal? #t (or (and #f #t) #t)))
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
TL;DR: A data-structure that stores pairs of key-value entries. There is a lookup operation that given a key retrieves the value associated with that key. Keys are unique in a hash-table, so inserting an entry with the same key replaces the old value by the new value.
Hash-tables represent a (partial) function.
Hash-tables were covered in CS310.
Hash-tables are also known as maps, and dictionaries. We use the term hash-table, because that is how they are known in Racket.
CS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(hash k1 v1 ... kn vn) creates a hash-table with the given key-value entries. Passing zero arguments, (hash), creates an empty hash-table.(hash-set h k v) copies hash-table h and adds/replaces the entry k v in the new hash-table.(hash? h) returns #t if h is a hash-table, otherwise it returns #f(hash-count h) returns the number of entries stored in hash-table h(hash-has-key? h k) returns #t if the key is in the hash-table, otherwise it returns #f(hash-ref h k) returns the value associated with key k, otherwise abortsCS450 ☽ Exercises ☽ Lecture 15 ☽ Tiago Cogumbreiro
(define h (hash)) ; creates an empty hash-table
(check-equal? 0 (hash-count h)) ; we can use hash-count to count how many entries
(check-true (hash? h)) ; unsurprisingly the predicate hash? is available
(define h1 (hash-set h "foo" 20)) ; creates a new hash-table where "foo" is bound to 20
(check-equal? (hash "foo" 20) h1) ; (hash-set (hash) "foo" 20) = (hash "foo" 20)
(define h2 (hash-set h1 "foo" 30))
(check-equal? (hash "foo" 30) h2) ; in h2 "foo" is the key, and 30 the value
(check-equal? 30 (hash-ref h2 "foo")) ; ensures that hash-ref retrieves the value of "foo"
(check-equal? (hash "foo" 20) h1) ; h1 remains the same