2016-04-06 34 views
3

, ben takip eden hatayı alıyorum:Clojure core.logic dosyasında, neden iş parçacıklı makroları kullanamıyorum? Aşağıdaki kodu çalıştırdığınızda

(run 3 [q] 
    (fresh [a0 a1 a2 
      b0 b1 b2 
      c0 c1 c2] 
    (== q [[a0 a1 a2] [b0 b1 b2] [c0 c1 c2]]) 
    (fd/in a0 a1 a2 b0 b1 b2 c0 c1 c2 (fd/interval 1 9)) 
    (fd/distinct [a0 a1 a2 b0 b1 b2 c0 c1 c2]) 
    (fd/eq 
    (= a0 4) 
    (= 22 (- (* a0 a1) a2)) 
    (= -1 (-> b0 (* b1) (- b2))) 
    ))) 

hatası:

2. Unhandled clojure.lang.Compiler$CompilerException 
    Error compiling src/euler/core.clj at (1392:5) 

1. Caused by java.lang.IllegalArgumentException 
    Can't call nil 
core.clj: 3081 clojure.core/eval 
        main.clj: 240 clojure.main/repl/read-eval-print/fn 
        main.clj: 240 clojure.main/repl/read-eval-print 
        main.clj: 258 clojure.main/repl/fn 
        main.clj: 258 clojure.main/repl 
       RestFn.java: 1523 clojure.lang.RestFn/invoke 
    interruptible_eval.clj: 87 clojure.tools.nrepl.middleware.interruptible-eval/evaluate/fn 
        AFn.java: 152 clojure.lang.AFn/applyToHelper 
        AFn.java: 144 clojure.lang.AFn/applyTo 
        core.clj: 630 clojure.core/apply 
        core.clj: 1868 clojure.core/with-bindings* 
       RestFn.java: 425 clojure.lang.RestFn/invoke 
... 

elma suyu içinde diş makro -> ile çizgi, ben makro genişletmek edeceğiz Bildirim ve her şey iyi görünüyor, ama sonunda kod çöker. Bunun makroların hatası olduğunu farz ediyorum ama neden emin değilim. Herhangi bir fikir?

cevap

3

the source of clojure.core.logic.fd'a bakmalısınız. Hata, makro formda oluşmadan önce tüm formlarını işleyen eq makrosunda gerçekleşir.

Hızlı bir çözüm için, herhangi bir şey yapmadan önce tüm formlarını macroexpand-all olarak adlandırılan eq sürümünü oluşturdum. Diğer bağlamlarda test etmemesine rağmen, kodunuz için çalışıyor gibi görünüyor:

(defmacro mac-eq [& forms] 
    (let [exp-forms (map clojure.walk/macroexpand-all forms)] 
    `(fd/eq [email protected]))) 

Haydi deneyelim!

stack-prj.logicThreadMacro> (run 3 [q] 
           (fresh [a0 a1 a2 
             b0 b1 b2 
             c0 c1 c2] 
           (== q [[a0 a1 a2] [b0 b1 b2] [c0 c1 c2]]) 
           (fd/in a0 a1 a2 b0 b1 b2 c0 c1 c2 (fd/interval 1 9)) 
           (fd/distinct [a0 a1 a2 b0 b1 b2 c0 c1 c2]) 
           (mac-eq 
           (= a0 4) 
           (= 22 (- (* a0 a1) a2)) 
           (= -1 (-> b0 (* b1) (- b2)))))) 
()