Stream: beginners

Topic: Can Roc be executed from a Rust host app?


view this post on Zulip Ari Seyhun (Sep 20 2024 at 05:07):

I'm looking at using Roc as a kind of replacement for Lua. However I see its a compiled language rather than scripting language, so I guess I could compile it to wasm and run it from Rust.

If I assumed things correctly, I have a few questions:

view this post on Zulip Luke Boswell (Sep 20 2024 at 05:53):

It's not super easy right now, but doable. There's a few things in development which make platform development more difficult than it will be in future.

I have a template https://github.com/lukewilliamboswell/roc-platform-template-wasi which does what you are looking for. It currently uses a build script using build.sh which you can see the steps manually. We have some WIP PR's which should unlock more WASI/WASM type workflows but that hasn't landed yet.

view this post on Zulip Luke Boswell (Sep 20 2024 at 05:56):

Would I just use Wasmtime to execute the Roc script? Or is there a better way to do so without even compiling Roc to wasm?

You can make a custom roc platform that compiles your roc app/script/plugin to WASM/WASI, and then load that an run it using something like wasmtime.

view this post on Zulip Luke Boswell (Sep 20 2024 at 05:59):

If it is compiled to wasm, how would I share data between Roc and my host Rust app? I could use Json or something of course, but is there any other approaches similar to wasm bindgen?

The example template I shared above is using zig for the (roc platform) host language. If you use rust then you can use wasm bindgen to simplify data across the WASM boundary

view this post on Zulip Luke Boswell (Sep 20 2024 at 06:00):

It can be difficult to talk about this idea specifically because there are multiple layers and terms that are overloaded, like the roc platform has a host and the wasm runtime is also a host... so it can get confusing.

view this post on Zulip Luke Boswell (Sep 20 2024 at 06:03):

Would I just use Wasmtime to execute the Roc script? Or is there a better way to do so without even compiling Roc to wasm?

The other option which is much simpler is to use roc in what I think of as a plugin. Have your rust app compile the roc source to a dynamic library (using roc as a library "libroc" by pointing cargo at the compiler repository, or even just shelling out using std::process::Command) and then load the library at runtime to run the roc app.

view this post on Zulip Luke Boswell (Sep 20 2024 at 06:05):

This is what roc does internally with the roc glue subcommand, where the end user provides a glue script and the roc cli compiles and then runs that to generate the glue files.

view this post on Zulip Luke Boswell (Sep 20 2024 at 07:27):

I had a crack at doing this to make an example and see what is involved.

https://github.com/lukewilliamboswell/roc-plugin-experiment-rust

I got pretty far, it builds and runs fine... but there is something not quite right as it doesn't look like roc is running when I call it, or at least it doesn't appear to be modifying the input at all.

I'm hoping @Brendan Hansknecht or @Folkert de Vries or someone can see my problem as it's probably something simple I'm missing I think.

view this post on Zulip Luke Boswell (Sep 20 2024 at 07:30):

One hunch I have is that I'm providing an implementation of roc_alloc and friends to satisfy roc_std which is linked in at build time and then the host also provides an implementation of roc_alloc for linking with the script... and maybe these two need to be the same implementation. :man_shrugging:

view this post on Zulip Ari Seyhun (Sep 20 2024 at 10:28):

This is awesome, thank you for the detailed response Luke!

Since what I'm building is a little more than just a side project, I'll probably have to stick with a simpler approach for now until Roc has some more stability and documentation for this kind of thing. But I'll still check out the GH repos you linked thanks for taking the time for that

view this post on Zulip Luke Boswell (Sep 20 2024 at 11:18):

Ok, I got carried away (and Folkert helped to) and now it works :tada:

https://github.com/lukewilliamboswell/roc-plugin-experiment-rust

Definitely one of the coolest experiments I've put together in a little while.

I can see how this could be easily expanded to more complicated platforms with a Task based API etc.

view this post on Zulip Luke Boswell (Sep 20 2024 at 11:19):

I haven't tested this on linux, but tried to use some cfg flags so hopefully it should just work.

view this post on Zulip Luke Boswell (Sep 20 2024 at 11:22):

In the end I had everything setup correctly but we have a bug where the codegen isn't correct for

mainForHost : U64 -> Str
mainForHost = main

But is for

mainForHost : U64 -> Str
mainForHost = \x -> main x

:smiley:


Last updated: Jul 06 2025 at 12:14 UTC