This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-11-10
Channels
- # announcements (3)
- # asami (19)
- # babashka (38)
- # beginners (42)
- # cider (19)
- # clojure (17)
- # clojure-europe (34)
- # clojure-hungary (3)
- # clojure-nl (1)
- # clojure-norway (53)
- # clojure-uk (7)
- # clojuredesign-podcast (34)
- # conjure (2)
- # cursive (7)
- # data-science (13)
- # datalevin (3)
- # datomic (19)
- # dev-tooling (1)
- # events (1)
- # honeysql (2)
- # hyperfiddle (31)
- # integrant (16)
- # juxt (39)
- # missionary (14)
- # nrepl (14)
- # off-topic (57)
- # overtone (22)
- # podcasts-discuss (1)
- # practicalli (32)
- # reitit (12)
- # releases (2)
- # ring (13)
- # ring-swagger (2)
- # sql (85)
- # squint (75)
Hi all, anyone knows a good way to debug defmulti?
I’m trying to simulate the visitor pattern using defmulti
, and I’m trying to find a way to debug what’s going on after each dispatch.
What I want is similar to the trace tool in https://github.com/camsaul/methodical, you can trace a method call and it’ll print out a nested call stack like this
Make sure your dispatch points to a function bound to a var, then you can use with-redefs
to rebind your function to a version with tracing in the context of the test/debugging
hmm, does that mean I’ll need to use that var on all defmethods?
https://gist.github.com/souenzzo/b00220ad5c2b65884f5ab792588be492 That’s why I prefer map-dispatch instead multimethods
Another option would be to get the multimethods that you're interested in, iterate over their methods, and wrap each in another function that just reports what's going on.
And map-dispatch
is a suitable replacement only in some scenarios, not all of them.
Why is it suitable only in some scenarios?
Some existing libraries rely on multimethods - you can't get around those. They have a global state - sometimes it's desirable. They're extendable from anywhere, not just the initialization site. Multimethods support dispatch value derivation. Multimethods dispatch on a result of a function, not on a predefined field. Of course, the linked implementation can be adjusted for that, but there is still something that needs to be done there. Same for a potential default value.
I don’t see how a global state is desirable + a very bad one to inspect is desirable.
I tend to almost not use multimethods library
You can always extend map-dispatch
associng / dissocing keys from it’s registry importing default registries or making new ones
Value derivation is a bad practice and sounds like inheritance
If something is so bad to debug and does not provide you a very amazing performance, it should not be used
If the problem is debugging then I’d encourage you to try methodical, I think its performance is ~ with multimethod, and it has a great debugging tool. you can even define triggers for before/after a method execution.
I almost never have to debug something, but when I do, multimethods aren't a problem at all. Regardless if they use a custom hierarchy or derivation (which isn't related to inheritance all that much).
same here, but since I’m trying to replicate the visitor pattern, the call build up data as it recursively calls the defmulti multiple times. so I want to see what’s in and out through each call
ah no, it’s call the-multimethod
multiple times
As long as there are no new methods defined while you're debugging your code, iterating over the result of (methods ...)
and re-defining all the methods with a wrapper should work just fine.
If you need a more advanced approach, you should in theory be able to wrap defmulti
and defmethod
macros themselves.
Finally, IntelliJ IDEA with Cursive has first-class debugging support. You can just step over the code as you'd do in e.g. Java.
@U023C0QKU4W have you tried http://www.flow-storm.org/ ? It can provide you that same hierarchy of nested calls and other ways to look at the executed multimethods also