Question 1 @ 2024-11-05 18:40
Consider this implementation of a recursive binder:
(eval bound-body
(Some-Kind-of-Extend bound-id (eval named-expr env) env))]
What’s wrong with it?
- It is perfectly fine.
-
It is fine, except for
WRec
which should beRec
. -
Impossible to tell without knowing how
Some-Kind-of-Extend
is implemented. - It will lead to a type error: undefined value
- The named-expr is evaluated too early and with the previous environment.
- It can create an infinite loop.
Question 2 @ 2024-11-05 18:43
Say that we enter the following in the Racket REPL:
> (define y (box 'green))
> (set-box! x (set-box! y 'blue))
> (unbox x)
What is the result of the last expression?
-
'red
-
'green
-
'blue
-
#<void>
- Type Error
- Infinite loop
Question 3 @ 2024-11-05 18:45
Say that we enter the following in the Racket REPL:
> (define y (box #f))
> (set-box! x (set-box! y x))
Does this result in a cyclic structure?
(Reminder: choose the best answer!)
- Yes.
-
Yes,
x
points toy
, and vice versa. - No.
- No, because the computation gets stuck in an infinite loop.
- Impossible to tell, since it depends on whether the language is lazy or eager.
Question 4 @ 2024-11-05 18:49
Say that you’re working in a REPL of a Racket-like language, and
you have a box value in x
:
Consider the following expression:
(unbox x))
Based on the result of this expression, you’ll be able to tell whether the language:
-
… evaluates left-to-right or right-to-left.
-
… is eager or lazy.
-
… uses lexical scope or dynamic scope.
-
… returns the new value, the old value, or some useless value as a result of varaible assignment.
-
… returns the new value, the old value, or some useless value as a result of a box mutation.
-
… is statically typed or dynamically typed.
Question 5 @ 2024-11-05 18:52
During some random REPL-based hacking of a web page, I entered:
What could be a reason that I used () => f()
rather than just f
?
Notes:
- Racket translation: …
(lambda () (f))
rather than justf
? setInterval(F, N)
arranges forF
to be called everyN
milliseconds.
(Keep in mind that this is in the full Javascript language, equivalent to the full Racket language.)
- Make the code run slower, so it’s easier to debug.
- Reveal a language-implementation-level bug.
-
Call
f
lazily. -
Avoid a potential infinite loop, like our Y’s
protect
. -
Make it possible to modify
f
interactively.