[Rd] debuggingState() analogous to tracingState() ?
Richard M. Heiberger
rmh at temple.edu
Thu Oct 2 17:55:49 CEST 2014
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
<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