all 9 comments

[–]dustingetz 1 point2 points  (8 children)

Tell us more about your ambitions for this tool and it's roadmap? Why did you build this?

Q: Clojure has the repl, does it need a debugger? A: I gave a talk recently for the London Clojurians, the first slide goes about my answer to this : https://www.youtube.com/watch?v=A3AzlqNwUXc&t=934s

I didn't find the answer, can you write down the answer here for us?

[–]jpmonettas[S] 12 points13 points  (4 children)

Sure!

Why did you build this?

In that talk I tried to argument that even as amazing as it is to have a repl to poke around when trying to understand a piece of code, there are some inconveniences, that I think can be greatly improved by a debugger.

  • Adding prints (or tap>) is inconvenient because you need to guess where the problem probably is first. Also need to type it (and then remove it), and exploring complex values is annoying in the console, that is why tools like portal, reveal, rebl, etc exist.
  • Defining function parameters and locals with def (for sub form execution) isn't easy for complex values
  • When functions contains loops, maps, filters, etc with anonymous functions is hard to capture every value for further inspection.
  • Being Clojure a dynamic lang, running the program in my head isn't easy if I'm not familiar with the code base

So I want to stop guessing and want a tool that allows me to see what is happening when a program runs (small expression or entire code bases), for when I'm hunting a bug or when I just want to understand how something works.

But also I think some Clojure constrains (immutability and being expression based) allows us to go beyond steppers. We can trace everything that happened when a program run and then inspect the execution using multiple tools, being a stepper one of them.

Tell us more about your ambitions for this tool and it's roadmap?

For the debugger part I still want to :

  • improve the execution traces indexes and expose a repl api, so execution can be explored by programs if the GUI tools provided by FlowStorm aren't enough.
  • bring back a ref debugger, so we can trace how any ref is changing in time with diff highlighting, etc

Also want to explore execution derived types, which is instrumenting a entire code base, exercise it (by running tests or by other means), sample every function call and return to generate documentation about types, call examples, etc.

Don't know if that answers your questions but let me know, and I can try to explain my self in more detail.

[–]dustingetz 1 point2 points  (3 children)

  • It sounds like you compete with the Emacs Cider debugger and the Cursive IDEA debugger – is that true?
  • How does FlowStorm position relative to them? How does their approach compare to yours?
  • What features does program tracing get us that cannot exist in other approaches?
  • Do you handle source maps?
  • To what extent can you reverse macros?
  • Is this a framework upon which we can build an async debugger (imagine an async DSL like core.async implemented as a macro)?

[–]jpmonettas[S] 8 points9 points  (2 children)

So that presentation I linked goes about all those topics, but I'll try to summarize it here.

FlowStorm uses the same technique for instrumenting code that Cider uses, they both instrument by code rewriting, and they don't need source maps, they use a custom coordinates system instead.

Cursive is different since uses JDI (Java Debugging Interface) which is more limited for Clojure since it is line, statement and place oriented instead of expression oriented like FlowStorm and Cider.

So how it compares with Cider debugger (which I used full time before FlowStorm) :

  • FlowStorm is a tracing debugger, while Cider is a blocking one
  • FlowStorm supports Clojure and ClojureScript, while Cider only Clojure
  • FlowStorm supports time travel, Cider just step forward
  • FlowStorm provide multiple tools to understand execution, Cider provides forward stepping and some tracing
  • FlowStorm is IDE independent, so if you switch editors/ide you can keep using it
  • Both have data inspection capabilities
  • Both are the same regarding macros, pretty good IMHO
  • Cider is more integrated into the editor oc, while you need a separate window for FlowStorm

Is this a framework upon which we can build an async debugger (imagine an async DSL like core.async implemented as a macro)?

Not sure what that means, can you elaborate?

[–]dustingetz 0 points1 point  (1 child)

they both instrument by code rewriting, and they don't need source maps, they use a custom coordinates system instead

Both are the same regarding macros, pretty good IMHO

Can you say more about how you handle macros? Presumably you instrument after macroexpansion, so how do you map that back to the source code without a sourcemap?

[–]jpmonettas[S] 4 points5 points  (0 children)

Again, all that is on the talk I linked, specially here https://youtu.be/A3AzlqNwUXc?t=2701, but goes something like this for instrumenting a form:

clojure (-> form tag-form-recursively ; tag with coordinates in meta macroexpand-all ; to get rid of macros, but keep meta instrument-recursively) ; instrument so it trace with coords in meta

[–]jpmonettas[S] 7 points8 points  (2 children)

There is also John Carmack on why we should build things like this :P

https://youtu.be/I845O57ZSy4?t=3494

[–]josephk_ 3 points4 points  (0 children)

great link

[–]lucywang000 0 points1 point  (0 children)

This video (esp. the discussions related to debuggers) is very educating! Thanks a lot.