Search code examples
functionschemevariadic-functionsvariadic

How do I handle an unspecified number of parameters in Scheme?


For example ((fn-stringappend string-append) "a" "b" "c") I know how to handle this (f x y z). But what if there's an unknown number of parameters? Is there any way to handle this kind of problem?


Solution

  • In Scheme you can use the dot notation for declaring a procedure that receives a variable number of arguments (also known as varargs or variadic function):

    (define (procedure . args)
      ...)
    

    Inside procedure, args will be a list with the zero or more arguments passed; call it like this:

    (procedure "a" "b" "c")
    

    As pointed out by @Arafinwe, here's the equivalent notation for an anonymous procedure:

    (lambda args ...)
    

    Call it like this:

    ((lambda args ...) "a" "b" "c")
    

    Remember that if you need to pass the parameters in a list of unknown size to a variadic function you can write it like this:

    (apply procedure '("a" "b" "c"))
    (apply (lambda args ...) '("a" "b" "c"))
    

    UPDATE:

    Regarding the code in the comments, this won't work as you intend:

    (define (fp f)
      (lambda (.z)
        (f .z)))
    

    I believe you meant this:

    (define (fp f)
      (lambda z
        (apply f z)))
    

    With a bit of syntactic sugar the above procedure can be further simplified to this:

    (define ((fp f) . z)
      (apply f z))
    

    But that's just a long way for simply writing:

    (apply f z)
    

    Is this what you need?

    (apply string-append '("a" "b" "c"))
    

    Because anyway that's equivalent to the following:

    (string-append "a" "b" "c")
    

    string-append already receives zero or more arguments (at least, that's the case in Racket)