请分享您的想法,参与2024年Clojure状态调查!

欢迎!请访问关于页面,了解更多这个网站的工作方式。

+1
规范
下面的例子显示了在unform之后并未统一任何形式的情况。我期望您可以通过不断地重复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返回函数定义,但以列表形式而不是向量形式表示参数
  (->> 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中都工作。

在规范2中,我们添加了对非流动分类符s/and(目前称为s/and-,但这个名字仍在变化,最终可能是s/union或其他)的支持,这是为了添加s/cat变体,这些变体除了强制coll是向量或序列之外,还需要s/catv和s/cats。

最终,我们将重新设计core.specs,使用spec2,并为defn arg vector使用s/catv,这将解决此问题。

0

评论者:jeroen

这个代码片段展示了以上代码的良好格式:https://gist.github.com/jeroenvandijk/28c6cdd867dbc9889565dca92673a531

0

评论者:lgs32a

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

考虑一下,在这种情况下以及类似的情况应该有一个vcat。

0

评论者:marco.m

你好,有什么新消息吗?

0

评论者:alexmiller

没有。

0

评论者:jeroen

发现了另一个问题

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

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

0
参考:https://clojure.atlassian.net/browse/CLJ-2021(由jeroen报告)
...