[Rd] .doTrace problem with eval.parent(substitute(expr)) vs. lazy evaluation of expr

From: William Dunlap <wdunlap_at_tibco.com>
Date: Fri, 12 Jun 2009 16:15:50 -0700


Here are a couple of problems with the use of eval.parent(substitute(expr))
instead of just lazily evaluating expr in the .doTrace function used by trace.

(a) In S+ I sometimes use trace() to see how long a function takes to run with a tracer expression the saves the start time and calls on.exit to report the difference between the start and end times when the trace function ends. E.g.,

> trace(unix, Quote({START<-proc.time();on.exit(cat(command, "took", proc.time()-START, "\n"))}))
> unix("sleep 4") # like R's system()
On entry: sleep 4 took 0 0 4.02000000000001 0 0.01 character(0)

This trick fails in R (2.10.0 svn 48672):

> trace(system, Quote({START<-proc.time();on.exit(cat(command,
"took", proc.time()-START, "\n"))}))

   Tracing function "system" in package "base"    [1] "system"
> system("sleep 4")

   Tracing system("sleep 4") on entry
   sleep 4 took 0 0 0 0 0
   [4 second pause before the next prompt]

If I change .doTrace by changing its

        exprObj <- substitute(expr)
        eval.parent(exprObj)
to just
        expr # evaluate in caller's environment by lazy evaluation
then the on.exit works as I wished it to. I think the on.exit clause is being executed at the end of eval.parent() instead of at the end of the caller of .doTrace (put print(sys.calls()) into the on.exit to see the evidence).

(b) Another thing I'm used to doing with trace() in S+ is to selectively expand some of the arguments of the traced function (so I can see its value instead of just its name), as in

> trace(match,

Quote({CALL<-match.call();CALL$x<-paste(class(x),"(",length(x),")",sep=" ");print(CALL)}))

> for(x in list(factor(letters), 1:2, "c"))match(x,c("c","d","e"))

   On entry: match(x = "character(26)", table = exclude)
   On entry: match(x = "character(26)", table = levels)
   On entry: match(x = "factor(26)", table = c("c", "d", "e"))
   On entry: match(x = "character(26)", table = table, nomatch =
nomatch, incomparables =
           incomparables)

   On entry: match(x = "integer(2)", table = c("c", "d", "e"))    On entry: match(x = "character(1)", table = c("c", "d", "e")) This fails in R

> for(x in list(factor(letters), 1:2, "c"))match(x,c("c","d","e"))
   Tracing match(x, table, nomatch = 0L) on entry    Error in match.call() :
     unable to find a closure from within which 'match.call' was called until I make that change to .doTrace

> for(x in list(factor(letters), 1:2, "c"))match(x,c("c","d","e"))
   Tracing match(x, table, nomatch = 0L) on entry    match(x = "character(1)", table = table, nomatch = 0L)    Tracing match(levels, exclude) on entry

   match(x = "character(26)", table = exclude)
   Tracing match(x, levels) on entry
   match(x = "character(26)", table = levels)
   Tracing match(x, c("c", "d", "e")) on entry
   match(x = "factor(26)", table = c("c", "d", "e"))
   Tracing match(x, c("c", "d", "e")) on entry
   match(x = "integer(2)", table = c("c", "d", "e"))    Tracing match(x, c("c", "d", "e")) on entry    match(x = "character(1)", table = c("c", "d", "e"))

Would there be any harm in making this change to .doTrace?

I can avoid the on.exit problem by using both the tracer and exit arguments to
trace:

> trace(system, Quote(START<-proc.time()), exit=Quote(cat(command,
"took", proc.time()-START, "\n")))

   Tracing function "system" in package "base"    [1] "system"
> system("sleep 4")

   Tracing system("sleep 4") on entry
   Tracing system("sleep 4") on exit
   sleep 4 took 0.001 0.002 4.018 0.002 0.002 but I do miss the ability of the tracer to use match.call().

Are there other properties lost by using eval.parent(substitute(expr)) instead lazily evaluating expr? Should eval.parent(substitute(expr)) try to mimic more closely the lazy evaluation of expr?

The patch I used for testing was
Index: src/library/base/R/methodsSupport.R


Bill Dunlap
TIBCO Software Inc - Spotfire Division
wdunlap tibco.com



R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Fri 12 Jun 2009 - 23:28:00 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Sat 13 Jun 2009 - 11:35:43 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.

list of date sections of archive