Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enum code generation #913

Closed
romainfrancois opened this issue Oct 12, 2018 · 9 comments
Closed

enum code generation #913

romainfrancois opened this issue Oct 12, 2018 · 9 comments

Comments

@romainfrancois
Copy link
Contributor

Currently working with enums from some c++ code base is cumbersome and requires writing error prone boiler plate code in the R side, something like https://github.com/apache/arrow/blob/master/r/R/enums.R

enum <- function(class, ..., .list = list(...)){
  structure(
    .list,
    class = c(class, "arrow-enum")
  )
}
FileMode <- enum("arrow::io::FileMode",
  READ = 0L, WRITE = 1L, READWRITE = 2L
)

Would be useful to have some code, perhaps as part of attributes that would scan the c++ code, e.g. https://github.com/apache/arrow/blob/c9ac8696a335f4e818c7356d9af77317150e94ce/cpp/src/arrow/io/interfaces.h#L36

struct FileMode {
  enum type { READ, WRITE, READWRITE };
};

background: apache/arrow#2714 (comment)

@wesm
Copy link

wesm commented Oct 12, 2018

I think it would even be fine for Rcpp to generate constants like FileMode_READ. Even if this requires extra typing by the developer (rather than something more complicated like parsing headers) that is better than having hard-coded values which may break.

E.g. we declare constants in Cython to make the enum values available, but their representation is opaque:

https://github.com/apache/arrow/blob/master/python/pyarrow/includes/libarrow.pxd#L35

@eddelbuettel
Copy link
Member

Early morning here so maybe I am even slower than usual -- but what is it that are proposing?. Namespace-scoped variables on the R side that map enums? Presumably as immutable constants? Any suggestion about how to go about it? R doesn't really have the notion of a constant...

@romainfrancois
Copy link
Contributor Author

Ideally the enum would be able to travel to the C++ functions so that we they can be used as Rcpp::export functions, in and out.

There is limited support for this on the c++ side with a macro, but not on the R side where you essentially have to manually re create them.

@eddelbuettel
Copy link
Member

So you are thinking of R side facilities to create enums on the C++ side? Ie extending Attributes to generate something?

I was most often driven by the other side (and held back by the lack of support): I wanted what already exists in C++ (as enums) to be identifiers in R. Ie QuantLib has a ton of them, starting with simple ones like enumeration of the months etc. We have nothing for that either.

@romainfrancois
Copy link
Contributor Author

That’s the same use case.

We have c++ enums in some headers that we interface, and want to get a handle on them at the r side.

Having them in a list with an S3 class and the $ method on that list emitting something that has a class allowing it to be recognized on the c++ side, via inout parameter etc ...

@eddelbuettel
Copy link
Member

Right on. I have a feeling you and even talked about such use cases many moons ago.

@wesm
Copy link

wesm commented Oct 14, 2018

Ideally the enum values should not leak to the R bindings. So if instead of using 0, 1, 2 for the enum values, you used 10, 20, 30, you would not want to see those details duplicated anywhere. In Python what we are doing is generating variables that use whatever value is declared in the C++ header:

https://github.com/apache/arrow/blob/master/python/pyarrow/lib.pyx#L61

Type_NA = _Type_NA

So here _Type_NA dealiases to the C++ symbol arrow::Type::NA, which is promoted to a Python integer object by Cython

@alexkyllo
Copy link

I stumbled upon this thread as I'm assessing effort needed to write R bindings for the Z3 Theorem Prover

Their approach with python bindings was to write a python script to read through the C++ headers, find all the enum members, and generate another python file declaring them as constants. This outputs a python file with hundreds of lines like this:

# Automatically generated file

# enum Z3_lbool
Z3_L_FALSE = -1
Z3_L_UNDEF = 0
Z3_L_TRUE = 1

# enum Z3_symbol_kind
Z3_INT_SYMBOL = 0
Z3_STRING_SYMBOL = 1

# enum Z3_parameter_kind
Z3_PARAMETER_INT = 0
Z3_PARAMETER_DOUBLE = 1
Z3_PARAMETER_RATIONAL = 2
Z3_PARAMETER_SYMBOL = 3
Z3_PARAMETER_SORT = 4
Z3_PARAMETER_AST = 5
Z3_PARAMETER_FUNC_DECL = 6

I'll probably need to generate R code using the same approach for now--but in the future if Rcpp could provide a better way to do this, that would be awesome!

@github-actions
Copy link

This issue is stale (365 days without activity) and will be closed in 31 days unless new activity is seen. Please feel free to re-open it is still a concern, possibly with additional data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants