Just FYI: the 'debug' package lets you set a stop-before-exit, and of course the ability to adjust breakpoints while the function is running. You can get the current return value via 'get.retval()'.
There is some rough-edged support for debugging scripts, too. Mark Mark Bravington CSIRO CMIS Marine Lab Hobart Australia ________________________________________ From: r-devel-boun...@r-project.org [r-devel-boun...@r-project.org] on behalf of Richard M. Heiberger [r...@temple.edu] Sent: 03 October 2014 01:55 To: Martin Maechler Cc: ESS-core; r-devel; jonathan.mcpherson.jonat...@rstudio.com Subject: Re: [Rd] debuggingState() analogous to tracingState() ? Interesting timing. I could have used this additional control yesterday in class. I am teaching a graduate Statistical Computing class. Last night I went through the symbolic deriviatives (the deriv and D functions) in Section 9.6 of the Blue Book. The D function is recursive. I illustrated its behavior with debug(D) and then studied the statement D(expression(x^2+4), "x") At each step the console displays the entire switch() statement. And inside ESS the entire switch statement in the derivative.R buffer is highlighted. That is too much redundancy. I would like to have the .R buffer highlighted and maybe a truncated version of the statement displayed in the *R* (console) buffer. I am thinking of a trunctation similar to what C-c C-c in ESS does when it sends over a function definition. Somewhere around the third or fourth level of recursion I would truncate it even further. When investigating 3*x^2 + 4*x^5 It would be nice to see the detail of several levels of recursion for the 3*x^2 term and turn off the debug/trace behavior of the 4*x^5 term, with the debug/trace beahvior automatically coming back on when the two terms are merged. I discovered I would like an additional stop during debug. Here is a simple function to illustrate. simple <- function(x) { y <- x + x 2*y } debug stops before the 'y <- x+x 'and again before the '2*y' is evaluated and I can do regular browser investigations. When I hit enter, I want it to stop again after 2*y has been evaluated and before it returns to the console. I would like to investigate the result and then go back and investigate the intermediate variables with the result in view. Obviously I can redefine my own function to redesignedsimple <- function(x) { y <- x + x z <- 2*y z } but doing that to a function inside a NAMESPACE is very difficult to get right. Rich On Thu, Oct 2, 2014 at 10:55 AM, Martin Maechler <maech...@stat.math.ethz.ch> wrote: > We have had some conversation within R core, > lead by Duncan Murdoch and me, about a proposal > to extend the current tracingState() functionality > by something tentatively called debuggingState(). > > Duncan has allowed me to copy the previous conversation > (after very minor editing): > > The following is quite technical and assumes you know more about > R's debug()ing and trace()ing than an estimated 99.9% of the R users: > >>>>>> Duncan Murdoch <murdoch.dun...@gmail.com> >>>>>> on Thu, 2 Oct 2014 07:19:34 -0400 writes: > > > On 02/10/2014, 6:36 AM, Martin Maechler wrote: > >>>>>>> Duncan Murdoch <murdoch.dun...@gmail.com> > >>>>>>> on Thu, 2 Oct 2014 05:41:00 -0400 writes: > >> > >> > On 02/10/2014, 5:17 AM, Martin Maechler wrote: > >> >>>>>>> Martin Maechler <maech...@stat.math.ethz.ch> > >> >>>>>>> on Sat, 27 Sep 2014 22:55:21 +0200 writes: > >> >> > >> >> > It would be really nice to temporarily disable debugging similar to > >> >> > tracingState() being able to turn of trace()ing. > >> >> > >> >> > In eval.c the corresponding C code would be used as the > tracingState() > >> >> > analogue is used. > >> >> > >> >> > [...........] > >> >> > ??? > >> >> > >> >> It seems to work ok, the few cases I've tried. > >> >> > >> >> I wonder a bit about the R / C interface. > >> >> Using an extra function debuggingState() seems a bit of a > >> >> waste, and I was thinking of enhancing > >> >> tracingState() from a 1-argument to a 2-argument form. > >> >> > >> >> something like > >> >> > >> >> tracingState <- function(on = NULL, debug = on) > >> >> .Internal(traceOnOff(on, debug)) > >> >> > >> >> but I don't see how to keep usages such as > >> >> > >> >> on <- tracingState(FALSE) # turn it off QUICKLY (via a > .Internal) > >> >> if(on) { > >> >> on.exit(tracingState(TRUE)) # restore on exit, keep off during > trace > >> >> ............ > >> >> } > >> >> > >> >> working back compatibly. > >> >> > >> >> We could think of tracingState() only returning length one when > >> >> called with one argument, and returning length two when called > >> >> with a second argument... but that seems messy. > >> >> > >> >> If nobody has a better idea, I'd commit a new debuggingState() > >> >> function which is very much "parallel" to tracingState(). > >> > >> > It's hard to comment on this, because I don't know exactly what > >> > behaviour is controlled by the debugging flag. > >> > >> Good point. The flag, accessed via RDEBUG(.), is used in quite a few > places, > >> and the intent and my experiments have replaced > >> > >> RDEBUG(.) > >> by RDEBUG(.) && R_current_debug_state() > >> > >> in some places, but not in most places. > >> > >> > Will it cause an > >> > explicit call to browser() to be a no-op, or does it just control breaks > >> > triggered by entry into a function that has been marked by debug()? > >> > >> What would you want? Probably the latter, right? > >> With my use case below, however, I could argue I'd even want browser() > >> to be a no-op in that case. It is not so important to me. > >> > >> > What is the effect of a call to a function marked with debugOnce()? > >> > >> Good question. Here my code was such that the function would also > >> not have been debugged. > >> But of course, that is open for "debate", and I am glad you've > >> started / continued the discussion. > >> > >> My main use case for > >> debuggingState(FALSE) > >> > >> would be when I want to call some R function that "just runs > >> through" and gives me its result, even though the user may have > >> added the debug flag to a very basic R function which is called > >> by my R function. > >> > >> Given these question, you could start arguing we'd want more > >> than just TRUE or FALSE for debugging state, > >> just so one could apply differing behaviour in the above cases. > > > Or the alternative: expand the use of the tracingState() flag to affect > > RDEBUG as well. > > Indeed. If we additionally want to remain backcompatible, I think, > we'd need to add new values in addition to {TRUE, FALSE} (and > NULL for input). > > E.g., --- making up something to be improved --- > using bit patterns which when added give an integer "tracing+debugging-state" > > 1 : tracing-turned-off > 2 : debugging turned off, allowing browser() and debugonce() > 4 : making browser() a no-op > 8 : making debugonce() a no-op > > and hence 1+2+4+8 = 15 turns off all "browsing/debugging" > for which I'd typically want a convenient short cut. > > for back compatibility, > FALSE = 1 > TRUE = 0 > > I'd use UI with a vector of character strings, that can be > translated to integer codes entirely analogous to > .deparseOpts() {used from deparse(), dput() and dump()}. > > ----- > > A considerably simpler interface which would be good enough for > my use, was to simply add a new debuggingState() function with > TRUE/FALSE option, and we would just have to decide how much > "turning off debugging" should happen when the state is set to FALSE. > In that case, I would still like the ability (on the level of R) > to simultaneously turn off debugging and tracing and turn them > back on as easily. So I'd consider setting up debuggingState() > in a way that it can simultaneously turn off and on both tracing > and debugging. > > > I don't have much of an opinion on these questions. I've never used the > > tracingState() function, though I use trace() all the time (via > > setBreakpoint()). You might want to consult people who write debugger > > front-ends. > > which I am now doing: I'm including ESS-core, > Jonathan (RStudio) and Tobias (StatET) which Duncan mentioned as > being interested and having asked for better debugging support > functionality in the past, such as > > > the ability to add a breakpoint to a function that is > > currently being evaluated. > > So, after quite a bit of musing, we are grateful for your > thoughtful comments on this > (and yes: I am fan of "keep it simple!" and "small is beautiful!" > also inside R's code base). > > Martin Maechler, > ETH Zurich > > _______________________________________________ > ESS-core list: https://stat.ethz.ch/mailman/listinfo/ess-core ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel