Skip to content

Macro idea for async instrumentation: >defn-go #24

@tslocke

Description

@tslocke

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions