2024 Clojure状态调查!中分享你的想法。

欢迎!请参阅关于页面,了解更多关于此网站的信息。

+1
Spec
以下示例展示了在unform之后,一个经过conform的形式不具备任何进一步conform的情况。我期待可以通过不断重复conform -> unform -> conform无限次并得到相同的结果。


(require '[clojure.core.specs])
(require '[clojure.spec :as s])

(s/def ::defn-macro (s/cat :type #{'defn} :definition :clojure.core.specs/defn-args))

(let [form '(defn foo "bar" ([a & b] a a c) ([a b] a))]

  (-> form
      (->> (s/conform ::defn-macro))) ;;=> {:type defn, :definition {:name foo, :docstring "bar", :bs [:arity-n {:bodies [{:args {:args [[:sym a]], :varargs {:amp &, :form [:sym b]}}, :body [a a c]} {:args {:args [[:sym a] [:sym b]]}, :body [a]}]}]}}

  ;; Unforming returns the function definition, but with the args in a list instead of a vector
  (->> form
      (s/conform ::defn-macro)
      (s/unform ::defn-macro))  ;;=> (defn foo "bar" ((a (& b)) a a c) ((a b) a)))

  ;; 调用unform后,再次调用conform不再有效
  (->> form
      (s/conform ::defn-macro)
      (s/unform ::defn-macro)
      (s/conform ::defn-macro)) ;;=> :clojure.spec/invalid

    )

7个答案

+1

对于“正则表达式集必须也是向量”的特定情况,使用spec 1来实现这一点并不真正可能,使其对所有conform、unform和gen都有效。

在spec 2中,我们添加了对非流式s/and(目前称为s/and-,但该名称仍在变动,可能最终成为s/union或其他名称)的支持,这是添加额外强制coll是向量或序列的s/cat变体s/catv和s/cats所需。

最终我们将使用spec2重新编写core.specs文件,并使用s/catv作为defn参数向量的参数,这将解决这个问题。

0投票

评论人:jeroen

这个gist显示了上述代码的更好格式化 https://gist.github.com/jeroenvandijk/28c6cdd867dbc9889565dca92673a531

0投票

评论人:lgs32a

这个问题可以快速追溯到:clojure.core.specs/arg-list,它被定义为s/and向量?。在不规范化时,它不会创建向量。

考虑一下,对于这种情况和其他类似情况,vcat会更好。

0投票

评论人:marco.m

你好,有什么消息吗?

0投票

评论人:alexmiller

没有。

0投票

评论人:jeroen

发现另一个问题

(->> '(foo (link: h0 & [h1]))
(s/conform :clojure.core.specs.alpha/defn-args)
(s/unform :clojure.core.specs.alpha/defn-args))
;#=> '(foo (link: h0 (& [h1))))

这里剩余的参数被包在一个额外的列表中。我应该在哪里报告这个问题?

0投票
...