metosin / malli

High-performance data-driven data specification library for Clojure/Script.
Eclipse Public License 2.0
1.48k stars 209 forks source link

Protocol function instrumentation #555

Open piotr-yuxuan opened 2 years ago

piotr-yuxuan commented 2 years ago

Hello, thank you very much once again for this great tool.

The doc for function schema instrumentation (link) mentions defn and doesn't refer to protocol functions so I guess the behaviour below isn't a bug, but more a feature request.

(defprotocol Backend
  (upsert [this data])
  (delete [this id])
  (query [this f]))

(m/=> upsert
      [:=>
       [:cat Backend [:map [:id int?]]]
       [:map [:id int?]]])

(m/=> delete
      [:=>
       [:cat Backend int?]
       [:enum :done]])

(m/=> query
      [:=>
       [:cat Backend ifn?]
       [:sequential [:map [:id int?]]]])

(defrecord InMemoryBackend [state]
  Backend
  (upsert [_ {:keys [id] :as data}] (swap! state assoc id data))
  (delete [_ id] (swap! state dissoc id) :done)
  (query [_ f] (->> @state vals (filter f))))

(mi/instrument!)

(doto (InMemoryBackend. (atom {}))
  (upsert {:id 1}))
=> (atom {1 {:id 1}})

;; Not the expected outcome
(doto (InMemoryBackend. (atom {}))
  (upsert :should-fail))
=> (atom {nil :should-fail})

Would you consider and review a PR that would extend malli and add support for protocol function instrumentation? Any thoughts about it off the top of your mind?

ikitommi commented 2 years ago

Would be good to support protocol methods too. But, how would that work? How do Spec and Plumatic handle these?

piotr-yuxuan commented 2 years ago

I haven't donw a lot of research about it, but I have been left under the impression that:

Not sure it's feasible, but I will try to think more about a path toward protocol function instrumentation.

parlir commented 2 years ago

This would also be something I would love to see as well. I have several protocols that are used on many different implementations which I want guarantees for inputs/outputs.