swig / swig

SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages.
http://www.swig.org
Other
5.78k stars 1.24k forks source link

The R support is strange #854

Open ivannp opened 7 years ago

ivannp commented 7 years ago

Hello,

My feeling is that swig's R support is strange. I am wondering whether it needs a re-work. Here are my arguments:

  1. R has multiple class systems: S3,S4,R6. Swig is using S4, to implement something like R6. That's strange. Most likely S3 would suffice. But if using S4, then I would think that instead of: circle$area(), swig should generate code to use: area(circle). Looks more R-ish to me. Or, if the former syntax is preferred, then, why not use R6 to begin with?

  2. The function dispatching, when there are several versions, is done in R (not in C). Python does it in C (passing all args as tuple), and there are advantages to that. If it is done in C, using typemaps, one can "translate" certain SEXP arguments, like something we know is a numeric vector, to any type. I don't think this is possible to achieve with the type checking done in R. Furthermore, the current series of if-statements in R, check either for scalar types, or for SWIG types. In other words, let's say I have a C function which takes a class as it first argument:

void SomeFunction(Dimensions dims)

Dimensions includes a std::vector and adds a few methods. How can I instruct swig to generate R&C code, which accepts R numeric vector (or integer) and via the *.i file to add a small fragment to convert the SEXP to Dimensions? I don't think that's possible. All the type-checking is done in R, so if we simply pass a numeric vector - we get an error.

wsfulton commented 7 years ago

@joequant ... as the resident R SWIG expert, if these suggestions from @ivannp make sense, can you comment as perhaps @ivannp is able to help with a new implementation. As we would like to release swig-3.1 next year, maybe a radical change in R wrappers can go into this major release.

joequant commented 7 years ago

Yes. The R wrapper was done organically, so a lot of it involved just getting something that works. The reason that it doesn't use R6 is that R6 didn't exist when the wrapper was first written.

I'd be game for a major overhaul. If we can put together a wish list, that would be wonderful. I think moving this onto R6 would be a high priority.

ivannp commented 7 years ago

My experience so far with swig is that the general approach for R is solid. I would have gone the same path - using mostly S4. And it's necessary at some places - I don't think R6 has anything special about operator overloading.

My wish list (biased, based on projects I have looked) is:

  1. Get basic std:: types (vector, string, shared_ptr, etc) working as easy in R as in Python. Allowing easy mapping between R vectors (like c(1,2,3)) and C++ vectors for instance.
  2. Use S4 in more R-ish way. This means adding generic methods (setGeneric) and implementations for all methods (setMethod).
  3. Get garbage collection working. As a minimum, provide a solution which people can use via *.i files, if full support is too much.
  4. Operator support - R has a smaller subset than C++, but I guess that's true for other bindings too?

Starting with 1. might help answering whether a more intrusive change is necessary (moving the function-dispatch to C, for instance, or to R6 classes altogether). Thoughts?

Should we continue here, or is there a different forum for similar discussion?

bradbell commented 7 years ago

I have a swig application that uses std::vector where Type is an operator overloaded type (supporting the normal numeric operators +, -, *, /). Perhaps it would be good to have a list of completed swig features and a priority list for future features. Perhaps these lists already exist ?

chuanwen commented 7 years ago

Here is my biased wishlist:

  1. Use R6
  2. Usage of the tool is as easy as that of Rcpp
richardbeare commented 6 years ago

Hi, I'm putting together some plans to begin addressing general R issues, so send any new impressions/thoughts if this is still of interest. I'm not intending to address the R6 issue yet, as I think it is too big, but I hope the initial work will restructure the internals enough to make tackling the R6 idea feasible. Many of the issues that arise in the R module appear to be caused by not using the internal swig mechanisms in the right places, and that is what I hope to address first.

On R6 - I think it is the right way to go for C++ class libraries, and the code that swig currently generates is set up to appear to the user a lot like R6.

We already have automatic mapping between std::vectors of numeric types and R vectors, and some list support. Would like to add dictionaries.

Garbage collection works for classes returned via constructors.

ojwb commented 2 years ago

Still to be done.