Can anybody explain, what's wrong with the example below? Why does it throw the StackOverflowError exception?
(s/def ::tag keyword?)
(s/def ::s string?)
(s/def ::n number?)
(s/def ::g
(s/cat :tag (s/? ::tag)
:ex (s/alt :string ::s
:number ::n
:and (s/+ ::g)
)))
(s/conform ::g '["abc"])
Similarly to what Alex Miller points out in this Google Groups discussion, s/+
tries to resolve ::g
during the definition.
This should do what you want, I think:
(s/def ::g
(s/spec (s/cat :tag (s/? ::tag)
:ex (s/alt :string ::s
:number ::n
:and ::g))))
; REPL
user=> (s/conform ::g [:foo [:bar "abc"]])
{:ex [:and {:ex [:string "abc"] :tag :bar}] :tag :foo}