clojure.spec explain and multi-arity functions with first optional argument

343 views
Skip to first unread message

Yegor Timoshenko

unread,
Apr 22, 2017, 1:31:48 PM4/22/17
to Clojure
(require '[clojure.spec :as s])
(require '[clojure.spec.test :refer [instrument]])

(defn request ([url]) ([params url]))

(s/fdef request
  :args (s/cat :params (s/? map?) :url string?))

(instrument `request)
(request [] "")

ExceptionInfo Call to #'user/request did not conform to spec:
In: [0] val: [] fails at: [:args :url] predicate: string?
:clojure.spec/args  ([] "")
:clojure.spec/failure  :instrument
:clojure.spec.test/caller  {:file "form-init1226863901212006294.clj", :line 1, :var-scope user/eval2193}
  clojure.core/ex-info (core.clj:4725)

I expected that it would fail at `map?` predicate rather than at `string?` predicate.
s/or produces better explanation, but at the same time is relatively more verbose:

(require '[clojure.spec :as s])
(require '[clojure.spec.test :refer [instrument]])

(defn request ([url]) ([params url]))

(s/fdef request
  :args (s/or :simple (s/cat :url string?)
                   :advanced (s/cat :params map? :url string?)))

(instrument `request)
(request [] "")

ExceptionInfo Call to #'user/request did not conform to spec:
In: [0] val: [] fails at: [:args :simple :url] predicate: string?
In: [0] val: [] fails at: [:args :advanced :params] predicate: map?
:clojure.spec/args  ([] "")
:clojure.spec/failure  :instrument
:clojure.spec.test/caller  {:file "form-init1226863901212006294.clj", :line 1, :var-scope user/eval2208}
  clojure.core/ex-info (core.clj:4725)

Is it subject to improvement? https://dev.clojure.org/jira/browse/CLJ-1982 might be the same issue.

Leon Grapenthin

unread,
Apr 23, 2017, 10:57:00 AM4/23/17
to Clojure
Please try whether my CLJ-2013 patch fixes the issue for you. From my observation it should.
Reply all
Reply to author
Forward
0 new messages