Search code examples
schemeguile

How to parse a function into another function in scheme


I am trying to create a function that takes another function as a parameter and calls the functions in a loop.

The code below should get the function and the number of times the loop should execute:

(define (forLoop loopBody reps)
    (let
        (
         (fun (car loopBody))
         (str (cdr loopBody))
        )
       (cond
          ((eval (= reps 0) (interaction-environment)) "")
          (else (cons str (forLoop '(fun str) (- reps 1))))
       )
    )
)

The code below is how i am calling the function

(define (printermsg)
  (display msg)
 )
(forLoop '(printer "text ") 4)

The expected output for the above code:

text text text text 

Solution

  • There are several issues with your code:

    • The way you pass the loopBody parameter to your function is incorrect, a list of symbols will not work: you want to pass along a list with the actual function and its argument.
    • You are not obtaining the second element in the list, cdr won't work because it returns the rest of the list, you need to use cadr instead.
    • Avoid using eval, it's not necessary at all for what you want, and in general is a bad idea.
    • Why are you building a list? cons is not required here.
    • When calling the recursion, you are again passing a list of symbols instead of the proper argument.
    • You're not actually calling the function!

    This should work:

    (define (forLoop loopBody reps)
      (let ((fun (car  loopBody))
            (str (cadr loopBody)))
        (cond
          ((= reps 0) (void)) ; don't do anything when the loop is done
          (else
           (fun str) ; actually call the function!
           (forLoop loopBody (- reps 1))))))
    
    (define (printer msg)
      (display msg))
    
    (forLoop (list printer "text ") 4) ; see how to build the loop body
    => text text text text