Почему мы не можем написать вложенные сокращенные функции в Clojure?

11

Сегодня я попытался оценить выражение Clojure с помощью вложенных сокращенных функций, и оно мне не дало.

Выражение было:

(#(+ % (#(+ % (* % %)) %)) 5) ; sorry for the eye bleed

Выход был:

IllegalStateException Nested #()s are not allowed  clojure.lang.LispReader$FnReader.invoke (LispReader.java:630)
...and a bunch of other garbage
Линкольн Берджесон
источник
2
я считаю, что неспособность написать такой код - хорошая вещь для clojure.
Саймон Бергот,
3
Потому что это заставляет твои глаза кровоточить.
Майкл Шоу
Вам не нужно (# (+% 1 (# (+% 2 (*% 3% 4))% 5)) 5)?
Иннова

Ответы:

5

Вы бы знали, что% принадлежит внутренней функции. Недостатком является то, что вы потеряете доступ к% во внешней функции.

fn [x]Вместо этого используйте синтаксис.

Роберт Харви
источник
1
Так? В большинстве случаев мне не нужен доступ к %внешнему интерфейсу, и в те времена, когда вы это делали, вы могли отступить (fn), верно?
Заз
10

Это совершенно произвольно; в парсере есть пара строк, которые явно отключают его. Если вы отредактируете эту строку, вы можете иметь вложенные анонимные функции, и они будут действовать точно так, как вы ожидаете.

в частности, строки 634-635 в 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");
        // ...
амара
источник
Не могли бы вы идентифицировать строку в синтаксическом анализаторе и продемонстрировать, что код, переписанный так, чтобы не иметь анонированной функции, и код со строкой, удаленной из синтаксического анализатора и анонированной вложенной функции, работают одинаково?
2
@MichaelT: поехали. и вы можете просто проверить это; это легко сделать, так как вы можете переключать их во время выполнения. парсер clojure действительно легко взломать
amara
4
Ну, не совсем произвольно; если только у Рика Хики не было произвольного дня, у него, должно быть, была причина, и он, кажется, не знает, что это за причина. Duh.
Роберт Харви
Ух, какая находка! Ницца - +1.
Вызовет ли это изменение двусмысленный анализ вложенных методов? Мне любопытно, что fn [x]переписывание кода OP будет иметь такую ​​же функциональность, что и модифицированная версия clojure. Кроме того, возникнет ли проблема с переносимостью кода clojure?
3

Вы можете иметь вложенные анонимные функции вида (fn [params] (body)). Только синтаксис # не поддерживает вложенность.

WolfeFan
источник