Skip to content

step by step debugger in R?

7 messages · Romain Francois, Robert Gentleman, Simon Urbanek

#
[moving this to r-devel]
Robert Gentleman wrote:
Sure. What I have in mind is something that gets __automatically__ 
called, similar to the task callback but happening right before the user 
is given the browser prompt.
Thanks. I'll have another look into that.

  
    
#
Hi,
  I stripped the cc's as I believe that all read this list.
Romain Francois wrote:
I am trying to understand the scenario you have in mind. Is it that the user is
running R directly and your debugger is essentially a helper function that gets
updated etc as R runs?

 If so, then I don't think that works very well and given the constraints we
have with R I don't think it will be able to solve many of the problems that an
IDE should.  The hook you want will give you some functionality, but no where
near enough.

 Let me suggest instead that the IDE should be running the show. It should
initialize an instance of R, but it controls all communication and hence
controls what is rendered on the client side.  If that is what you mean by
embedding R, then yes that is what is needed. There is no way that I can see to
support most of the things that IDE type debuggers support without the IDE
controlling the communication with R.

 And if I am wrong about what your debugger will look like please let me know.

 best wishes
   Robert

  
    
#
Robert Gentleman wrote:
yes. there are now several ui toolkits that could be use to give some 
sort of graphical representation of what is being debugged.

I agree with you that and IDE should command R and not the other way 
around, but I am not (yet) here talking about a fully featured IDE, but 
simply a debugger.

I need to read more about embedding R (as in section 8 of WRE). I know 
you can supply your own implementation of the REPL, but I am not sure 
this includes the one that goes on once trapped into the browser. For 
example littler ships its own REPL, but this does not seem to fool/deal 
with browser:

$ r -e "print(1:10); browser(); print(1:5) "
 [1]  1  2  3  4  5  6  7  8  9 10
Called from: NULL
c
 [1]  1  2  3  4  5

Not sure this is an omission of Jeffrey and Dirk or something else.
In the long run, I do agree. In the short run, I'd prefer taking the bus 
to the airport rather than walk.

  
    
1 day later
#
On May 24, 2009, at 10:18 AM, Romain Francois wrote:

            
Yes - it would be quite useless otherwise ;)  there are many examples  
of GUIs that use it (including the built-in ones [Windows, MAc, ..] or  
external ones e.g JGR).

Cheers,
S
#
Simon Urbanek wrote:
Hi Simon,

Do you mean the rReadConsole callback ? I managed to make some minor 
modifications to the rtest.java example that comes with JRI to somewhat 
emulate automatically call some code (ls.str()) in this example at the 
browser prompt, before giving the prompt to the user.

    static boolean browse_first = true ;  
      public String rReadConsole(Rengine re, String prompt, int 
addToHistory) {
        System.out.print(prompt);
                if( prompt.startsWith( "Browse[") ){
                        if( browse_first ){
                            System.out.println( "\n>>>> re.eval( \" 
print( ls.str() )\" ); " ) ;
                            re.eval( "print( ls.str() )" ) ;
                            browse_first = false ;
                            System.out.println( "\n>>>> return 
\"ls.str()\"" ) ;
                            return "ls.str()\n" ;
                        } else{
                            browse_first = true ;
                        }
                       
                }
...
}

It seems to work and could get me somewhere, although it has a "it 
works, but it does not feel right" taste. Basically the code pretends 
the user typed "ls.str\n" at the browse prompt, so that the R evaluator 
evaluates it, and then comes back to the browse prompt.

There is also the re.eval( "print( ls.str() )" ) part which was my first 
attempt, but apparently this gets evaluated in the global environment, 
which is no good. I can get around that by returning some sort of 
"record the sys.frames and sys.calls somewhere and do something with 
them" function, but I was wondering if you meant something else.

Romain

Here is the transcript of a simple session of ./run rtest (with the 
small adjustement above)

 > f <- function( x= 5) browser()
rBusy(1)
rBusy(0)
 > f()
rBusy(1)
Called from: f()
rBusy(0)
Browse[1]>
 >>>> re.eval( " print( ls.str() )" );
a :  chr "hello"
b : 'data.frame':    3 obs. of  2 variables:
 $ a: num  1.2 2.3 4.5
 $ b: num  1.4 2.6 4.2
bool :  logi [1:3] TRUE FALSE FALSE
f : function (x = 5) 
iris : 'data.frame':    150 obs. of  5 variables:
 $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
 $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
 $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
 $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
 $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 
1 1 1 1 1 ...

 >>>> return "ls.str()"
rBusy(1)
x :  num 5
rBusy(0)
Browse[1]>
rBusy(0)
 >
#
On May 25, 2009, at 4:54 PM, Romain Francois wrote:

            
Well, it's entirely up to you - the REPL is working. I wasn't  
suggesting you have to use JRI for the debugger, I was just pointing  
out that browsing is treated as a regular prompt on the REPL, so any  
embedding has access to it.
The JRI eval() command has nothing to do with this directly - you can  
evaluate in any environment, just not specifying anything will throw  
you in the global environment - it's really up to you (it just  
abstracts out the direct access to parse and eval part of R - you can  
(ab)use it any way you see fit).

Cheers,
Simon
#
Simon Urbanek wrote:
Thank you for these comments. It confirms what I was thinking.
I understand that. It was the quickest way for me to get an example 
going. java/JRI is one option, but there are others (Qt, ...)
... and I surely will.

Romain