-
Notifications
You must be signed in to change notification settings - Fork 14
Macro idea for async instrumentation: >defn-go #24
Description
I have a lot of core.async in my (CLJS) app. I guess spec + core.async is a very big topic, and at some point the Clojure community will probably come up with a powerful approach. In the mean time, this is more of a low-hanging-fuit idea that could be very helpful.
In async code there are a lot of functions where the top level form is (go ...). Often the return value is discarded, but sometimes not, e.g. an async function to fetch a value from a server via HTTP.
The normal return spec is pretty much useless, as such functions always return a channel.
What you really want is to be able to spec the (single) value that is sent over the returned channel. From an instrumentation point of view, this could be done if we lift the (go ...) to be part of the macro that defines the function (and the specs), i.e. something like this:
(>defn-go my-fn
[...args]
[...arg-specs => ret-spec]
...body)
which, when instrumented, would expand to something along the lines of
(defn my-fn
[...args]
; check passed args against arg-specs (as usual)
(go
(let [result# ...body]
; check result# against ret-spec
result#)))
I'm intending on having a crack at implementing this macro myself. Any advice would be greatly appreciated. If it sounds like something that could be a contribution, so much the better.