147pm
147pm

Reputation: 2239

Scheme variadic function to add numbers

I've got this code

(define mysum
    (lambda (l)
        (if (null? l)
            0
            (+ (car l) (mysum (cdr l))))))

which works:

(mysum '(1 2 3))

gives 6, but this

(define (my+func . numbers)
  (lambda (num)
    (if (null? num)
        0
        (+ (car num) (my+func (cdr num))))) numbers)

isn't working. I'm getting lost trying to do recursion inside the lambda, no doubt. Any ideas what I could do?

Upvotes: 1

Views: 276

Answers (1)

Sylwester
Sylwester

Reputation: 48745

So there are two ways to make a procedure. You have this:

(define name (lambda (arg ...) body ...))

And there is the equal syntactic sugar:

(define (name arg ...) body ...))

If you want to you can do the reverse process with your last procedure:

(define my+func 
  (lambda numbers
    (lambda (num) 
      (if (null? num)
          0
          (+ (car num) (my+func (cdr num)))))
    numbers))

When you do (my+func 1 2 3) it creates a procedure that takes one argument. Since the procedure is not the last expression it's discarded and thrown away and the last expression is numbers. Thus you'll get (1 2 3) as the result.

This would work:

(define my+func 
  (lambda numbers
    (if (null? numbers)
        0
        (+ (car numbers) (apply my+func (cdr numbers))))))

Which can be translated back to the sugared define:

(define (my+func . numbers) 
  (if (null? numbers)
      0
      (+ (car numbers) (apply my+func (cdr numbers)))))

Notice the apply. It's because you cannot send (my+func '(2 3)) as the recursion but it needs to be (my+func 2 3) and that is what apply does. Alternatively you can make a helper that uses lists instead:

(define (my+func . numbers) 
  (define (helper ns)
    (if (null? ns)
        0
        (+ (car ns) (helper (cdr ns)))))
  (helper numbers))

Usually one would choose the same name for the numbers in the helper, but I remember that I was confused the the shadowing variables that were not the same.

Upvotes: 3

Related Questions