CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
Did you know? In Computer Science, static analysis corresponds to analyzing the source code, without running the program.
(define (f)
(define x 10) ; visible: `f`
(define y 20) ; visible: `f, f.x`
(+ x y)) ; visible: `f, f.x, f.y`
; visible: `f`
(define x 1)
; visible: `f, x`
(define y (+ x 1))
; visible: `f, x, y`
(check-equal? (f) 30) ; yields (+ `f.x` `f.y`)
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
- Lexical scoping is the default in all popular programming languages
- With lexical scoping, we can analyze the source code to identify the scope of every variable
- With lexical scoping, the programmer can reason about each function independently
appeared in McCarthy’s Lisp 1.0 as a bug and became a feature in all later implementations, such as MacLisp, Gnu Emacs Lisp.
Moreau, L. Higher-Order and Symbolic Computation (1998) 11: 233. DOI:10.1023/A:1010087314987
*;; NOT VALID RACKET CODE!!!
(define (f) `x`)
(define (g `x`) (f))
(check-equal? (g 10) 10)
(define `x` 20)
(check-equal? (f) 20)
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
What is the result of evaluating
(g)?
(define x 1)
(define (f y) (+ y x))
(define (g)
(define x 2)
(define y 3)
(f (+ x y)))
*(check-equal? (g) ???)
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
What is the result of evaluating
(g)?
(define x 1)
(define (f f:y) (+ f:y x))
(define (g)
(define g:x 2)
(define g:y 3)
(f (+ g:x g:y)))
*(check-equal? (g) 6)
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
What is the result of evaluating
(g)?
(define (g) x)
(define x 10)
*(check-equal? (g) ??)
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
What is the result of evaluating
(g)?
(define (g) x)
*; (g) throws an error here
(define x 10)
*(check-equal? (g) 10)
We can define a function
gthat refers to an undefined variablex; variablexmust be defined before callingg.In Racket, variable definition produces a side-effect, as the definition of
ximpacted a previously defined functiong. In Module 5, we implement the semantics ofdefine.
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
The body of a function can refer to variables defined outside of that function.
It can access variables defined outside of the function, but where exactly?
The function's body can access any variable that is accessible/visible when the function is defined, which is known as the lexical scope.
In the following example, the function returns 3 and not 10, even though variable x is now 10.
; For a given x create a new function that always returns x
(define (getter `x`) `(lambda () x)`)
(define get3 (getter 3)) ; At creation time, x = 3
*(define x 10)
(check-equal? 3 (get3)) ; At call time, x = 10
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
!= function definition:CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
It is crucial for us to know how variables are captured in Racket.
Given an expression the set of free variables can be defined inductively:
x, the set of free variables is { x }.(lambda (x) e), the set of free variables is
that of expression e minus variable x.(e1 e2), the set
of free variables is the union of the set of free variables of e1
and the set of free variables of e2.Captured variables: Given an expression (lambda (x) e) a function
closure captures the set of free variables of expression (lambda (x) e).
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
Let us compute $\mathrm{fv}$ (lambda (x) (+ x y)):
$\mathrm{fv}$ (lambda (x) (+ x y)) = $\mathrm{fv}$ (+ x y) $\setminus \{ x \}$
$\mathrm{fv}$ (+ x y) $\setminus \{ x \} = \big( \mathrm{fv}(+) \cup \mathrm{fv}(x) \cup \mathrm{fv}(y) \big) \setminus \{ x \}$
free-vars is a variable.CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
Definition: At any execution point there is an environment, which maps each variable to a value.
What creates environments:
cond creates an environmentWhat updates an environment:
lambda are added to the function's body environment(define x e) updates the current environment by adding/updating variable x and setting it to the value that results from evaluating eCS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
The
lambdais capturingxas the parameter ofgetterat creation time, so when we call(get3)we get(lambda () 3).
(define (getter `x`)
(lambda () x)) ; `getter:x`
(define get3 (getter 3)) ; `getter:x = 3; (lambda () getter:x)`
(check-equal? 3 (get3))
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
cond starts a new scopeFunction
gettercapturedxat the outermost scope (thexcaptured at function declaration time). Inside the branches ofcondwe have a new scope, which means thatgetteris unaffected by the redefinition ofx.
(define (getter) `x`) ; `root.x`
(define x 10) ; root.x = 10
; Each branch of the cond creates a new environment
; so it does not affect getter
(cond [#t (define x 20) (check-equal? 10 (getter))])
(check-equal? 10 (getter))
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
Function
getterreturns variablexfrom the environment of functionf. When callingf 20the last value of variablexin the scope offis10, due to(define x 10), which overwrites the function's parameterx=20.
(define (f x)
(define (getter) `x`) ; `f.x = ?`
(define x 10) ; `f.x = 10`
getter)
(define g (f 20))
(check-equal? 10 (g))
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
$$\frac{ {\color{green} e_f} \Downarrow {\color{purple}\lambda x}.{\color{red} e_b} \qquad {\color{blue}e_a} \Downarrow {\color{blue}v_a} \qquad {\color{red}e_b} \overbrace{[{\color{purple}x} \mapsto {\color{blue}v_a}]}^{\color{brown}\text{Complexity?}} \Downarrow {\color{red}v_b} }{ ({\color{green}e_f}\ {\color{blue}e_a}) \Downarrow \color{red}v_b } \ \texttt{(E-app)} $$
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
Let us consider our implementation of Mini-Racket, and draw our attention to function substitution.
Given a function call $(e_f\ e_a)$
What is the complexity of the substitution operation $[x \mapsto v_a]$?
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
Let us consider our implementation of Mini-Racket, and draw our attention to function substitution.
Given a function call $(e_f\ e_a)$
What is the complexity of the substitution operation $[x \mapsto v_a]$?
The run-time grows linearly on the size of the expression, as we must replace $x$ by $v_a$ in every sub-expression of $e_b$.
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
We introduce the evaluation of expressions down to values, parameterized by environments:
$$ {\color{blue}e} \Downarrow_{\color{blue}E} {\color{green}v} $$The evaluation takes two arguments: an expression $e$, and an environment $E$. The evaluation returns a value $v$.
Homework Assignment 4:
- Evaluation ${\color{blue}e} \Downarrow_{\color{blue}E} {\color{green}v}$ is implemented as function
(e:eval env exp)that returns a valuee:value, where environmentenvis ahash, and expressionexpis ane:expression.- functions and structs prefixed with
s:correspond to the $\lambda_S$ language (Section 1).- functions and structs prefixed with
e:correspond to the $\lambda_E$ language (Section 2)
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
CS450 ☽ Specifying λE ☽ Lecture 14 ☽ Tiago Cogumbreiro
An environment $E$ maps variable bindings to values.