Granted, it's not a ideologue "turtles all the way down" LISP. But it isn't intended to be. If you want that, I advise you to find an old Lisp Machine and use that.
(let [x (f (first s))]
(if (nil? x)
(keep f (rest s))
(cons x (keep f (rest s)))))
The rest of it appears to be performance optimizations, that probably make sense for a key function in the core library likely to be commonly invoked.Classic version has a self-evident clarity and familiar shape of a recursive function, which utilizes TCO.
Perfection is achieved when there is nothing more to cut off, not when there is nothing more to pile up.)
After refactoring it, the tail-recursive version would be a bit harder to read than the naive implementation. In a sense the Clojure code is in the same boat, it's just that the optimizations are more complicated, because it's not working with singly linked lists in the "address register" and "decrement register".
A definition of a similar keep fn in clojure would be almost indistinguishable from your lisp example (it would just be more readable).
(Even Guy Steele, who should know, recommended a couple years ago that language designers omit cons from their langauges!)