My little story of "What do beginners struggle with?"

I’ll start off by noting that the shorthand function syntax is implemented as a “reader macro”. Once parsed, it will generate the fully expanded form. e.g. for:
#(str "Hello" %1 %2)
After parsing the compiler will be given something similar to:
(fn [p1__444# p2__445#] (str "Hello" p1__444# p2__445#))

In other words, there’s no technical difference. It’s entirely up to whether the programmer thinks it makes things easier.

In general, I think it’s great to name function arguments, though I do think there are a few occasions where it’s useful:

  • Fixing arguments in a function. For instance, if all my queries will be against a database, then a shortcut doesn’t seem to add much cognitive load:
    (let [my-q #(q % the-database)] (my-q the-query))
    I can see the argument against this though.
  • Using a simple Java interop function where a function reference is required:
    (map #(Long/parseLong %) ["1" "2" "3"])
  • It creates faster code than using partial:
    (map (partial + 2) [2 3 5 7 11])
    is essentiall the same as:
    (map #(+ 2 %) [2 3 5 7 11])
    But faster (since partial allows multiple arguments)
    Again, there is an argument to use (fn [x] (+ 2 x)) but in this case the “x” is as arbitrary as “%”, and it’s taken more typing.

All of this is about using a simple % argument. I almost never use the numbered variety. About the only time I have is when I want to swap the order of the arguments:
(let [flip-f #(f %2 %1)] (flip-f :a :b))

But as I said at the start, if you don’t think it works for you, then don’t use it. Clojure doesn’t care :slight_smile:

3 Likes