Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by

This is the output of a regular for function:

(for [x ['a 'b 'c] 
      y [1 2 3]]
  [x y]) 
  ;;=> ([a 1] [a 2] [a 3] [b 1] [b 2] [b 3] [c 1] [c 2] [c 3])

How would you turn this into a variadic function that takes any number of args?


    (defn variadic-for
        [& args]
        (for [... ] [...]))
(variadic-for [['a 'b 'c] [1 2 3]])
;;=> ([a 1] [a 2] [a 3] [b 1] [b 2] [b 3] [c 1] [c 2] [c 3])

1 Answer

+2 votes
selected by
Best answer

I don't think that for is the construct you are looking for if you have an unknown number of collections.

If we look at the definition of for we can see that it is a macro that creates bindings from elements of the each collection to their own symbol. In your first example, x and y are bound to values of their respective collections. The only way to generate a call to for that has dynamic number of collections (and therefore bindings) would be define a new macro that checks the size of args, generates 1 symbol per element of args, and then assembles a call to for with all the bindings. It is doable, but I suspect we can find a simpler solution.

If your goal is to collect every possible way to take one item from each collection this can be accomplished with the cartesian-product function from math.combinatorics found here .

Amazing. Thank you