For context, if I supply an invalid value for an 'alt' spec, explain-data will return two problems:
(s/explain-data (s/cat
:x (s/alt :i int? :s string?))
[:kw])
;; explain-data contains two problems, one for each alternative:
;; #:clojure.spec.alpha{:problems ({:path [:x :i], :pred clojure.core/int?, :val :kw, :via [], :in [0]} {:path [:x :s], :pred clojure.core/string?, :val :kw, :via [], :in [0]}), :spec {:clojure.spec.alpha/op :clojure.spec.alpha/pcat, :ps [{:clojure.spec.alpha/op :clojure.spec.alpha/alt, :ps (#function[clojure.core/int?] #function[clojure.core/string?--5132]), :ks (:i :s), :forms (clojure.core/int? clojure.core/string?), :id #uuid "88448dbf-dce7-4789-9266-aa150a6563bc"}], :ret {}, :ks [:x], :forms [(clojure.spec.alpha/alt :i clojure.core/int? :s clojure.core/string?)], :rep+ nil}, :value [:kw]}
However, if the value is missing an element, explain-data returns a single problem
(s/explain-data (s/cat
:x (s/alt :i int? :s string?))
[])
;; explain-data contains a single problem, with a compound predicate
;; #:clojure.spec.alpha{:problems [{:path [:x], :reason "Insufficient input", :pred (clojure.spec.alpha/alt :i clojure.core/int? :s clojure.core/string?), :val (), :via [], :in []}], :spec {:clojure.spec.alpha/op :clojure.spec.alpha/pcat, :ps [{:clojure.spec.alpha/op :clojure.spec.alpha/alt, :ps (#function[clojure.core/int?] #function[clojure.core/string?--5132]), :ks (:i :s), :forms (clojure.core/int? clojure.core/string?), :id #uuid "5f655d8c-19bb-43de-a153-722dd338d1f3"}], :ret {}, :ks [:x], :forms [(clojure.spec.alpha/alt :i clojure.core/int? :s clojure.core/string?)], :rep+ nil}, :value []}
Motivation: for specs for macros with many alternatives, the errors for a missing element are fairly opaque. For example, try (defn hello "hello world")