I wrote Rust bindings for Julia. If you're interested in calling Julia from Rust, please have a look and tell me what you think

Note: this topic’s contents are a copy of the original post on the Rust subreddit.

After quite some effort I’m finally ready to release first version of jlrs, the Julia bindings I’ve been working on for the past few weeks.

This first version brings many nice features. For example:

  • Primitive data and strings can be copied from Rust to Julia.

  • N-dimensional arrays containing primitive data can be created; their contents can either be completely managed by Julia, take ownership of data from Rust, or mutably borrow data from Rust.

  • All of these can be copied back from Julia to Rust.

  • You can acquire handles to arbitrary modules, globals and functions, and call the latter.

  • You can include and call your own Julia code.

  • If a Julia function returns another function, you can call it.

  • You can only use Julia data that is guaranteed to be protected from garbage collection.

Of course, not everything is great yet. Some of it is due to limitations of Julia itself: access to the runtime is single-threaded, for example, and that thread will block when it’s calling Julia code; you can’t simply “pause” a long-running computation to quickly do some smaller amounts of work. Thread support in Julia itself is still in an experimental phase. Most annoyingly, the documentation is not available on docs.rs at this time because the bindings can’t be compiled. If anyone could help me fix that or point me in the right direction, your help would be greatly appreciated (and yes, my failed attempts to fix it are the reason several version have been released already… sorry about that).

Luckily, the readme in the Github repository should provide enough details to build this crate, cargo doc will work if you’re able to build it.

You probably shouldn’t use this crate to do many one-off or short-and-simple computations; in the first case, the fact that Julia code is JIT-compiled will bite you, in the latter the overhead of this crate will. Rather, you should use it to call sufficiently complex functions that you will call regularly, or to use functionality that’s not available in Rust yet.

Another possible use case is one that actually motivated me to keep writing this. I work as (mostly) a software engineer in vision and robotics, a recurring task is to convert some specific algorithm written in Python to C++ for both performance reasons and so we can integrate it into the software that actually powers the products we sell. This is an error-prone process (rewriting software always is), takes a lot of time, and you now have two versions of some code to maintain. If I were able to just call the “original” code with great performance, we’d be rid of the split codebase and save a lot of time and money in the process.