2024年 Clojure 调查!中分享您的想法。

欢迎!请访问关于页面以了解更多有关此工作的信息。

0
Spec

看起来可以使用宏来为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

1 答案

+1

选中
 
最佳答案

不,规范并不太过分。defn 宏不支持这一点。您可以使用-Dclojure.spec.skip-macros=true禁用规范宏检查。

您可以根据需要编写一个包裹defn的宏并发出评估过的事物。

...