I tried to evaluate a Clojure expression with nested shorthand functions today, and it wouldn’t let me.
The expression was:
(#(+ % (#(+ % (* % %)) %)) 5) ; sorry for the eye bleed
The output was:
IllegalStateException Nested #()s are not allowed clojure.lang.LispReader$FnReader.invoke (LispReader.java:630)
...and a bunch of other garbage
3
You would know that % belongs to the inner function. The drawback is that you would lose access to the % in the outer function.
Use the fn [x]
syntax instead.
1
It’s completely arbitrary; there’s a couple lines in the parser that explicitly disable it. If you edit that line out, you can have nested anonymous functions, and they act exactly like you’d expect.
specifically, lines 634-635 in https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java
public static class FnReader extends AFn{
public Object invoke(Object reader, Object lparen) {
PushbackReader r = (PushbackReader) reader;
if(ARG_ENV.deref() != null) // <-- line 634
throw new IllegalStateException("Nested #()s are not allowed");
// ...
7
You can have nested anonymous functions of the (fn [params] (body)) sort. Only the # syntax doesn’t support nesting.