I've found an ugly pipeline that solves the problem. I don't find it much elegant but I haven't been able to beautify it.
(->> [:a :b :c :d]
(iterate rest)
(take-while not-empty)
(mapcat (fn [[f & r]] (map #(vector f %) r)))
vec)
Let's analyze the function in the mapcat when given list [:a :b :c :d]. It computes all vectors with first element :a and second element succesive elements taken from [:b :c :d], that is([:a :b] [:a :c] [:a :d])`.
The first part of the pipeline, constructs the sequence of all the rests od the original vector ([:a :b :c :d](:b :c :d)(:c :d)(:d) () () () ...) which is stopped at the first empty rest.
Then the mapcat plugs this list in the combining function described before, and the vec at the end, converts the sequence into a vector.
This can be more readable by introducing some auxiliar functions:
(defn rests [coll]
(take-while not-empty (iterate rest coll)))
(defn pairfirst [[f & r]]
(map #(vector f %) r))
(defn pairs [coll]
(mapcat pairfirst (rests coll)))
(first)and calling some inner function over the rest with(rest )until(= 0 (count (rest )))(but I'm having a heck of time trying this in tryclj.com, maybe this can help some else who knows more than I do.v, I found that(nth v 999999)is as fast as(v 999999).(for [elem (range 1000)] elem)is faster than(let [r (range 1000)] (for [idx r] (nth r idx)))