methodical icon indicating copy to clipboard operation
methodical copied to clipboard

Ability to add docstring defmethod definitions.

Open maacl opened this issue 5 years ago • 6 comments

@camsaul This would be very useful.

maacl avatar Apr 06 '21 14:04 maacl

Where would the docstring go for that? I think you'd run into the same issue as in regular Clojure (i.e. there is no symbol to which to attach it).

jeff303 avatar Apr 29 '21 19:04 jeff303

I don't know how this is implemented so I cannot speak to how it is best solved. The StackOverflow response claims that needing a docstring for a method indicates that it should be implemented as a separate function, which makes no sense as the multimethod just works as a function specialised on its parameters. As a function a docstring would be useful. Perhaps defmethod could create a symbol for each method.

maacl avatar Apr 29 '21 19:04 maacl

defmethod actually does create a symbol under the hood for each method, so the :doc metadata could go on that

camsaul avatar Apr 29 '21 22:04 camsaul

defmethod actually does create a symbol under the hood for each method, so the :doc metadata could go on that

Interesting. But how useful would it be? Isn't that symbol supposed to be a black box of sorts? How would tooling be aware of it (which, I presume, would be the ultimate use case of doing this)?

jeff303 avatar May 03 '21 20:05 jeff303

If we really wanted to be clever (and I think we do) we could have a new method implementation update the docstring for multimethod itself. e.g.

(m/defmulti my-multimethod
  "WOW"
  keyword)

(:doc (meta #'my-multimethod))
-> 
"WOW"

(m/defmethod my-multimethod :x
  "Doesn't do anything!"
  [_])

(:doc (meta #'my-multimethod))
->
"WOW

Primary Method Implementations:

#### `:x` 

Doesn't do anything."

We could also display that docstring when we pretty-print Methodical stuff.

I think this would really be something helpful and could be a real killer feature

camsaul avatar Jun 04 '21 17:06 camsaul

RE where to put the doc metadata for a method...

(m/defmethod my-multimethod :x
  [_])

just macroexpands to

(do
  (defn my-multimethod-primary-method-x [next-method _])
  (u/add-primary-method!
   #'my-multimethod
   :x
   my-multimethod-primary-method-x))

(it actually generates a symbol based on combining the multimethod with a munged version of the dispatch value so it's easy to debug in stacktraces)

So we could of course put metadata on the var itself (#'my-multimethod-primary-method-x). But Fns are also IMetas so it might be better to put the multimethod on the actual function the var points to (my-multimethod-primary-method-x) so we can access it programmatically. Or maybe just put the metadata on both

camsaul avatar Jun 04 '21 17:06 camsaul