1 Context: normal vs. applicative order
1.1 Applicative order voor evaluatie van operands
• eval evalueert voor een procedure-oproep de operator en alle operands anticipatief
• apply ontvangt de resulterende procedure en lijst van waarden
1.2 Normal order voor evaluatie van operands
• eval evalueert voor een procedure-oproep alleen de operator maar nog niet de operands
• apply ontvangt de resulterende procedure en een lijst van expressies
o de evaluatie van elk van deze expressies wordt uitgesteld
▪ tot haar waarde geprint moet worden op de read-eval-print loop
▪ tot haar waarde nodig is om te beslissen over de control flow (e.g.,
predicaat-deelexpressie van een if-expressie)
▪ tot haar waarde als concreet argument
moet dienen voor een primitieve die
“strikt” is in de corresponderende
parameter
• Voorbeeld: “+” is strikt in elk van zijn parameters maar cons-stream
niet in 2e parameter
2 Voorstelling van uitgestelde waarden: thunks
1
, (define (delay-it exp env)
(list 'thunk exp env))
Env wordt bijgehouden omdat, wanneer expressie uiteindelijk wel
geëvalueerd kan worden, we een env nodig hebben.
(define (thunk? obj)
(tagged-list? obj 'thunk))
(define (thunk-exp thunk)
(cadr thunk))
(define (thunk-env thunk)
(caddr thunk))
3 Uitgestelde waarden berekenen
(define (force-it obj)
Obj is een thunk of een waarde
(if (thunk? obj)
Als het nog een thunk is, actual-value berekenen
(actual-value (thunk-exp obj) (thunk-env obj))
Anders gewoon waarde teruggeven → recursie stopt
obj))
(define (actual-value exp env)
(force-it (eval exp env)))
Uit eval komt een waarde of een thunk → forceren
4 Aanpassing van de read-eval-print loop
(define input-prompt ";;; L-Eval input:")
(define output-prompt ";;; L-Eval value:")
2