Everytime debuggers are brought up, there is inevitable lecturing from advanced programmers about how ânobody needs a debugger, it is indicative of a poor design, all I need are better stack traces, etcâŚâ.
Whether those comments are true or not, it is a good way to separate the different types of users. These (primarily skilled package developers) are the the exact opposite of the people the debugger is intended to support. With all due respect, the easiest way to simplify a debugger is to split out those requirements into something completely different (i.e gdb style âdebuggerâ, and utterly useless for the vast majority of people who say they want a debugger).
So if the main users of a debugger are scientists and students writing scripts, who find computing somewhat of an annoyance, then getting the GUI right is essential. Doing something half-assed and targeted at package developers is useless or worse. If a matlab or low-tech python user tries out âthe debuggerâ and it is all about stack traces and macros, then they are likely to conclude that Julia is intended as a hardcore systems language, and not towards their needs.
So better to wait until the right resources are in place, do it right, and attempt to make it a matlab style code-stepping utility. My feeling is that all systems debugger style features can be entirely ignored or patched on as minifeatures (as suggested here).
When the time is right and the resources are in place, the big requirement that can slide is about speed. Obviously, the debugger canât run all of Julia in interpreted mode, but it can be pretty slow (e.g two orders of magnitude is perfectly reasonable in code that is actually be debugged). A full Visual Studio style debugger which runs pretty fast and still manages to allow debugging anywhere in the codebase is not necessary at first.
I am under the assumption that the approach is basically to have an âAST interpretedâ mode for functions that are being debugged, where as many other functions are compiled as possible. I imagine that the issue of having nested functions support this is an issue due to intensive inlining/etc. If so, then let me propose a simplifying assumption:
- The only functions which can run interpreted are ones that have a breakpoint set in them. i.e. hitting
F9
in the GUI or right clicking to create a breakpoint. Note I am saying the GUI, because that is what the users actually want.
- The idea is that the breakpoint would flag the method as being something to run interpreted.
- Now, how would this work nested deep inside a bunch of calls where it may have been inlined? It wouldnât! Methods run interpreted only if their caller was running interpretedâŚ
- At the top level in Atom (note I am not even saying REPL, because the GUI is the key) lets say I have a âdebug modeâ setting.
- If that setting is on, then it would check whether the top-level method is flagged to be interpreted or not, and would run the method in the debugger it it was.
- Next, when the interpreter is running a method in interpreted mode, it can check to see if methods it is calling are in interpreted mode before deciding if it wants to enter them or not.
- This way, the only way to be in interpreted mode is if the entire call stack to that point was interpreted (and had breakpoints).
- Down the road, things could be setup so the âStep Intoâ (i.e.
F11
or whatever) automatically flags a function it is about to call in interpreted mode, so that they wouldnât have to actually set a breakpoint in each function.
Would this be confusing in practice? Not really, because they majority of people using this sort of debugging would be in only a few functions deep. Now, I have no idea if this helps simplify much⌠I know that even a slow interpreter is still a major undertaking. But this could get people who really want a debugger 80% of the way there.