It is possible to write R extensions in Nim. Here is a rather useless example:
    
    
    type sexptype = cuint
    const realsxp = 14
    
    type sexp {.importc: "SEXP", header: "<Rinternals.h>".} = object
    
    proc protect(s: sexp): sexp
       {.importc: "PROTECT", header: "<Rinternals.h>".}
    
    proc unprotect(s: cint)
       {.importc: "UNPROTECT", header: "<Rinternals.h>".}
    
    proc allocVector(t: sexptype, n: cint): sexp
       {.importc: "allocVector", header: "<Rinternals.h>".}
    
    proc asReal(a: sexp): cdouble
       {.importc: "asReal", header: "<Rinternals.h>".}
    
    proc real(a: sexp): ptr cdouble
       {.importc: "REAL", header: "<Rinternals.h>".}
    
    proc add(a, b: sexp): sexp {.exportc, dynlib.} =
       result = protect(allocVector(realsxp, 1))
       real(result)[] = asReal(a)+asReal(b)
       unprotect(1)
    

On my Windows machine (with 64 bit R, 64 bit Nim 0.16.0 and whatever gcc comes 
with RBuildTools) I compile it like this:

`nim c -t:-m64 -l:-m64 -t:-I"C:/PROGRA~1/R/R-32~1.0/include" -t:-DNDEBUG 
-t:-I"d:/RCompile/r-compiling/local/local320/include" -t:-mtune=core2 
-l:-Ld:/RCompile/r-compiling/local/local320/lib/x64 
-l:-Ld:/RCompile/r-compiling/local/local320/lib 
-l:-LC:/PROGRA~1/R/R-32~1.0/bin/x64 -l:-lR --app:lib usewithR2.nim`

Then it can be used from R like this:
    
    
    dyn.load("usewithR2.dll")
    print(.Call("add", 1.5, 3.2))
    

And it prints [1] 4.7. So far so good. However, it can't be distributed easily. 
CRAN probably wouldn't accept a package that requires a working Nim compiler to 
be installed. Is it possible to generate a platform-independent (as in 
"Windows, Linux and OS X", not as in "every possible AVR microcontroller") C 
file that does not require anything related to Nim and can be compiled with R 
CMD SHLIB? I had no success with options like `--os:standalone`, but maybe I 
didn't use it correctly. I would appreciate your help.

Reply via email to