In Clojure, when and why does one want to use a named anonymous function? E.g.,
((fn add-five [x] (+ x 5)) 3))
In ClojureDocs, one example's comment says that it is useful in stack traces. Can one give an example of that?
In Clojure, when and why does one want to use a named anonymous function? E.g.,
((fn add-five [x] (+ x 5)) 3))
In ClojureDocs, one example's comment says that it is useful in stack traces. Can one give an example of that?
There are two reasons to name anonymous functions (or at least two reasons that I've done so). The first is that giving it a name tells a later reader (perhaps yourself 6 months down the line) what the heck that anonymous function is supposed to do.
The second is (as you mention) to have better information in a stack trace to point you at the right location in your code when a failure occurs. Functions are compiled into classes and the class name includes a (munged) version of the function name. When you have a stack trace, it will include that class name and thus point you semantically towards the proper location.
user=> (filter (fn [x] (/ 100 x)) [100 50 0])
ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:158)
user=> (pst *e)
ArithmeticException Divide by zero
clojure.lang.Numbers.divide (Numbers.java:158)
clojure.lang.Numbers.divide (Numbers.java:3784)
user/eval8/fn--9 (NO_SOURCE_FILE:3)
clojure.core/filter/fn--6908 (core.clj:2790)
...
nil
user=> (filter (fn hundred-div [x] (/ 100 x)) [100 50 0])
ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:158)
user=> (pst *e)
ArithmeticException Divide by zero
clojure.lang.Numbers.divide (Numbers.java:158)
clojure.lang.Numbers.divide (Numbers.java:3784)
user/eval14/hundred-div--15 (NO_SOURCE_FILE:5) ;; <---
clojure.core/filter/fn--6908 (core.clj:2790)
...
Apart from being useful in stacktraces, I suppose you could use it when you need an anonymous function to be recursive, as it would be able to call itself.
For instance:
(fn factorial[n]
(if (<= n 1)
1
(* n (factorial (- n 1)))))
Although recursing like this in Clojure is a bit dangerous, as it could potentially cause stack overflows.
Named anonymous functions can be useful when they refer to themselves, and also by being printed with their name:
user=> ((fn [] (throw (Exception. "unnamed"))))
Exception unnamed user/eval805/fn--806 (NO_SOURCE_FILE:1)
user=> ((fn myfn [] (throw (Exception. "named"))))
Exception named user/eval809/myfn--810 (NO_SOURCE_FILE:1)