看起来可以使用宏来为defn生成属性映射,但是似乎defn规范要求使用字面量映射。下面是一个示例,它会导致规范失败。
(defmacro example [f output input]
`{:test (fn [] (is (= (~f ~input) ~output)))})
(defn tails
(example tails
[1 2 3 4]
'([1 2 3 4] (2 3 4) (3 4) (4)))
[coll]
(take-while some? (iterate next coll)))
->
Call to clojure.core/defn did not conform to spec.
#:clojure.spec.alpha{:problems
({:path [:fn-tail :arity-1 :params],
:pred clojure.core/vector?,
:val
(example
tails
[1 2 3 4]
'([1 2 3 4] (2 3 4) (3 4) (4))),
:via
[:clojure.core.specs.alpha/defn-args
:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/param-list],
:in [1]}
{:path [:fn-tail :arity-n :bodies :params],
:pred clojure.core/vector?,
:val example,
:via
[:clojure.core.specs.alpha/defn-args
:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/params+body
:clojure.core.specs.alpha/param-list
:clojure.core.specs.alpha/param-list],
:in [1 0]}),
:spec
#object[clojure.spec.alpha$regex_spec_impl$reify__2510 0x643aeb02 "clojure.spec.alpha$regex_spec_impl$reify__2510@643aeb02"],
:value
(tails
(example tails [1 2 3 4] '([1 2 3 4] (2 3 4) (3 4) (4)))
[coll]
(take-while some? (iterate next coll))),
:args
(tails
(example tails [1 2 3 4] '([1 2 3 4] (2 3 4) (3 4) (4)))
[coll]
(take-while some? (iterate next coll)))}
alpha.clj: 712 clojure.spec.alpha/macroexpand-check
alpha.clj: 704 clojure.spec.alpha/macroexpand-check
AFn.java: 156 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
Var.java: 705 clojure.lang.Var/applyTo
Compiler.java: 6974 clojure.lang.Compiler/checkSpecs
Compiler.java: 6992 clojure.lang.Compiler/macroexpand1
Compiler.java: 7079 clojure.lang.Compiler/macroexpand
Compiler.java: 7165 clojure.lang.Compiler/eval
Compiler.java: 7136 clojure.lang.Compiler/eval
core.clj: 3202 clojure.core/eval
core.clj: 3198 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 667 clojure.core/apply
core.clj: 1977 clojure.core/with-bindings*
core.clj: 1977 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 437 clojure.main/repl/read-eval-print/fn
main.clj: 437 clojure.main/repl/read-eval-print
main.clj: 458 clojure.main/repl/fn
main.clj: 458 clojure.main/repl
main.clj: 368 clojure.main/repl
RestFn.java: 137 clojure.lang.RestFn/applyTo
core.clj: 667 clojure.core/apply
core.clj: 662 clojure.core/apply
regrow.clj: 20 refactor-nrepl.ns.slam.hound.regrow/wrap-clojure-repl/fn
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 84 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 152 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 202 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 201 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 829 java.lang.Thread/run