I need to implement some external callbacks to R and I'm not happy with the current REPL, since it prevents any general solution. Are there plans to improve the current REPL anytime soon? The current approach has some deficiencies you are surely aware of (only one input (=external event loop), the loop is blocked while waiting for input in R_ReadConsole, ...). But the major problem is that several packages/modules simply replace the standard REPL with their own implementations by not returning control to the loop. This virtually prevents any cooperation - it is impossible to load two such modules at a time without breaking something. I think that something along the lines of a "light" REventLoop (i.e. just the loop management where modules can register their handlers, w/o the "demo" loops) would be very helpful. What makes me wonder is that even quite recent code again just replaces the REPL (simply never returns back while duplicating the functionality) or uses other tricks. So, are there plans to replace the current REPL soon? (preferably in 1.8 ;)). If not, what are the reasons? Another related question is why shouldn't we use threads for external event loops? Most current GUIs are multi-threaded anyway. This wouldn't affect R directly. I have something like this in mind: - external hander registers and gets an ID R main loop: { - wait for mutex A to be signaled (with an ID) - call signaler's handler function and perform REP if required - release the mutex A } each external loop runs in a separate thread thus not affecting R (R can be computing anything in the meantime). once it needs to do something in R (e.g. user typed a line), it locks the mutex and signals a condition on the mutex which results in action taken in the main R REPL. the above approach makes sure that R (and anything jumping into R) still remains single-threaded, but allows arbitrary event loops to run as multiple threads in parallel. afaik all current OSes have threads support (we could provide single-threaded REPL as fallback for those who don't) and the above is fairly easy to implement in pthreads (and compatible) as well as Windows. I'm willing to provide code for the latter approach or to help with the first one if necessary. Cheers, Simon --- Simon Urbanek Department of computer oriented statistics and data analysis University of Augsburg Universit?tsstr. 14 86135 Augsburg Germany Tel: +49-821-598-2236 Fax: +49-821-598-2200 Simon.Urbanek@Math.Uni-Augsburg.de http://simon.urbanek.info
Simon Urbanek <Simon.Urbanek@math.uni-augsburg.de> writes:> I think that something along the lines of a "light" REventLoop (i.e. > just the loop management where modules can register their handlers, > w/o the "demo" loops) would be very helpful. What makes me wonder is > that even quite recent code again just replaces the REPL (simply never > returns back while duplicating the functionality) or uses other > tricks. So, are there plans to replace the current REPL soon? > (preferably in 1.8 ;)). If not, what are the reasons?The main reason is that we can't seem to get it right... It would be a very welcome thing to have in R-2.0 (Planned: Apr.2004) in some form or another. Or 1.8 if you can just send us the perfect solution by next week, for all platforms, please ;) ;) [I'm not quite sure what you're pointing to with the "quite recent code" remark. Could you be more specific?] One particular issue that has come up again recently is that people want to run REPL loops on connections (e.g. sockets). With the current implementation, we can't handle incomplete input, and the only easy fix would be to buffer up and reparse from start of expression at every end of line, as we currently do on std. input. We could (I think) fairly easily have a parser that could continue across line endings, but we can't multiplex two of them. I.e., receiving "c(" on a socket blocks the command line, and/or having the "+" prompt on the console stops the socket processing. This appears inevitable as long as we use single-threading and use a parser that works using a single C call. Changing either might make it work - you could potentially replace yyparse() with a state-machine manipulator (e.g. bison can be set to generate a set of parse tables), but multithreading seems much more straightforward. -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907