11

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
  • 2
    i find that not being able to write such code is a good thing for clojure. – Simon Bergot Jan 25 '13 at 11:20
  • 3
    Because it makes your eyes bleed. – Michael Shaw Jan 25 '13 at 13:16
  • Don't you need (#(+ %1 (#(+ %2 (* %3 %4)) %5)) 5)? – innova Jun 9 '15 at 14:06
5

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
    So? Most of the time I don't need access to the % of the outer fn, and on the times you did, you could fall-back to (fn), right? – Zaz May 12 '15 at 23:56
10

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");
        // ...
  • Could you identify the line in the parser and demonstrate that the code rewritten to not have an anon nested function and the code with the line removed from the parser and an anon nested function works the same? – user40980 Jan 24 '13 at 22:09
  • 2
    @MichaelT: there you go . and you can just test it; it's easy to do since you can switch them out at runtime . the clojure parser is really quite easily hackable – amara Jan 25 '13 at 1:17
  • 4
    Well, not completely arbitrary; unless Rick Hickey was just having an arbitrary day, there must have been a reason he put it in there, and you don't seem to know what that reason is. Duh. – Robert Harvey Jan 25 '13 at 19:40
  • Wow, what a find! Nice -- +1. – user39685 Jan 25 '13 at 20:05
  • Would this change cause any ambiguous parsings of nested methods? I am curious of a fn [x] rewrite of the OP's code would have identical functionality to a modified clojure version. Furthermore, would there be any issue with portability of the clojure code? – user40980 Jan 25 '13 at 20:52
3

You can have nested anonymous functions of the (fn [params] (body)) sort. Only the # syntax doesn't support nesting.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.