Question 1 @ 2025-02-18 18:31
You’re running into a situation where a language that you need to implement is very different from the language you’re implementing it in.
What kind of evaluator would you likely implement for this language?
- Syntactic evaluator
- Meta evaluator
- Meta-circular evaluator
- Can go either way
- Bogus question, these terms are unrelated in this context
Question 2 @ 2025-02-18 18:33
We’ve talked about the difference between syntactic and meta evaluators. Which of the following features demonstrates a meta evaluator in our Flang language?
-
With
-
Call
-
Fun
- Arithmatic operations
- None
Question 3 @ 2025-02-18 18:35
What is the purpose of the Y-combinator?
(Choose the best answer)
- Allow recursive functions in lexically-scoped languages
- Allow recursive functions in dynamically-scoped languages
- Allow recursive functions regardless of scope
- Represent numbers using lambdas
-
Often called
fix
because it can prevent infinite loops in code - Provides seed capital for start-ups
Question 4 @ 2025-02-18 18:37
Reminder: the Y combinator definition that we used is
(rewrite (protect f) => (lambda (x) (f x)))
(define (make-recursive f)
((lambda (x) (x x)) (lambda (x) (f (protect (x x))))))
(define (make-recursive f)
((lambda (x) (x x)) (lambda (x) (f (protect (x x))))))
Why do we need this “protection”?
- Without it we get a free identifier instead of a recursive reference
- Avoids the problem of laziness
- Avoid infinite loop due to eager evaluation
- Without it we get a lazy Y, so using it will be much slower
- Enables substitution when using lexical scope
- The Y combinator does not need protection
Question 5 @ 2025-02-18 18:45
Reminder: the Y combinator definition that we used is
(rewrite (protect f) => (lambda (x) (f x)))
(define (make-recursive f)
((lambda (x) (x x)) (lambda (x) (f (protect (x x))))))
(define (make-recursive f)
((lambda (x) (x x)) (lambda (x) (f (protect (x x))))))
Why didn’t we use a simple definition for protect
(define (protect f) (lambda (x) (f x)))
?
- Bogus question: there is no need for this
- Simple definitions don’t work right in a lazy language
-
It is wrong to have a function that returns a
lambda
-
This is in Racket, and there is no need for
Y
in Racket -
As we’ve seen later,
protect
is more for clarity, so it’s not needed -
Using a function defeats the purpose, much like defining an
if
-like function
Question 6 @ 2025-02-18 18:46
Are the following two definitions of Y valid and equivalent?
(define Y1
(lambda (f)
((lambda (x) (f (lambda (n) ((x x) n))))
(lambda (x) (f (lambda (n) ((x x) n)))))))
(define Y2
(lambda (f)
((lambda (x) (x x))
(lambda (x) (f (lambda (n) ((x x) n)))))))
(lambda (f)
((lambda (x) (f (lambda (n) ((x x) n))))
(lambda (x) (f (lambda (n) ((x x) n)))))))
(define Y2
(lambda (f)
((lambda (x) (x x))
(lambda (x) (f (lambda (n) ((x x) n)))))))
- Yes
- Yes, only if we’re using an eager language
- Yes, only if we’re using an lazy language
- They’re equivalent, but wrong
- They’re equivalent, but wrong: both will loop infinitely
- No, on both counts