Generate all permutations in Clojure
Let's clean the code up a bit.  

Function tails gives us all the possible ending sub-sequences. For example ...

(tails (range 3)) ; ((0 1 2) (1 2) (2) ())


And inits gives us all the initial sub-sequences. For example ...

(inits (range 3)) ; (() (0) (0 1) (0 1 2))


To get the rotations, we marry the init with the corresponding tail,using concat. If we just 

(defn rotations [a-seq]
  (map concat (tails a-seq) (inits a-seq)))


`
... then we get the original sequence at both ends:

(rotations (range 5)) ; ((0 1 2 3 4) (1 2 3 4 0) (2 3 4 0 1) (3 4 0 1 2) (4 0 1 2 3) (0 1 2 3 4))


The given code uses distinct to get rid of the duplicate. It's faster and simpler to use rest:

(defn rotations [a-seq]
  (rest (map concat (tails a-seq) (inits a-seq))))


Now

(rotations (range 5)) ; ((1 2 3 4 0) (2 3 4 0 1) (3 4 0 1 2) (4 0 1 2 3) (0 1 2 3 4))


And we're ready to generate all the permutations. We can rewrite the given code as follows:

(defn permutations [a-set]
  (if (empty? a-set)
    (list ())
    (mapcat
     (fn [[x &amp; xs]] (map #(cons x %) (permutations xs)))
     (rotations a-set))))



(mapcat f coll)is an abbreviation for (apply concat (map f coll)).
(fn [[x &amp; xs]] ... ) is a destructuring form that sets x to the
first and xs to the rest of its sequence argument.
#(cons x %) is an abbreviation for (fn [y] (cons x y)), a
function that puts x on the front of its sequence argument.


For every rotation of the given set, the permutations function glues its first element onto each permutation of the rest of the elements, and then concatenates all these collections together. For example ... 

(permutations (range 3))
; ((1 0 2) (1 2 0) (2 1 0) (2 0 1) (0 2 1) (0 1 2))


That's it. 



The given inits ...

(defn inits [a-seq]
  (reverse (map reverse (tails (reverse a-seq)))))


... is somewhat overworked, on account of all the reverses. A neater way to get the rotations is 

(defn rotations [a-seq]
  (let [a-vec (vec a-seq)]
    (for [i (range (count a-vec))]
      (concat (subvec a-vec i) (subvec a-vec 0 i)))))