Question 1 @ 2024-02-13 18:28
Assuming a correct FLANG substitution, what will the following substitution result in?
-
{call {fun {3} {+ 3 1}} {+ x 2}}
-
{call {fun {x} {+ 3 1}} {+ 3 2}}
-
{call {fun {x} {+ x 1}} {+ 3 2}}
-
{call {fun {x} {+ x 1}} {+ x 2}}
-
{call {fun {x} {+ x 1}} 5}
-
{call {fun {x} 4} 5}
-
Depends on the dynamic context that the expression gets evaluated in.
Question 2 @ 2024-02-13 18:32
In the properly dynamically scoped language that we discussed in class, what would the following code evaluate to?
(define y 1)
(define (f x) (+ x y))
(let ([x 2]
[y 3]
[+ -])
(f 4))
-
-1
-
1
-
2
-
3
-
5
-
7
- Impossible to tell in a dynamically scoped language.
Question 3 @ 2024-02-13 18:36
In the properly dynamically scoped language that we discussed in class, what would the following code evaluate to?
(define x 1)
(define y 2)
(let ([x 11]
[y 22])
(let ([x y]
[y x])
(list x y)))
-
(1 2)
-
(2 2)
-
(2 1)
-
(11 22)
-
(22 22)
-
(22 11)
- Impossible to tell in a dynamically scoped language.
Question 4 @ 2024-02-13 18:39
What will the following return, assuming the current FLANG-ENV
code in
class?
(The Flang language, implemented with environments)
{fun {y} {+ y x}}}")
(EmptyEnv))
-
(NumV 5)
because that’s the value ofx
-
(NumV 5)
becauseeval
always returns aNumV
result -
(FunV 'y (Add (Id 'y) (Id 'x)) (Extend 'x (NumV 5) (EmptyEnv)))
-
(FunV 'y (Add (Id 'y) (NumV 5)) (EmptyEnv))
-
The question is bogus because
eval
will throw an error on non-NumV
results.
Question 5 @ 2024-02-13 18:44
Which of the following advantages of dynamic scope is correct?
-
Dynamic scope facilitates easier compilation due to its reliance on the lexical structure of programs.
-
Dynamic scope allows for easy configuration of variables at runtime, making it good for languages like Racket.
-
Dynamic scope allows for easy configuration of variables at runtime, making it good for reusing code in unexpected ways.
-
Dynamic scope ensures that all functions are modifiable, leading to a more flexible codebase.
-
Dynamic scope makes recursion easy, but not as much as lexical scope.
Question 6 @ 2024-02-13 18:46
Reflecting on the Fun
and Call
expressions’ evaluation strategy, why
is the substitution cache crucial for implementing closures in a
language that supports first-class functions?
-
It ensures that every function call is memoized, thus speeding up repeated calls to the same function with identical arguments.
-
It allows functions to retain access to the environment in which they were defined, independent of where they are called from dynamically.
-
It provides a mechanism for functions to modify their behavior dynamically based on the calling context.
-
It simplifies the parser implementation by caching parsed function bodies for reuse in subsequent evaluations.