On Saturday, 7 December 2013 at 17:08:49 UTC, Joseph Rushton
Wakeling wrote:
On 06/12/13 03:16, bachmeier wrote:
I have been using R and D together for several months. It is
easy to embed
either inside the other. Unfortunately I have not found the
time to write up any
decent notes about it. With the latest release of DMD, my
workflow is to create
shared libraries with D and call them from R. Using the .C
interface from R is
simple, but not much fun. I wrote up a few notes here:
http://lancebachmeier.com/wiki/doku.php?id=rlang:calling-d
That's very cool, and also something of a relief to see, as I
think interfacing nicely with R is an essential feature for a
programming language in some domains of research.
What I've been working on lately is a .Call-based interface
that provides some
of the same convenience as Rcpp. I call into Gretl's C API to
get a wide range
of econometric functions. It works well enough that I'm going
to give a lecture
to my graduate students on calling D functions from R next
week.
To embed R inside D, which is maybe more what you're after, I
created a simple C
interface to RInside. That works well. Unfortunately I don't
have notes on that
either.
I'll be happy to share more if any of this will help you.
I think that you would be doing everyone a big favour if you
would provide a good writeup on this. Can I also suggest
making a talk proposal to DConf 2014 about this work?
I will write something up as soon as I can, but it might be a
while before that happens. I will also share my code for the
.Call interface. Hopefully I will get feedback from someone more
knowledgeable about D.
I'll leave DConf to the experts. I'm an economist who taught
himself to program.
Question: I remember a colleague who had worked on linking a C
library into R telling me that he'd had to make copies of data
before passing into R, because R expects variables to be
immutable. Is there anything that you can do with D's support
for immutability that lets you avoid this? Or are you
constrained by the fact that you need to use an extern(C) API?
Your colleague might well be right, but I'm not familiar with
that issue. In the other direction (R to C) you want to copy the
data before mutating. Suppose you have
x <- c(1,2,3)
y <- x
.Call("foo", y)
R does a lazy copy of x into y, such that y is a pointer to x
until the copy is actually needed. In this example, when you pass
y from R to C, all you're passing is a pointer to the struct
(SEXP). On the C side, you can do anything you want with that
pointer, and it will modify both y and x unless you make a copy
of y.
You can create an SEXP on the C side and pass it into R, but
that's a bit clumsy so I avoid it. Whether I'm embedding R in
C/C++/D or vice versa I do the allocation in R. Moving data
between R and D is nothing more than passing a pointer around.