Compiling and loading NIFs on runtime

I tried out Rustler and it is amazing when I need to define NIFs at the compile time.

I’m experimenting with a use case where it would be useful to define a NIF at a run time.

Imagine being in an IEx shell where you are able to define a function at the runtime and use it right after.

I wonder how I could do something similar for nifs. Let’s imagine that I have the following Rust code that I want to compile and load at the runtime of BEAM

  fn add(a: i64, b: i64) -> i64 {
    a + b
  }

and use it like

defmodule AdditionWithRust do
  def add(a, b), do
     add_function = """
     fn add(a: i64, b: i64) -> i64 {
       a + b
     }
    """

    RustOnRuntime.apply(add_function, a, b)
end
"""

Where RustOnRuntime is a fictional module that does some magic.

I would copy paste this to IEx and I would be able to use the function normally.

It’s OK to assume I have a fixed number of Rust libraries that are defined at the compile time, and only those library functions can be used, no new can be loaded.

I suppose this is quite a complex question. I suppose that at the bottom of it there is probably a question if it is even possible to compile and load erlang nifs (of any kind not just Rust) at the run time…

Any pointers what things to consider or where to start would be much appreciated.

I’m not a Rust fan - prefer C++ - but I’ll tell you what I know. If you update the shared library, and the NIF supports reloading (see ERL_NIF_INIT), then there is no reason that you shouldn’t be able to update your NIF whenever you want with new functionality. Updating the shared library for my setup is as easy as just running gmake in the right directory.

Imagine being in an IEx shell where you are able to define a function at the runtime and use it right after.

Yeah, this is what I should be doing, but I haven’t set the appropriate reload functions. Still, though my development cycle is pretty close - edit the c++ code in one window, then restart iex in another (which compiles my nif via gmake) and then run my test at the iex command line.

BTW I proposed a dedicated Nif subforum here but couldn’t get any momentum so my plan is to maintain some pages of Nif-related resources somewhere else, either github or my own site.

4 Likes

That’s a great pointer @arcadian, thanks! I’ll look into ERL_NIF_INIT. Your answer also helped me find the Rust equivalent.

1 Like

That would be great :slight_smile:

1 Like