Skip to content

R bridge replacement#271

Draft
AndrewIOM wants to merge 21 commits intofslaborg:masterfrom
AndrewIOM:r-bridge-replacement
Draft

R bridge replacement#271
AndrewIOM wants to merge 21 commits intofslaborg:masterfrom
AndrewIOM:r-bridge-replacement

Conversation

@AndrewIOM
Copy link
Copy Markdown
Collaborator

@AndrewIOM AndrewIOM commented Apr 8, 2026

Proposed Changes

R.NET is not properly maintained and is a complex codebase that includes substantial overhead that is not required by RProvider. This draft PR utilises a far smaller, F# R interop layer (RBridge), which only implements the raw interop and structural elements required by RProvider. See #270

Types of changes

What types of changes does your code introduce to RProvider?
Put an x in the boxes that apply

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • Build and tests pass locally
  • I have added tests that prove my fix is effective or that my feature works (if appropriate)
  • I have added necessary documentation (if appropriate)

Further comments

In removing R.NET and replacing with the smaller bridge layer, I have made a clearer distinction between the raw native R C API and structural elements of the R language (which sit in RBridge and RBridge.Extensions), and placed a newer semantic layer into RProvider itself. This means we have full control over its form, operator overrides etc.

For the bridging layer, I have mostly been following the latest embedded R docs rather than referring to R.NET, which should help us to clear up some of the very old bugs.

Semantic types layer

I have introduced a new semantic types layer within RProvider, in the RTypes module. This includes scalars, vectors, data frames, and factors. The semantic types keep data in R memory and support mathematical operators.

Plugin system

I have removed the traditional plugin system, as in my opinion it no longer fits with current F# scripting practices, and was very brittle. Also, the Deedle plugin has been removed from Deedle, which was the main plugin that existed. The aim is to replace this with an explicit conversion system / registry, although the introduction of proper semantic types may reduce the need.

Dependencies

By slimming the R<->.NET conversion system and the bridge layer, most dependencies have been removed.

Status

I am currently focusing on adding tests. Core functions work correctly (packages, eval, function calls, conversion / extraction to and from R).

NB Currently untested on Windows.

Smaller changes made as part of conversion process

  • bindingInfo in R interop switched to use SEXP types rather than R typeof(get(..)) execution.
  • Introduced RTypes in Runtime, for wrapping of semantic R types.
  • Removed old plugin system. As an alternative, implemented FsSci shapes on RTypes, so that R numeric types are interoperable with F# types. This doesn't allow implicit conversion between R frames and Deedle for example, but does allow use of R data frames in F# stats functions that support the common numerics shapes.
  • getBindings and other core API functions actually now properly use R environments / namespaces; this was not implemented before (in RInterop).
  • Refactored 'call' within Runtime to use the namespace of the package to retrieve the symbol for the required function, then call it directly. Drops support for tuple-based named arguments.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant