Schytheron
Schytheron

Reputation: 735

Scheme - How do I loop an anonymous function?

I have been trying to convert a normal function into a higher order function that does the same thing. The function is supposed to take a operator as a argument and then apply that operator to each and every element in a list. For example if I choose the operator "+" it would return the sum of all the elements in a list.

Normal version of function:

(define (accumulate proc id lst)
  (cond ((null? lst) id)
    ((eqv? (cdr lst) '()) (car lst))
    (else (proc (car lst) (accumulate proc id (cdr lst))))))

Higher order version of function (incomplete):

(define (acc-proc proc id)
(lambda (lst)
(cond ((null? lst) id)
      ((null? (cdr lst)) (car lst))
      (else 

In the normal function I am using a recursive call to loop it but I can't loop the higher order function because it doesn't have lst as an argument. Instead the argument lst is in the anonymous lambda procedure.

I am new to Scheme so forgive me if my solutions are bad. Maybe there is a better way to do this without looping? I have no idea what to put into that else statement...

Upvotes: 1

Views: 173

Answers (1)

molbdnilo
molbdnilo

Reputation: 66371

Note that there's a bug in your original function: your second case means that you're ignoring id for everything except the empty list:

> (accumulate + 34 '(1 2 3))
6
> (accumulate + 34 '())
34

You only need two cases; empty and non-empty lists.

For the actual problem: if the "anonymous" part isn't essential, you can use a local named function:

(define (acc-proc proc id)
  (define (recurse lst)
    (if (null? lst)
        id
        (proc (car lst) (recurse (cdr lst)))))
  recurse)

If anonymousity is important, you need to take the lambda calculus route and use a fixpoint combinator.

Upvotes: 1

Related Questions