2
\$\begingroup\$

From SICP:

Exercise 3.8

When we defined the evaluation model in section 1.1.3, we said that the first step in evaluating an expression is to evaluate its subexpressions. But we never specified the order in which the subexpressions should be evaluated (e.g., left to right or right to left). When we introduce assignment, the order in which the arguments to a procedure are evaluated can make a difference to the result. Define a simple procedure f such that evaluating (+ (f 0) (f 1)) will return 0 if the arguments to + are evaluated from left to right but will return 1 if the arguments are evaluated from right to left.

I wrote this solution:

(define it false)
(define (f x)
 (if it
 it
 (begin (set! it (/ x 2)) it)))
(+ (f 1) (f 0))

Is there a better way?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked May 19, 2011 at 3:28
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Your code returns 1/2 if the (f 0) is evaluated first, not 0. A better way would be to return the last argument to f, with a default of 0.

(define last 0)
(define (f x)
 (define temporary last)
 (set! last x)
 temporary
)

When (+ (f 0) (f 1)) is evaluated with (f 0) first, execution is as follows:

  1. f is called with 0
  2. temporary is set to 0 (the default last)
  3. last is set to 0 (the argument to f)
  4. temporary (0) is returned
  5. f is called with 1
  6. temporary is set to 0
  7. last is set to 1
  8. temporary (0) is returned
  9. 0+0=0

If (f 1) is evaluated first, then execution is as follows:

  1. f is called with 1
  2. temporary is set to 0 (the default last)
  3. last is set to 1 (the argument to f)
  4. temporary (0) is returned
  5. f is called with 0
  6. temporary is set to 1
  7. last is set to 0
  8. temporary (1) is returned
  9. 0+1=1
answered May 19, 2011 at 20:30
\$\endgroup\$
2
  • \$\begingroup\$ I agree - returning the last argument is cleaner than my solution. I don't think that my answer returned 0.5 though - it computes 0/2 (which is 0) and then returns that twice - so it should still be correct? Anyway, I like your solution better. Thanks! \$\endgroup\$ Commented May 20, 2011 at 0:07
  • \$\begingroup\$ @jaresty You're right, it would return 0. I thought 0 was considered false, but was wrong. \$\endgroup\$ Commented May 20, 2011 at 0:12

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.