In Scheme, you can write a variadic function as (lambda x ...)
, in which case x
gets bound to the entire list of arguments, or by using an improper lambda list, e.g., (lambda (a b c . ds) ...)
, which takes at least three arguments, and binds ds
to the list of the remaining arguments. The code you're trying to write, then, would be something like (I'm writing in R5RS Scheme):
(define (my-map function list1 . more-lists)
(define (some? function list)
;; returns #f if (function x) returns #t for
;; some x in the list
(and (pair? list)
(or (function (car list))
(some? function (cdr list)))))
(define (map1 function list)
;; non-variadic map. Returns a list whose elements are
;; the result of calling function with corresponding
;; elements of list
(if (null? list)
'()
(cons (function (car list))
(map1 function (cdr list)))))
;; Variadic map implementation terminates
;; when any of the argument lists is empty
(let ((lists (cons list1 more-lists)))
(if (some? null? lists)
'()
(cons (apply function (map1 car lists))
(apply my-map function (map1 cdr lists))))))
This works as expected:
(my-map + '(0 2 5) '(1 2 3))
;=> (1 4 8)
Notice that to make this work, we needed a non-variadic map
(here called map1
) in order to do (map1 car lists)
to get the argument list to call function
with, and (map1 cdr lists)
to get the rests of the lists to recurse with. To write a variadic map
(here called my-map
), you already need an implementation of the non-variadic map
.