Fork me on GitHub
#malli
<
2022-12-04
>
Carlo07:12:41

A question about recursive generators and :+. Consider this recursive spec that describes a boolean formula:

(def formula
  [:schema
   {:registry
    {::formula
     [:or
      :boolean
      [:tuple [:enum :not] :boolean]
      [:tuple [:enum :and] [:* [:ref ::formula]]]
      [:tuple [:enum :or]  [:* [:ref ::formula]]]]}}
   [:ref ::formula]])
We can of course generate examples via:
(repeatedly 20 #(mg/generate formula))
But, if I change :* with :+ (rest in 🧵)

Carlo07:12:35

I now have:

(def formula
  [:schema
   {:registry
    {::formula
     [:or
      :boolean
      [:tuple [:enum :not] :boolean]
      [:tuple [:enum :and] [:+ [:ref ::formula]]]
      [:tuple [:enum :or]  [:+ [:ref ::formula]]]]}}
   [:ref ::formula]])

(repeatedly 20 #(mg/generate formula))
and the generator for this seems broken to me (for starters, it usually doesn't return 20 things. I suspect the reason is that it makes more difficult to generate values (as a naive sampling terminates more rarely). Is that correct?

ikitommi10:12:35

recursive generators are hard, please read https://github.com/metosin/malli/blob/master/src/malli/generator.cljc#L186-L281. Ideas welcome on how to make it better.

🙌 1
ambrosebs06:12:23

the issue is that recursive :+ can make generators like (gen/non-empty (gen/return ()))

ikitommi07:12:36

That was a quick resolution, thanks @U055XFK8V!

Carlo08:12:38

Also, what's :malli.core/potentially-recursive-seqex supposed to represent? Can't seqexes contain recursive terms?

Carlo08:12:43

By a brute force search, I saw that this problem is solved if I wrap :+ into a :schema. A more thorough explanation would be useful though

jfntn19:12:32

Can someone confirm whether :schema values being explained as reified values is a bug?

malli.core
> (explain [:map [:a int?]] {:a "_"})
{:errors ({:in [:a],
           :path [:a],
           :schema #<malli.core$_simple_schema$reify$reify__13042@17a463a5>,
           :value "_"}),
 :schema #<malli.core$_map_schema$reify$reify__13253@3a3e779a>,
 :value {:a "_"}}
https://github.com/metosin/malli/issues/789