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

欢迎!请访问关于页面以获取更多关于如何使用本站的信息。

+1
Spec
以下示例显示了一个已经合规的形式在反规范化后没有进一步合规的情况。我的预期是您可以重复进行合规 -> 反规范化 -> 合规操作并始终获得相同的结果。


(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]}]}]}}

  ;; 反规范化返回函数定义,但参数为列表而非向量
  (->> form
       (s/conform ::defn-macro)
       (s/unform ::defn-macro))  ;;=> (defn foo "bar" ((a (& b)) a a c) ((a b) a)))

  ;; 反规范化后的合规操作不再有效
  (->> form
       (s/conform ::defn-macro)
       (s/unform ::defn-macro)
       (s/conform ::defn-macro)) ;;=> :clojure.spec/invalid

    )

7 答案

+1

对于“正则表达式集合也必须是向量”的特定情况,使用spec 1来实现这并不现实,使其对所有合规、反规范化和生成操作都有效。

在规格文件 2 中,我们增加了对非流动 s/and(目前称为 s/and-,但该名称仍在变化,可能最终会是 s/union 或其他名称)的支持,这是添加 s/cat 变体(如 s/catv 和 s/cats)并强制 coll 为向量或序列所必需的。

最终,我们将使用 spec2 重构 core.specs,并使用 s/catv 作为定义参数的向量,这将解决这个问题。

0 投票

评论者:jeroen

此 Gist 展示了上述代码的更好格式: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 & [h1]))
(s/conform :clojure.core.specs.alpha/defn-args)
(s/unform :clojure.core.specs.alpha/defn-args))
;#=> '(foo (link: h0 (& [h1))))

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

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