Sometimes using arity overloading like you've done is the best way to write a function.
I tried to rewrite your function using destructuring, like this:
(defn rev [[x & more]]
however, it doesn't really work because you need some way of storing your "result sequence" in progress, which in your function is
l. Because we're trying to write a reverse function, it's hard to do what we want without having some way of "building up" the sequence as we go and storing it in an intermediate value.
Taking a look at how reverse is actually implemented in Clojure, we can see that a more concise way to express this idea of iterating over a sequence and building up a result sequence is by using
reduce with a starting value of
(defn reverse [coll]
(reduce conj '() coll))
The magic behind this is that we're starting with a seq,
'(). When you
conj something onto a seq, it adds it to the beginning, not the end. So what this does is it starts with an empty seq, then goes through the input list items one by one and adds them to the beginning of the result list, so that you end up with a list that's reversed.
EDIT: Leonid has a more thorough answer here.