0

I've been working on the examples from SICP, and I've run into some trouble writing the two versions of accumulate in example 1.32. So far, my code looks like this.

Recursive version:

#lang racket
(provide accumulate)

(define (accumulate f a next b comb null)
    (if(> a b)
        null
        (comb (f a)
            (accumulate f (next a) next b comb null))))

Iterative version:

#lang racket
(provide accumulate)

(define (accumulate f a next b comb null)
    (define (iter cur_a result)
        (if (> cur_a b)
            result
            (iter (next cur_a) (comb (f cur_a) result))))

    (iter a null))

While these two functions give the same result for simple comb terms like addition and multiplication, something like `(lambda (x y) (+ (* 3 x) (* 3 y))) will cause the two functions to give different results, due to the direction of application. The recursive version goes left from the right end of the range, while the iterative version goes right from the left end of the range.

I'm wondering if it's possible to change this direction for the functions, so that one could choose whether the code would run left or right. It seems to me that to do so, one would have to give a prev term instead of a next term so that the function could run the other way. Is there any other way to implement this without touching the function parameters?

harry0816
  • 23
  • 4

1 Answers1

0

Here is my solution from my private repository of sicp.

(define (term x) x)
(define (next i) (+ i 1))
;;; recursive process
(define (accumulate combiner null-value term a next b)
  (if (> a b)
      null-value
      (combiner (term a)
                (accumulate combiner null-value term (next a) next b))))

;;; iterative process
(define (accumulate-iter combiner null-value term a next b)
  (define (iter a res)
    (if (> a b)
        res
        (iter (next a) (combiner (term a) res))))
  (iter a null-value))

(define (product term a next b)
  (accumulate * 1 term a next b))

(define (product-iter term a next b)
  (accumulate-iter * 1 term a next b))

(define (factorial n)
  (product term 1 next n))

(define (factorial-iter n)
  (product-iter term 1 next n))

(factorial 10)

(factorial-iter 10)
alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • but the OP wants both `(accumulate (lambda (x y) (+ (* 3 x) (* 3 y))) null (lambda (x) x) a next b)` and `(accumulate-iter (lambda (x y) (+ (* 3 x) (* 3 y))) null (lambda (x) x) a next b)` to give the same results. – Will Ness Jan 04 '20 at 04:20
  • @WillNess indeed, but taking into account that he did not paste enough code and only summarily explained what he did, the effort would be much bigger to help him otherwise. Starting from my code he can find what he did wrong. – alinsoar Jan 05 '20 at 12:43