Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Case where clojure.spec/unform returns invalid result according to 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]}]}]}}
;; 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)))
;; Conforming after unforming doesn't work anymore
(->> form
(s/conform ::defn-macro)
(s/unform ::defn-macro)
(s/conform ::defn-macro)) ;;=> :clojure.spec/invalid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment