title: Common Lisp: Zip arbitrary number of lists
body: <p>Suppose you have a list of lists, e.g. <code>'(("abc" "def" "ghi") ("012" "345" "678") ("jkl" "mno" "pqr"))</code> or <code>'(("ab" "cd" "ef") ("01" "23" "45"))</code>.</p>
  
  <p>What would be the canonical way to zip the lists inside the given list?
  I.e. how would <code>func</code> be defined such that</p>
  
  <pre><code>(func '(("ab" "cd" "ef") ("01" "23" "45")) :sep "|" :combiner #'concat) 
    ;; =&gt; ("ab|01" "cd|23" "ef|45")
  
  (func '(("abc" "def" "ghi") ("012" "345" "678") ("jkl" "mno" "pqr")) ...)
    ;; =&gt; ("abc|012|jkl" "def|345|mno" "ghi|678|pqr")
  </code></pre>
  
  <p>where <code>concat := (lambda (args) ...)</code> is the function that combines the heads of the respective lists.</p>
  
  <p>Presumably, this type of operation is known as <em>rotation</em> or <em>zipMany</em> (according to the <a href="https://stackoverflow.com/q/17976823/9081035">answers</a> for related questions for different languages).</p>
  
  <p>I have something like this (double-<code>apply</code>)</p>
  
  <pre><code>(apply #'mapcar #'(lambda (&amp;rest args) (apply #'concatenate 'string args)) lst)
  </code></pre>
  
  <p>where <code>lst</code> is <code>'(("ab" "cd" "ef") ("01" "23" "45"))</code>
   for example. The <code>combiner</code> would be <code>concatenate</code>. Note that no separator is given in this example implementation.</p>
  
  <p>But this seems awfully convoluted.</p>
  
  <p>So, <strong>what would be a canonical implementation for this kind of operation</strong>?</p>