2

I'm trying to sum a list using mutable objects for an assignment.letis used here to allow me to mutate x the total sum and counter. I'm not very well versed with scheme hence the use if statements for each number in the list lst:

(define lst (list 1 2 3 4 5))

(let mut ((counter 0))
 (let ((x (car lst)))

  (if (= counter 4)
      x)
  (if (= 0 counter)
    (+ x (cadr lst)))
  (if (= 1 counter)
      (display (caddr lst)) ;test
      (+ x (caddr lst)))
  (if (= 2 counter)
      (+ x (caddr lst)))  

  (set-car! lst (cdr lst))   
  (mut (+ counter 1))
  )
)

however when I run the code I get an error

+: contract violation
      expected: number?
      given: (mcons 2 (mcons 3 (mcons 4 (mcons 5 '()))))
      argument position: 1st
      other arguments...:

However when I check (caddr lst) it returns a 3 as expected. My issue is why, when run, does caddr produce (mcons 2 (mcons 3 (mcons 4 (mcons 5 '())))) when applied to an + but when not applied it returns 3

I am using R5RS edit: I have omitted some of the if statements for conciseness

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Artemis
  • 139
  • 12
  • Open your interpreter. Write `(define ls '(1 2 3 4))`. Examine `(car ls)` and `(cdr ls)`. Write `(set-car! ls (cdr ls))`. Examine `(car ls)` and `(cdr ls)` again. – molbdnilo Mar 11 '18 at 12:44
  • You've skipped over the fundamentals of Scheme and are trying to write a program in a different language. Start over from chapter 1. (`(if (= counter 4) x)` is *not* the same as `if x == 4: return x`.) – molbdnilo Mar 11 '18 at 12:46
  • @molbdnilo I was under the impression that `car` returns a number not a reference, is that not the case? – Artemis Mar 11 '18 at 14:32
  • There are no "references" in Scheme. [SICP](https://mitpress.mit.edu/sicp/full-text/book/book.html) is available for free online. – molbdnilo Mar 11 '18 at 16:08

1 Answers1

1

Okay so I figured it out using a whole different implementation @molbdnilo was correct that my understanding was flawed. here is my implementation if anyone else is struggling with this problem

(define (goMut)
  (define mVar 0)
  (define acc 0)

(define (accDo num)
    (set! acc (+ num acc)))

  (for-each (lambda (x) (set! mVar x) (accDo x))
            (list 1 2 3 4 5))
  acc
)

Using set! we can apply the value in the list to an external variable and mutate it as we iterate throughout the loop using the function accDo. Function template taken from SICP pg 107

Artemis
  • 139
  • 12
  • 1
    the `if`s in your original code just had to be *nested*, [like so](http://lpaste.net/5655897051754397696). of course a chain of nested `if`s like that is better coded with a `cond`. here you're using the ready-made `for-each` , but originally you did the iteration yourself. (better to learn that way?) – Will Ness Mar 11 '18 at 22:52