Search code examples
clojurevariadic-functionsdestructuring

Recursive variadic clojure function (unboxing/destructuring a list when calling a function)


Just trying to write a recursive variadic function that prints the elements of a list, one each call. First attempt:

(defn f1 [head & tail]

  (when-not (nil? head)
        (println head )
        (f1 tail) ;; how to unbox/destructure tail ????
  ) ;; when

) ;; defn

(f1 "one" "two" "three" "four")

But just get :-(

one 
(two three four)

Then, solved it in a very "un-elegant" way:

(defn f2Aux [all]
    (when-not (empty? all)
      (println (first all) )
      (f2Aux (rest all))
    )
) ; defn


(defn f2 [head & tail]
    (f2Aux (list* head tail))

) ;; defn

(f2 "one" "two" "three" "four")

Pretty sure there is a better way to go.

Thanks

Edit. Still looking for something different from:

(defn f3 

  ;; if we get a list
  ([all]
    (when-not (empty? all)
      (println (first all) )
      (f3 (rest all))
    ) ; when
  )

  ;; if we get several args
  ([head & tail]
    (f3 (list* head tail)) ;; pack the args and call us again
  )
) ;; defn

Solution

  • Because tail is destructured into a sequence, and your function is variadic, you need to apply tail to your function so that it receives one argument per item in tail:

    (defn f1 [head & tail]
      (println head)
      (when tail (apply f1 tail)))
    
    (f1 "one" "two" "three" "four")
    ;; one
    ;; two
    ;; three
    ;; four