Соответствие clojure.spec вызывает исключение переполнения стека

Кто-нибудь может объяснить, что не так с примером ниже? Почему он выдает исключение StackOverflowError?

(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"])

person Lambder    schedule 09.05.2017    source источник


Ответы (1)


Аналогично тому, на что указывает Алекс Миллер в этом обсуждении групп Google. , s/+ пытается разрешить ::g во время определения.

Это должно делать то, что вы хотите, я думаю:

(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}
person Eero Helenius    schedule 09.05.2017