Search code examples
clojure

Clojure - Unknown number of arguments in a function


I have a function

(defn x [w]
  (let [[w1 w2 w3] w]
    (println w1)
    (println w2)
    (println w3))) 

If I call the function

(x [[1 1] [2 2] [3 3]])
=> [1 1]
   [2 2]
   [3 3]

which is what I expect

Is there a way to generalise this? In this case I knew that w was a vector containing 3 vectors so I know to have [w1 w2 w3] If w was then a vector of 4 vectors, the last vector would not be set to anything

What I want is where w is a vector of n vectors and then in the let of the function set them to [w1 w2 w3 ... wn]? (note doesn't necessarily have to be w1, w2, ... wn)

The println are just there for debugging so not that important for the function

Any help would be much appreciated.


Solution

  • (defn x [ws]
      (dorun (map println ws)))
    

    For example,

    (x [[1 1] [2 2] [3 3]])
    [1 1]
    [2 2]
    [3 3]
    => nil
    
    • The map applies println to each of the ws in turn, returning the nil results as a sequence, on demand (lazily).
    • The dorun demands the whole sequence, discarding it as it goes, returning nil.

    If you want to see the sequence, replace dorun with doall:

    (defn x [ws]
      (doall (map println ws)))
    
    => (x [[1 1] [2 2] [3 3]])
    [1 1]
    [2 2]
    [3 3]
    => (nil nil nil)
    

    A more concise alternative to the former is

    (defn x [ws]
      (doseq [w ws] (println w)))
    

    ... and to the latter is

    (defn x [ws]
      (for [w ws] (println w)))