Re: problem writing debugging utility function

*To*: mathgroup at smc.vnet.net*Subject*: [mg100273] Re: [mg100248] problem writing debugging utility function*From*: Leonid Shifrin <lshifr at gmail.com>*Date*: Sun, 31 May 2009 06:30:53 -0400 (EDT)*References*: <200905300057.UAA23426@smc.vnet.net>

Hi, the way to do it is to use non-standard evaluation. Here is the function that probably does what you want In[1] = SetAttributes[ShowIt, HoldAll]; ShowIt[code_] := Module[{y}, Print[ToString[Unevaluated[code]], " = ", y = code]; y]; This will print the variable name, its value, and then return the variable value itself so that you can use it in your code, just as before - you just need to "stick" ShowIt in the place where you need to print the info. The parameter of the function does not necessarily have to be a variable - you can wrap it around any piece of code (there could be a few subtleties if your code also uses non-standard evaluation, but this is rarely the case). Note that we take care that the code (<code>) is executed only once, so the case of side effects (like i++ etc) is handled correctly. Example: In[2] = Block[{i, res = Table[0, {5}]}, For[i = 1, i <= 5, i++, res[[i]] = ShowIt[i]]; res] i = 1 i = 2 i = 3 i = 4 i = 5 Out[2] = {1,2,3,4,5} >But it's worth >noting that this would trivial to solve with a Lisp macro, and despite >the fantastic expressibility of Mathematica it doesn't seem to have a >good replacement for macros. This is just not true. The ShowIt function above *is* a macro, since, due to the HoldAll attribute, it expands the code before it is run. As another very simple macro example, consider this: ClearAll[withCodeAfter]; SetAttributes[withCodeAfter,HoldRest]; withCodeAfter[before_,after_]:=(after;before); This macro can be used to avoid an introduciton of auxilliary variable in case when the result is computed somewhere in the middle of the code (by the <before> piece), but when some other code must be executed (<after> piece), before the result is returned. Example: In[3] = Clear[i]; i = 0; withCodeAfter[Print[i], i++] 0 In[4] = i Out[4] = 1 The availability of macros in Mathematica is apparent from the fact that all the code we write is data as well (as can be seen by the FullForm command), and the availability of non-standard evaluation. This fact is obscured by the built-in pretty-printer/preprocessor which allows us to use shortcut and infix notation. However indeed there are a few reasons that make macros harder to write in Mathematica: a) Evaluator is more complex, than in Lisp. There are several kinds of global rules, there are attributes, there are several ways to make evaluation non-standard, there are built-in rules for system functions that the user may not be aware of, there is dynamic scoping with Block that is very powerful but can be easily abused, there are several lexical scoping constructs (Module, With, Function, SetDelayed, etc) and associated with them rules for variable collision resolution, etc, etc. It is harder to "compute" the consequences of the macro expansion, or to get it right in all cases of intended use. b) Pattern-matching gets in the way when some portion of the code is rule-based, since evaluation depends on whether or not some patterns match. c) This is a consequence of b): when we define a function with restricted patterns such as f[x_Integer]:=... etc, we effectively introduce a (weak) typing, which also gets in the way. d) It requires conscious effort not to use (at all) short-hand and/or infix notation, which is handy but often hides that the code may expressed as an expansion of some macro. I think it will generally be very nice if macros would find their way into the mainstream Mathematica programming, but this will probably start to really pay off for those who intend to use Mathematica to build rather large/complex systems (or their prototypes). Best regards, Leonid On Fri, May 29, 2009 at 5:57 PM, dabrowsa at indiana.edu <dabrowsa at indiana.edu>wrote: > This matter is pretty unimportant, but perhaps of interest in laying > out a persistent source confusion for me with Mathematica: evaluation > control. > > I'm skeptical of the built-in debugger because it seems to crash the > kernel often, so I do most of my debugging by inserting print > statements like > > Print["variableOne = ",variableOne]. > > Being extraordinarily lazy I soon thought it might be nice to have a > little function, say dbgv, which takes a variable or name of a > variable as an argument, and produces the same result as the print > statement above. > > At first I assumed this would be easy, since almost every programming > problem turns out to be pretty easy with Mathematica. But after an hour > or so I began to wonder whether it would be possible at all. I did > eventually find a solution, a function dbgv such that dbgv[variableOne] > produces exactly the effect of the print statement, but it's really ugly. > I'll post it later. > > Granted this is not an important problem since it's not too much > trouble to just type in the whole print statement. But it's worth > noting that this would trivial to solve with a Lisp macro, and despite > the fantastic expressibility of Mathematica it doesn't seem to have a > good replacement for macros. The closest equivalents are $Pre(Read), > which I used in my solution, but they're not nearly as nice to work with. > > Can anyone think of an elegant solution? > >

**References**:**problem writing debugging utility function***From:*"dabrowsa@indiana.edu" <dabrowsa@indiana.edu>