Question 1 @ 2025-04-01 18:40
At some point we’ve seen that we can end up with the wrong scope when we try to implement a lazy language.
How did we address this issue?
- Make the language more lazy
- Make the language more eager
- Use de-bruijn indexes
- Switched to a call-by-name evaluation
- Switched to a call-by-value evaluation
- Switched to a call-by-need evaluation
- Added expression closures
- Used Racket thunks
Question 2 @ 2025-04-01 18:42
Consider the following type definition for VAL
from our lazy Sloth
language implementation:
[RktV Any]
[FunV (Listof Symbol) SLOTH ENV]
[ExprV SLOTH ENV (Boxof (U #f VAL))]
[PrimV ((Listof VAL) -> VAL)])
Is this from the version of Sloth that implements a call by name or a call by need language?
(Choose the best answer.)
-
Call by name, because we look up the value of each
ExprV
in the environment using its name. -
Call by name, because the value of each
ExprV
is recalculated every time it is evaluated. -
Call by need, because the value of each
ExprV
is cached after the first time it is evaluated. -
Call by need, because
strict
is only called on anExprV
when we need to force it into a proper value. -
Trick question: this is actually for an implementation of an eager language.
-
Impossible to tell.
Question 3 @ 2025-04-01 18:44
Our first Sloth implementation was a “call by name” language, but then we switched to a “call by need” implementation.
Why?
- To avoid lexical redundancy.
- To avoid dynamic redundancy.
- To enable IO and other side-effects.
- To resolve the problem of using dynamic scope.
- To avoid a broken implementation that was mostly lazy but still had some eager cases.
- To avoid redundant errors.
Question 4 @ 2025-04-01 18:46
We’ve talked about how a whole class of programming problems become much easier to handle with laziness. What is it?
- Compilation
- Scope
- Memory management
- Typechecking
- Control flow
- Numerical analysis
- I/O
Question 5 @ 2025-04-01 18:47
Remember the type we used in class to represent IO operations in a lazy language:
[Print String]
[ReadLine (String -> IO)]
[Begin2 IO IO])
Say that we want to add functionality to retrieve the contents of a URL. How should its representation (in the form of another IO variant) look like?
-
A lazy language cannot deal with such functionality, since the web is non-deterministic (even for the same URL).
-
[Fetch String]
-
[Fetch IO (String -> IO)]
-
[Fetch (IO -> String -> IO)]
-
[Fetch String (String -> IO)]
-
[Fetch IO (String -> IO)]