[Rd] Emulating a REPL in frontends

From: Thomas Friedrichsmeier <thomas.friedrichsmeier_at_ruhr-uni-bochum.de>
Date: Thu 18 Jan 2007 - 12:47:40 GMT


A common need in R frontends is to provide some sort of read, (parse), evaluate, print loop. However, there are also a number of points where frontends may want to differ from the standard REPL as available e.g. in R_ReplDLLdo1().

First some thoughts on what is needed, and what is already there, or missing. If you want to skip over this, a short summary is provided in the second half, below a line marked "--------":

Read stage:
- R_ReplDLLdo1() calls ReadConsole to fetch an input buffer. This is not well
ideally for some situations. For example, the "Console", and the R process may be running on different machines. Or a frontend may provide several consoles or console-alikes working on the same workspace. Or the frontend may want to differentiate between "submitting code to the backend", and answering requests for input from read.line().

Parse stage:
- If (due to the above mentioned aspects, or for some other reason), a
frontend does not use R_ReplDLLdo1(), it will have to use R_ParseVector() for parsing. There's nothing wrong with that, except for the fact, that there does not seem to be a way to get at the full error message in case of a parse error, as parseError() is not exported.

Evaluate stage:
- Frontends may want to evaluate a sequence of statements at once, or one at a
time.
- A typical requirement of a frontend is for evaluation to be guaranteed to
return to the point of code it was called from.
- Both of this is available using R_tryEval().

Print stage:
- Frontends may want to always print the result of evaluation for some
statements, they may want to suppress printing entirely for some (internal) statement, but most importantly, they will probably want to auto-print values for most statements (i.e. print them if and only if R_Visible is TRUE).
- There does not seem to be a good way (from the C-API) to do auto-printing of
values outside of R_ReplDLLdo1(): R_Visible is not exported any longer, and PrintValueEnv() is neither. Rf_PrintValue() should yield the same results as PrintValueEnv() in most, but probably not all cases.
- From R API, withVisible() provides a way to emulate auto-printing, but with
the drawback that wrapping all statements inside withVisible() makes potential errors harder to read (you get something like "Error in eval.with.vis(x, parent.frame(), baseenv()) :", unless using extra magic to convert the Error magic back to "normal").

Other things done in R_ReplDLLdo1() / other REPLs:
- Frontends may want to set R_LastValueSymbol for most (statement entered by
the user directly), but not all statements (so as to keep .Last.value unchanged over internal operations like e.g. updating information on an object in an object browser)
- Frontends may want to call toplevel handlers after some statements, but not
after others (probably a similar distinction).


In summary, it seems like many frontends can not rely on R_ReplDLLdo1() (let alone running run_Rmainloop()), or at least not exclusively so. The alternative, using R_ParseVector() and R_tryEval() also has drawbacks, most importantly problems getting at parse errors, and auto-printing.

Two suggestions, which I hope are not too intrusive: 1) Make parseError() part of the public API. If there is a concern that the details of this function may change, a wrapper like the following should be good enough for most, if not all frontend purposes:

void Rf_parseErrorDefault()
{

        parseError(R_NilValue, 0);
}

2) Add a simple function to do auto-printing to the public API. E.g.:

Rboolean Rf_doAutoPrint(SEXP exp)
{

	if(R_Visible) {
	    printValueEnv(exp, R_GlobalEnv);
	    return TRUE;		/* was printed */
	}
	return FALSE;

}

Another suggestion, which might well be seen as adding too many constraints on future development, but provided for completeness: A more generic version of the EPL-part of R_ReplDLLDo1() with function parameters to determine, which steps are taken/omitted. I'm attaching a sketch of this. It is a copy with minimal modifications of the relevant code sections from R_ReplDLLdo1() and friends, which could then be simplified to use this function, internally.

Regards
Thomas Friedrichsmeier



R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Thu Jan 18 23:49:32 2007

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.1.8, at Thu 18 Jan 2007 - 14:31:02 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.