Reputation: 3806
When I run the following code, I get the ensuing error:
(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)))
)))
error:
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
...
Notice the line with the threading macro ->
, in CIDER I'll macro expand it and everything looks fine, but in the end the code crashes. I'm assuming this is the fault of macros, but I'm not sure why. Any ideas?
Upvotes: 3
Views: 128
Reputation: 1447
You should look at the source of clojure.core.logic.fd. The error occurs in the macro eq
, which process all of its forms before macroexpansion can occur.
For a quick solution, I've created a version of eq
which calls macroexpand-all
on all of its forms before doing anything else. It seems to work for your code, although I have not tested it in other contexts:
(defmacro mac-eq [& forms]
(let [exp-forms (map clojure.walk/macroexpand-all forms)]
`(fd/eq ~@exp-forms)))
Let's try it!
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))))))
()
Upvotes: 3