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

欢迎!请查看关于页面以了解更多有关此工作方式的信息。

+1
Spec
以下示例显示了一个已符合的表单,在解构之后没有符合任何东西的情况。我希望您可以在不断重复 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]}]}]}}

  ;; 解构返回函数定义,但参数在列表中而不是向量中
  (->> 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 来实现这一点并不可能,同时也让符合、解构和生成都起作用。

在spec 2中,我们添加了对非流动s/and的支持(目前称为s/and-,但这个名字还在变动,可能最终会是s/union或其他),这是为了添加s/cat变体,强制集合要么是向量要么是序列,例如s/catv和s/cats。

最终我们将使用spec2重新编写core.specs,对于定义参数向量使用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 & [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(由jeroen报告)
...