Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does a macro-enabled language keep track of the source code for debugging?

This is a more theoretical question about macros (I think). I know macros take source code and produce object code without evaluating it, enabling programmers to create more versatile syntactic structures. If I had to classify these two macro systems, I'd say there was the "C style" macro and the "Lisp style" macro.

It seems that debugging macros can be a bit tricky because at runtime, the code that is actually running differs from the source.

How does the debugger keep track of the execution of the program in terms of the preprocessed source code? Is there a special "debug mode" that must be set to capture extra data about the macro?

In C, I can understand that you'd set a compile time switch for debugging, but how would an interpreted language, such as some forms of Lisp, do it?

Apologize for not trying this out, but the lisp toolchain requires more time than I have to spend to figure out.

like image 877
Sean Woods Avatar asked Jul 09 '10 16:07

Sean Woods


1 Answers

I don't think there's a fundamental difference in "C style" and "Lisp style" macros in how they're compiled. Both transform the source before the compiler-proper sees it. The big difference is that C's macros use the C preprocessor (a weaker secondary language that's mostly for simple string substitution), while Lisp's macros are written in Lisp itself (and hence can do anything at all).

(As an aside: I haven't seen a non-compiled Lisp in a while ... certainly not since the turn of the century. But if anything, being interpreted would seem to make the macro debugging problem easier, not harder, since you have more information around.)

I agree with Michael: I haven't seen a debugger for C that handles macros at all. Code that uses macros gets transformed before anything happens. The "debug" mode for compiling C code generally just means it stores functions, types, variables, filenames, and such -- I don't think any of them store information about macros.

  • For debugging programs that use macros, Lisp is pretty much the same as C here: your debugger sees the compiled code, not the macro application. Typically macros are kept simple, and debugged independently before use, to avoid the need for this, just like C.

  • For debugging the macros themselves, before you go and use it somewhere, Lisp does have features that make this easier than in C, e.g., the repl and macroexpand-1 (though in C there is obviously a way to macroexpand an entire file, fully, at once). You can see the before-and-after of a macroexpansion, right in your editor, when you write it.

I can't remember any time I ran across a situation where debugging into a macro definition itself would have been useful. Either it's a bug in the macro definition, in which case macroexpand-1 isolates the problem immediately, or it's a bug below that, in which case the normal debugging facilities work fine and I don't care that a macroexpansion occurred between two frames of my call stack.

like image 127
Ken Avatar answered Sep 29 '22 23:09

Ken