I was learning SICP and I read about "the applicative order" and "the normal order". Then I played around the Exercise 1-6 and looked into the following code:
#lang racket
(define (p) (p))
(define (new-if test-expr then-expr else-expr)
(cond (test-expr then-expr)
(else else-expr)))
And when I evaluate (new-if (= 2 2) 5 (p))
, it goes into a dead loop because both the (= 2 2)
and (p)
are evaluated. So I wonder how to make this new-if
in the normal order without changing the #lang racket
into #lang lazy
, but I can't figure it out.
> (new-if (= 2 2) 5 (p))
> 5
You cannot change the evaluation order of #lang racket
. #lang lazy
works since it is normal order. You can delay evalution with delay
/ force
:
#lang racket
(define (p) (p))
(define (new-if test-expr then-expr else-expr)
(cond ((force test-expr) (force then-expr))
(else (force else-expr))))
(new-if (delay (= 2 2)) (delay 5) (delay (p))) ; ==> 5
Without side effects you can replace delay
with wrapping in a no argument lambda (thunk) and change force
to apply the procedure.