CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
defineCS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$v ::= n \mid \{E,\lambda x.t\} \mid \mathtt{void} $$We add
voidto values.
;; Values
(define (f:value? v) (or (f:number? v) (f:closure? v) (f:void? v)))
(struct f:number (value))
(struct f:closure (env decl))
(struct f:void ())
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$e ::= v \mid x \mid (e_1\ e_2) \mid \lambda x.t $$Expressions remain unchanged.
(define (f:expression? e) (or (f:value? e) (f:variable? e) (f:apply? e) (f:lambda? e)))
(struct f:variable (name))
(struct f:apply (func args))
(struct f:lambda (params body))
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$t ::= e \mid t;t \mid (\mathtt{define}\ x\ e) $$We implement terms below.
(define (f:term? t) (or (f:expression? t) (f:seq? t) (f:define? t)))
(struct f:seq (fst snd))
(struct f:define (var body))
A sequence is not present in the concrete syntax, but it simplifies the implementation and formalism (see reduction)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
defineCS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
defineCS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Consider the following program
(define a 20)
(define b (lambda (y) a))
(b 1)
What is the output of this program?
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Consider the following program
(define a 20)
(define b (lambda (y) a))
(b 1)
What is the output of this program? The output is:
20
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: []
Term: (define a 20)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: []
Term: (define a 20)
Environment: [ `(a . 20)` ]
Value: `void`
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: []
Term: (define a 20)
Environment: [ `(a . 20)` ]
Value: `void`
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [ (a . 20) ]
Term: (define b (lambda (y) a))
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [ (a . 20) ]
Term: (define b (lambda (y) a))
Environment: [
(a . 20)
(b . (closure `[(a . 20)]` (lambda (y) a)))
]
Value: void
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [ (a . 20) ]
Term: (define b (lambda (y) a))
Environment: [
(a . 20)
(b . (closure `[(a . 20)]` (lambda (y) a)))
]
Value: void
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(a . 20)
(b . (closure [(a . 20)] (lambda (y) a)))
]
Term: (b 1)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(a . 20)
(b . (closure [(a . 20)] (lambda (y) a)))
]
Term: (b 1)
Environment: [
(a . 20)
(b . (closure [(a . 20)] (lambda (y) a)))
]
Value: 20
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(a . 20)
(b . (closure [(a . 20)] (lambda (y) a)))
]
Term: (b 1)
Environment: [
(a . 20)
(b . (closure [(a . 20)] (lambda (y) a)))
]
Value: 20
where
${\color{blue}E}= {\{a:20,b:(\{a:20\}, \lambda y.a)\}}$
${\color{purple}F} = {\{a:20\}}[y \mapsto 1] = \{a:20, {\color{red}y:1}\}$
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Consider the following program
(define b (lambda (y) a))
(define a 20)
(b 1)
What is the output of this program?
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Consider the following program
(define b (lambda (y) a))
(define a 20)
(b 1)
What is the output of this program? The output is:
20
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: []
Term: (define b (lambda (y) a))
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: []
Term: (define b (lambda (y) a))
Environment: [
(b . (closure `[]` (lambda (y) a)))
]
Value: void
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: []
Term: (define b (lambda (y) a))
Environment: [
(b . (closure `[]` (lambda (y) a)))
]
Value: void
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(b . (closure [] (lambda (y) a)))
]
Term: (define a 20)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(b . (closure [] (lambda (y) a)))
]
Term: (define a 20)
Environment: [
`(a . 20)`
(b . (closure [] (lambda (y) a)))
]
Value: void
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(b . (closure [] (lambda (y) a)))
]
Term: (define a 20)
Environment: [
`(a . 20)`
(b . (closure [] (lambda (y) a)))
]
Value: void
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(a . 20)
(b . (closure [] (lambda (y) a)))
]
Term: (b 1)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
Environment: [
(a . 20)
(b . (closure [] (lambda (y) a)))
]
Term: (b 1)
Environment: [
(a . 20)
(b . (closure `[]` (lambda (y) a)))
]
Value: `error! a is undefined`
When creating a closure we copied the existing environment, and therefore any future updates are forgotten.
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$\frac{ e \Downarrow_{E} v \qquad {\color{red} E \leftarrow [ x := v]} }{ (\mathtt{define}\ x\ e) \Downarrow_{E} \mathtt{void} } \ \texttt{(E-def)} \\[2em] \frac{ t_1 \Downarrow_{E} v_1 \qquad t_2 \Downarrow_{E} v_2 }{ t_1; t_2 \Downarrow_{E} v_2 } \ \texttt{(E-seq)} $$We highlight in $\color{red}\text{red}$ an operation that produces a side-effect: mutating an environment.
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$v \Downarrow_{E} v \qquad (\texttt{E-val}) $$ $$x \Downarrow_{E} {E}(x) \qquad (\texttt{E-var}) $$ $$\lambda x.t \Downarrow_{E} ({E},\lambda x.t) \qquad (\texttt{E-lam}) $$ $$\frac{ e_f \Downarrow_{E} (E_f,\lambda x. t_b) \qquad e_a \Downarrow_{E} v_a \qquad {\color{red} E_b \leftarrow E_f + [x := v_a] } \qquad t_b \Downarrow_{E_b} v_b }{ (e_f\ e_a) \Downarrow_E v_b } \ \texttt{(E-app)} $$Because we have side-effects, the order in which we evaluate each sub-expression is important.
Can you explain why the order is important?
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$v \Downarrow_{E} v \qquad (\texttt{E-val}) $$ $$x \Downarrow_{E} {E}(x) \qquad (\texttt{E-var}) $$ $$\lambda x.t \Downarrow_{E} ({E},\lambda x.t) \qquad (\texttt{E-lam}) $$ $$\frac{ e_f \Downarrow_{E} (E_f,\lambda x. t_b) \qquad e_a \Downarrow_{E} v_a \qquad {\color{red} E_b \leftarrow E_f + [x := v_a] } \qquad t_b \Downarrow_{E_b} v_b }{ (e_f\ e_a) \Downarrow_E v_b } \ \texttt{(E-app)} $$Because we have side-effects, the order in which we evaluate each sub-expression is important.
Can you explain why the order is important? Otherwise, we might evaluate the body of the function $t_b$ without observing the assignment $x := v_a$ in $E_b$.
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$E \leftarrow [ x := v]$
Take a reference to an environment $E$ and
mutate its contents, by adding a new binding.
$E \leftarrow E' + [x := v]$
Create a new environment referenced by $E$ which copies the elements of $E'$ and also adds a new binding.
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$\frac{ % \blacktriangleright e \Downarrow_{E} v \quad\blacktriangleright\quad {\color{red} E \leftarrow [ x := v]} }{ % \blacktriangleright (\mathtt{define}\ x\ e) \Downarrow_{E} \mathtt{void} } \texttt{(E-def)} \\[2em] \frac{ % \blacktriangleright t_1 \Downarrow_{E} v_1 \quad\blacktriangleright\quad t_2 \Downarrow_{E} v_2 }{ % \blacktriangleright t_1; t_2 \Downarrow_{E} v_2 } \texttt{(E-seq)} \\[2em] \frac{ % \blacktriangleright e_f \Downarrow_{E} (E_f,\lambda x. t_b) \ \blacktriangleright \ e_a \Downarrow_{E} v_a \ \blacktriangleright \ {\color{red} E_b \leftarrow E_f + [x := v_a] } \ \blacktriangleright \ t_b \Downarrow_{E_b} v_b }{ %\blacktriangleright (e_f\ e_a) \Downarrow_E v_b } \texttt{(E-app)} $$Let us use a triangle $\blacktriangleright$ to represent the order of side-effects.
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
$$\frac{ \blacktriangleright_H \quad e \Downarrow_{E} v \quad \blacktriangleright_{H_1} \quad {\color{red} E \leftarrow [ x := v]} \quad \blacktriangleright_{H_2} }{ \blacktriangleright_H\ (\mathtt{define}\ x\ e) \Downarrow_{E} \mathtt{void} \blacktriangleright_{H_2} } \ \texttt{(E-def)} $$We can annotate each triangle with a heap, to make explicit how the global heap should be passed from one operation to the next. In this example, defining a variable takes an input global heap $H$ and produces an output global heap $H_2$.
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
(define b (lambda (y) a))
(define a 20)
(b 1)
E0: []
---
Env: E0
Term: (define b (lambda (y) a))
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
(define b (lambda (y) a))
(define a 20)
(b 1)
E0: []
---
Env: E0
Term: (define b (lambda (y) a))
E0: [
(b . (closure `E0` (lambda (y) a)))
]
Value: void
$$\frac{ % \blacktriangleright \cfrac{ }{ \lambda y.a \Downarrow_{E_0} ({E_0},\lambda y.a) } \quad\blacktriangleright\quad \cfrac{}{\color{red} E_0 \leftarrow [ b := ({E_0},\lambda y.a)]} }{ % \blacktriangleright (\mathtt{define}\ b\ \lambda y.a) \Downarrow_{E_0} \mathtt{void} } $$
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
E0: [
(b . (closure E0 (lambda (y) a)))
]
---
Env: E0
Term: (define a 20)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
E0: [
(b . (closure E0 (lambda (y) a)))
]
---
Env: E0
Term: (define a 20)
E0: [
`(a . 20)`
(b . (closure E0 (lambda (y) a)))
]
Value: void
$$\frac{ % \blacktriangleright \cfrac{ }{ 20 \Downarrow_{E_0} 20 } \quad\blacktriangleright\quad \cfrac{}{\color{red} E_0 \leftarrow [ a := 20]} }{ % \blacktriangleright (\mathtt{define}\ a\ 20) \Downarrow_{E_0} \mathtt{void} } $$
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
E0: [
(a . 20)
(b . (closure E0 (lambda (y) a)))
]
---
Env: E0
Term: (b 1)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
E0: [
(a . 20)
(b . (closure E0 (lambda (y) a)))
]
---
Env: E0
Term: (b 1)
E0: [
(a . 20)
(b . (closure E0 (lambda (y) a)))
]
*E1: [ E0
* (y . 1)
*]
*Value: 20
$$\frac{ % \blacktriangleright b \Downarrow_{E_0} (E_0,\lambda y. a) \ \blacktriangleright \ 1 \Downarrow_{E_0} 1 \ \blacktriangleright \ {\color{red} E_1 \leftarrow E_0 + [y := 1] } \ \blacktriangleright \ a \Downarrow_{E_1} 20 }{ %\blacktriangleright (b\ 1) \Downarrow_{E_0} 20 } $$
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
*(define (f x) (lambda (y) x))
(f 10)
E0: []
---
Env: E0
Term: (define (f x) (lambda (y) x))
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
*(define (f x) (lambda (y) x))
(f 10)
E0: []
---
Env: E0
Term: (define (f x) (lambda (y) x))
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
Value: void
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
*(define (f x) (lambda (y) x))
(f 10)
E0: []
---
Env: E0
Term: (define (f x) (lambda (y) x))
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
Value: void
$$\frac{ % \blacktriangleright \lambda x.\lambda y.x \Downarrow_{E_0} (E_0, \lambda x.\lambda y.x) \qquad \phantom{ \blacktriangleright\quad \color{red} E_0 \leftarrow [ f := (E_0, \lambda x.\lambda y.x)] } }{ %\blacktriangleright (\texttt{define}\ f\ \lambda x.\lambda y.x) \Downarrow_{E_0} \texttt{void} } $$
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
(define (f x) (lambda (y) x))
(f 10)
E0: []
---
Env: E0
Term: (define (f x) (lambda (y) x))
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
Value: void
$$\frac{ % \blacktriangleright \lambda x.\lambda y.x \Downarrow_{E_0} (E_0, \lambda x.\lambda y.x) \quad\blacktriangleright\quad \color{red} E_0 \leftarrow [ f := (E_0, \lambda x.\lambda y.x)] }{ %\blacktriangleright (\texttt{define}\ f\ \lambda x.\lambda y.x) \Downarrow_{E_0} \texttt{void} } $$
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
---
Env: E0
Term: (f 10)
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
---
Env: E0
Term: (f 10)
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
E1: [ E0 (x . 10) ]
Value: (closure E1 (lambda (y) x))
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
---
Env: E0
Term: (f 10)
E0: [
(f . (closure E0
(lambda (x) (lambda (y) x))))
]
E1: [ E0 (x . 10) ]
Value: (closure E1 (lambda (y) x))
$$\frac{ % \blacktriangleright \cfrac{ E_0(f) = (E_0, {\color{blue}\lambda x}.{\color{green}\lambda y.x}) }{ f \Downarrow_{E_0} (E_0, {\color{blue}\lambda x}.{\color{green}\lambda y.x}) } \quad \cfrac{ }{ 10 \Downarrow_{E_0} 10 } \quad \cfrac{}{ E_1 \leftarrow E_0 + [{\color{blue}x} := 10] } \quad \cfrac{ }{ {\color{green}\lambda y.x} \Downarrow_{E_1} \color{purple}(E_1, \lambda y.x) } }{ %\blacktriangleright (f\ 10) \Downarrow_{E_0} \color{purple}(E_1, \lambda y.x) } $$
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
CS450 ☽ Challenges specifying Racket's define ☽ Lecture 16 ☽ Tiago Cogumbreiro
b must somehow access variable a which is defined
after its creation.; Env: `[]`
(define b (lambda (x) a))
; Env: `[(b . (closure ?? (lambda (x) a)))]`
(define a 20)
; Env: `[(b . (closure ?? (lambda (x) a))) (a . 20)]`
(b 1)