[Rd] debuggingState() analogous to tracingState() ?
Duncan Murdoch
murdoch.duncan at gmail.com
Thu Oct 2 18:07:59 CEST 2014
On 02/10/2014 11:55 AM, Richard M. Heiberger wrote:
> 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.
You can add on.exit(browser()) to do that, or use the exit option of
trace(). The new (R-devel only) function returnValue() will tell you
what is about to be returned. In the current release, the return value
isn't available at that point.
Duncan Murdoch
> 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
> <maechler at 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.duncan at 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.duncan at gmail.com>
> > >>>>>>> on Thu, 2 Oct 2014 05:41:00 -0400 writes:
> > >>
> > >> > On 02/10/2014, 5:17 AM, Martin Maechler wrote:
> > >> >>>>>>> Martin Maechler <maechler at 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
More information about the R-devel
mailing list