On Mon, 6 Jul 2009, Riccardo (Jack) Lucchetti wrote:
On Mon, 6 Jul 2009, Allin Cottrell wrote:
> I've committed a few more changes to the gretl Rlib code. You can
> now (if you're set up right) call native R functions directly, as
> scalar c = choose(10,4)
> That is, "choose" is recognized as an R function and (thanks to
> Christoph) is called via libR.
> At present this works only if the function arguments and return
> value are either scalars or matrices. That could be extended
> somewhat if we find this valuable.
Wow! This is absolutely fantastic! However, this is big, very
big. I have the feeling that we need to think this over very
carefully, for at least two reasons:
Yes, agreed on both counts.
(a) what happens in case of a name clash? ...
Yes, indeed. I've been thinking about that too. The first point
to make is that trying to interpret a "word" as an R function name
is the "last resort" in genlex.c. So any built-in, or
user-defined, gretl function will mask an R function of the same
Perhaps we may wrap R function calls in an ad-hoc function, like
scalar c = R("choose(10,4)")
My first thought on this is to the same effect but a little
simpler: we could mark off R functions (either built-in, or
defined via "foreign" blocks within gretl) by using the prefix
"R_". So if you wanted to invoke the R "choose" function you'd
have to invoke it as "R_choose(args)". (Internally, we'd see the
"R_" and pass the remainder of the word to the new function
This would reliably avert clashes with gretl built-in functions
since gretl uses lower-case identifiers exclusively -- and I don't
envisage changing that since I hate mixed-case function names!
It does mean that if someone defines a user function "R_foo" it
will mask any "foo" function that may exist in R, but that doesn't
seems like a big problem to me -- particularly if the manual
mentions this point.
(b) are there portability problems?
Yes, it does raise a portability issue. We do have some of those
already: for example, the gretl command "mpols" will work only if
gretl is linked against (the optional) libgmp. There's also the
business of the optional third-party programs TRAMO/SEATS and
X-12-ARIMA. At present the functionality of these programs is
available only via the GUI, but it probably should be available
There are some other issues too.
libR is not an "ordinary" library: by plugging into its API you
basically "buy into" an R session. And this can be quite lumpy.
R seems to make liberal use of the evil "longjmp" function (C's
non-local goto -- and you thought that "goto" was bad!). So, for
example, the innocuous-looking R function "findFun" crashes the
caller on failure. Similarly, a call to "Rf_initEmbeddedR" will
abort the caller if the environment is not set up correctly for R.
I've tried to guard against both of these issues in recent changes
in gretl_foreign.c, but I'm sure there are more.
In addition, if you run a gretl/Rlib session under valgrind
valgrind --tool=memcheck --leak-check=full --show-reachable=yes
you'll see that libR wants to allocate at least 10 MB before it
does _anything_. Christoph gave an example function, defined in
R, that took a scalar argument and returned its argument plus 1.
Fine, R will do that for you if you give it 10 MB of RAM and a
several dozen function calls. (OK, any library uses resources;
I'm just saying that the libR approach is not a magic bullet for
saving on initialization costs.)