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)は必要ありませんか?
innova

回答:


5

%は内部関数に属していることがわかります。欠点は、外部関数の%にアクセスできなくなることです。

fn [x]代わりに構文を使用してください。


1
そう?ほとんどの場合、私は%外側のfnにアクセスする必要はありません(fn)
ザズ

10

それは完全に任意です。パーサーには、明示的に無効にするいくつかの行があります。その行を編集すると、入れ子になった匿名関数を使用でき、期待どおりに機能します。

具体的には、https: //github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.javaの634〜635行目

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のパーサは実際にはかなり簡単にハッキングされる
アマラ

4
まあ、完全に arbitrary 意的ではありません。Rick Hickeyがarbitrary意的な一日を過ごしていたのでなければ、彼がそこに入れた理由があったに違いありません。ああ。
ロバートハーベイ

わあ、なんてことだ!いいね-+1。

この変更により、ネストされたメソッドのあいまいな解析が発生しますか?私は好奇心のfn [x]修正Clojureのバージョンと同じ機能を持っているでしょうOPのコードの書き直し。さらに、clojureコードの移植性に問題はありますか?

3

(fn [params](body))ソートのネストされた匿名関数を使用できます。#構文のみがネストをサポートしていません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.