Fork me on GitHub
Ben Sless06:05:06

Next step is figuring out how to derive generators from this

Ben Sless07:05:53

Most cases just work besides equality

Ben Sless08:05:33

Here we go:

(defn- derive-from-fmap
  [schema options gen]
  (let [props (merge (m/type-properties schema)
                     (m/properties schema))]
    (when-some [fmap (:gen/fmap props)]
      (gen/fmap (m/eval fmap (or options (m/options schema)))

(defmethod mg/-schema-generator :and [schema options]
  (let [[h & t] (m/children schema options)
        base-gen (mg/generator h options)
        gen (reduce (fn [gen schema]
                      (if-let [gen (derive-from-fmap schema options gen)]
    (gen/such-that (m/validator schema options) gen 100)))

Ben Sless10:05:33

I collected the proof of concept implementation with some explanations and cleaned up code at a repo

Ben Sless12:05:14

Some more thoughts: • should references to paths inside maps be explicit rather than implicit? i.e. [:keys/> :x :y] vs [:keys/> [:path :x] [:path :y]] . The second syntax is more cumbersome but gives more freedom (`[:path :x :z]`) and facilitates more logic (see next points) • Facts about collections. How do I say the value at key k1 must be contained in the collection in k2 , or a number smaller than the size of that collection? Stuff like [:contains? :x :y] (the value at y is in x), or [:> [:count :x] :y] (y is smaller than the count of x)


Very cool stuff! I was playing with adding support for cljs yesterday. (resolve sym)( is not allowed in cljs - I suspect converting this to a macro may get cljs support working. In cljs resolve only allows a literal quoted symbol as an argument:


Note that runtime resolve in general doesn't play well with GraalVM native-image unless it's executed at compile time

Ben Sless14:05:00

I'll replace it with a map or defmulti

Ben Sless14:05:15

I think defmulti will be best, extensible

Ben Sless15:05:05

What about the alternative syntax?