Being drawn to and new to clojure and its macros I set myself the task of writing a macro that generates all strings of length 'n' from a list of chars such as "abc". So for n=2 the output should be "aa" "ab" "ac" "ba" "bb" "bc" "ca" "cb" "cc". I started with the following function as a template: (defn mkstr [n v] (for [i v j v] (str i j))). The repetition of 'v' in the for binding and the creation of how many vars should be a function of 'n'; in this specific case: 2.
After reading about 'quote' 'unquote' etc., then following an excellent online tutorial about macros, much trial and error, and some plain luck I managed to produce the following function and macro, which give the desired output whatever the value of 'n'. The really hard part was generating the variable amount of code needed in the 'for' bindings.
(defn mkvars [n]
"Gives a list of 'n' unique symbols"
(let [vc (repeatedly n #(gensym ))] vc))
(defmacro mkcoms [n syms]
"Generates a list of possible combinations of length 'n' from a string of symbols"
`(let [vs# (mkvars ~n) sy# ~syms
forarg# (vec (interleave vs# (repeat ~n sy#)))]
`(for ~forarg# (str ~@vs#))))
Now my 'real' problem or lack of understanding is that to obtain the output I must do this: (eval (mkcoms len chars)). Why does this only work by using 'eval'? True, it is usable as is, but something feels wrong about it.