Search code examples
schemelispracketr5rsmutability

How To Mutate Variables Scheme


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


Solution

  • 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