<< Previous exercise (3.82) | Index | Next exercise (4.2) >>

99% certain meteorgan's code should have the words "left" and "right" swapped in the let* in list-of-values2 (the right to left version). Only 99%, so I won't presume to edit it myself.

(define (list-of-values-lr exps env) (if (no-operands? exps) '() (let ((first (eval (first-operand exps) env))) (let ((rest (list-of-values-lr (rest-operands exps) env))) (cons first rest))))) (define (list-of-values-rl exps env) (if (no-operands? exps) '() (let ((rest (list-of-values-rl (rest-operands exps) env))) (let ((first (eval (first-operand exps) env))) (cons first rest)))))

;;; left-to-right (define (list-of-values-l2r exps env) (if (no-operands? exps) '() (let ((first-exp (eval (first-operand exps) env))) (cons first-exp (list-of-values-l2r (rest-operands exps) env))))) ;;; right-to-left (define (list-of-values-r2l exps env) (list-of-values-l2r (reverse exps) env))

; left-to-right (define (list-of-values exps env) (let ((first '()) (rest '())) (if (no-operands? exps) rest (begin (set! first (eval (first-operand exps) env)) (set! rest (list-of-values (rest-operands exps) env)) (cons first rest))))) ; right-to-left (define (list-of-values exps env) (let ((first '()) (rest '())) (if (no-operands? exps) rest (begin (set! rest (list-of-values (rest-operands exps) env)) (set! first (eval (first-operand exps) env)) (cons first rest)))))

I think it's wrong to use cons in right to left.

;; ex 4.1 ;; left to right (define (list-of-values-l2r exps env) (if (no-operands? exps) '() (let ((v (eval (first-operand exps) env))) (cons v (list-of-values-l2r (cdr exps) env))))) ;; right to left (define (list-of-values-r2l exps env) (reverse (list-of-values-l2r (reverse exps) env)))

Why? Only the order of *evaluation* matters. Once the expressions have been evaluated, it literally doesn't matter in what order `cons` evaluates its arguments because they have already been evaluated and thus evaluating from left-to-right and right-to-left are equivalent. Right?

meteorgan