Question

(define wadd (lambda (i L)
                (if (null? L) 0
                    (+ i (car L)))
                    (set! i (+ i (car L)))
                          (set! L (cdr L))))

(wadd 9 '(1 2 3))

This returns nothing. I expect it to do (3 + (2 + (9 + 1)), which should equate to 15. Am I using set! the wrong way? Can I not call set! within an if condition?

Was it helpful?

Solution

I infer from your code that you intended to somehow traverse the list, but there's nothing in the wadd procedure that iterates over the list - no recursive call, no looping instruction, nothing: just a misused conditional and a couple of set!s that only get executed once. I won't try to fix the procedure in the question, is beyond repair - I'd rather show you the correct way to solve the problem. You want something along these lines:

(define wadd
  (lambda (i L)
    (let loop ((L L)
               (acc i))
      (if (null? L)
          acc
          (loop (cdr L) (+ (car L) acc))))))

When executed, the previous procedure will evaluate this expression: (wadd 9 '(1 2 3)) like this: (+ 3 (+ 2 (+ 1 9))). Notice that, as pointed by @Maxwell, the above operation can be expressed more concisely using foldl:

(define wadd
  (lambda (i L)
    (foldl + i L)))

As a general rule, in Scheme you won't use assignments (the set! instruction) as frequently as you would in an imperative, C-like language - a functional-programming style is preferred, which relies heavily on recursion and operations that don't mutate state.

OTHER TIPS

I think that if you fix your indentation, your problems will become more obvious.

The function set! returns <#void> (or something of similar nothingness). Your lambda wadd does the following things:

  1. Check if L is null, and either evaluate to 0 or i + (car L), and then throw away the result.
  2. Modify i and evaluate to nothing
  3. Modify L and return nothing

If you put multiple statements in a lambda, they are wrapped in a begin statement explicitly:

(lambda () 1 2 3) => (lambda () (begin 1 2 3))

In a begin statement of multiple expressions in a sequence, the entire begin evaluates to the last statement's result:

(begin 1 2 3) => 3
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top