How to print a Mathematica expression without evaluating it & how to use that for debugging.

Introduction

For easy debugging of larger functions I usually add the option debug->True to output auxiliary variables.

A very easy approach would be the following:

myComplicatedFunction[arg1_, arg2_, (...), OptionsPattern[]]:=
Module[{(internalVariable, (...))},
    (...)
    
    If[OptionValue[debug],Print[internalVariable]];

    (...)
];

this can be made a little bit shorter by wrapping the If statement in a function and adding something like deb=OptionValue[debug] at the beginning of our function, so that we can simply write

debugPrint[deb,interalVariable];

However, I would also like to automatically print the name of the variable, not just the value it has. That’s fairly easy, we simply put all arguments of our function on hold via

SetAttributes[debugPrint,HoldAll];

so that we can access the symbol name (as a string) inside of our debugPrint function via

SymbolName@Unevaluated@expr

But with full expressions such as

debugPrint[deb,(internalVariable1+internalVariable2)/2]

we need to be more clever, because we cannot just use SymbolName@Unevaluated to get a nice printable expression: the expression is not a symbol (so SymbolName won’t work) and simply using Print@Unevaluated@expr will always print out the Unevaluated as well.

Here the trick is to use MakeBoxes (which converts everything into typesetting boxes that only contain strings) and then DisplayForm to display that.

Code

Here’s the full code:

A small example to see how it can be used:

globalVar = 4;

complicatedFunction[OptionsPattern[]] :=
  Module[{deb, a, b},
   	deb = OptionValue["debug"];
   a = 1;
   b = 2;
   debugPrint[deb, "Debug enabled"];
   debugPrint[deb, a];
   debugPrint[deb, globalVar];
   debugPrint[deb, a + b];
   debugPrint[deb, (globalVar + b)/2];
   Return["Whatever this function normally does..."];
   ];

Options[complicatedFunction] = {debug -> False};

And to run it:

(*should not print any debug messages*)
complicatedFunction[]

(*should print debug messages*)
complicatedFunction[debug->True]

Output:

Output

Note how all local variables have an $4354 attached to make the variable name unique inside of Module (mentioned e.g. here). In principle that suffix could be stripped with a regular expression, but I think that it is valuable information whether we are dealing with a local or global variable, so I just leave it like this.

Update (Jan 7 2018): Stripping the $... suffix is now the default behaviour (which can be temporarily disabled by an optional argument or by replacing removeDollars_:True with removeDollars_:False):

Output

Stripping the suffix is implemented by first converting the expression to its FullForm, which is then taken as a string, so that we can simply use a regular expression to replace everything that starts with a dollar sign, before converting it back to an expression.