2015-09-08 4 views
5

La funzione anonima nidificata è legale o no? Ho scritto quanto segue per il problem #107 di 4clojure:Funzioni anonime nidificate in Clojure

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

che passava tutte le 3 prove, tuttavia quando provo con il test 3 in REPL ottengo un IllegalStateException dicendo che nidificato #() s non sono consentiti:

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) 

Perché questo non può essere passato sul repl ma su 4clojure?

risposta

10

Le funzioni anonime nidificate sono perfettamente OK. Ma non è possibile nidificare la macro del lettore #(), perché non è ben definito - non possiamo sapere se per %1 il programmatore intendeva il primo argomento per la funzione esterna letterale o il primo argomento per la funzione interna letterale.

È necessario digitare la funzione interna "longhand" (utilizzando fn) se si desidera valutare l'intero modulo di test.

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

E lavorando 4Clojure deve probabilmente perché essi valutare la forma che fornisci prima di inserirlo nelle forme di prova. Come tale, la macro #() è già stata espansa (su un) quando viene valutato il modulo di test.

+1

mi stavo chiedendo, perché la mia versione con la macro '#()' reader ha anche superato il test su 4clojure, ma non nel mio repl. Grazie comunque per la tua spiegazione – amirteymuri

+0

Ah, ho frainteso la tua domanda un po 'allora. In questo caso il #() deve essere già stato espanso in macro quando è inserito nei moduli di test – Magos

+0

DOC; nel caso qualcuno lo cercasse: Ctrl-F per: '#() i form non possono essere nidificati in [clj-doc] (http://clojure.org/reader) – birdspider