2015-09-08 23 views
5

ネストされた匿名関数は有効ですか?私はREPLでテスト3でそれをしようとすると、すべての3つの試験に合格したClojureのネストされた匿名関数

(fn [n] #(reduce * (repeat n %))) 

、しかし、私は、ネストされた#()sが許可されていないことを言ってIllegalStateExceptionが取得:私は4clojureのproblem #107ために次のことを書きました:このカントは、REPLではなく4clojureに渡されるのはなぜ

IllegalStateException Nested #()s are not allowed 
clojure.lang.LispReader$FnReader.invoke (LispReader.java:628) 

CompilerException java.lang.RuntimeException: Unable to resolve symbol: n 
in this context, compiling:(NO_SOURCE_PATH:1:44) 

RuntimeException Unmatched delimiter:) 

clojure.lang.Util.runtimeException (Util.java:221) 

RuntimeException Unmatched delimiter:) 

clojure.lang.Util.runtimeException (Util.java:221) 

CompilerException java.lang.RuntimeException: Unable to resolve symbol: % 
in this context, compiling:(NO_SOURCE_PATH:0:0) 

RuntimeException Unmatched delimiter:) 

clojure.lang.Util.runtimeException (Util.java:221) 

RuntimeException Unmatched delimiter:) 

clojure.lang.Util.runtimeException (Util.java:221) 

RuntimeException Unmatched delimiter:) 

clojure.lang.Util.runtimeException (Util.java:221) 

RuntimeException Unmatched delimiter:) 

clojure.lang.Util.runtimeException (Util.java:221) 

答えて

10

ネストされた匿名機能は完全に問題ありません。しかし、#()リーダマクロをネストすることはできません。なぜなら、あまり定義されていないからです。%1によって、プログラマが外部関数リテラルの最初の引数または内部関数リテラルの最初の引数を意味するかどうかはわかりません。

テストフォーム全体を評価する場合は、「longhand」(fn)を使用して内部関数を入力する必要があります。彼らはあなたがテストフォームに挿入する前に提供フォームを評価するので、それが4Clojureに取り組ん

(fn [n] 
    (fn [m] 
    (reduce * (repeat n m)))) 

はそうでなければなりません。そのため、テストフォームが評価されると、#()マクロは既に展開されています(fn*)。

+1

私のバージョンが '#()'読者マクロを持つ私のバージョンも4clojureのテストに合格していますが、私のreplではテストに合格していないので、私は疑問に思っていました。とにかくあなたの説明のためにありがとう – amirteymuri

+0

ああ、私は少しあなたの質問を誤解しました。その場合、#()はテストフォームに挿入されたときに既にマクロ展開されている必要があります。 – Magos

+0

DOC;あなたが提供するフォームを評価するため、 'clj-doc](http://clojure.org/reader) – birdspider

関連する問題