Stream: beginners

Topic: Example for using as a embedded language.


view this post on Zulip swoorup joshi (May 04 2025 at 10:59):

I would like to use ROC as an embedded language in both web and desktop targets (wasmtime?) under sandbox environments. The scripting language has to export functions which will then be called by host. Is this possible? What is a good example to follow? (My host language is Rust). Or is this not a good usecase for roc?

view this post on Zulip Anton (May 05 2025 at 09:23):

Hi @swoorup joshi,
This is our wasm example. Unfortunately we made a mistake in testing it, so it silently broke, see also #7756. @Brendan Hansknecht @Luke Boswell do you know what happened to the glue.zig file required by web-assembly-platform/host.zig?

view this post on Zulip Anton (May 05 2025 at 09:39):

This roc wasm project may still work though

view this post on Zulip swoorup joshi (May 05 2025 at 09:40):

hmm, is there an example for rust? I am not familiar with zig :sweat_smile:. I am also wondering if it is somehow possible to embed the compiler into the host language.

view this post on Zulip swoorup joshi (May 05 2025 at 09:41):

I saw some old chats about using it with other host like bevy, but it was quite a while back. I am unsure if roc is still suitable for such embedded usecase?

view this post on Zulip Anton (May 05 2025 at 10:22):

hmm, is there an example for rust?
embed the compiler into the host language.

The wasm repl may be the example you want, it's available for use here. This is a nice image of how it works.

view this post on Zulip swoorup joshi (May 05 2025 at 11:25):

Interesting, I'll take a look.

view this post on Zulip Luke Boswell (May 05 2025 at 22:59):

Here's an example of using Roc for the front-end https://github.com/niclas-ahden/joy

view this post on Zulip Luke Boswell (May 05 2025 at 22:59):

I believe @Niclas Ahden is using this currently.

view this post on Zulip Luke Boswell (May 05 2025 at 23:00):

The story will be much nicer in future with the new zig compiler I think, as there's a few workarounds and challenges to do this using the current rust compiler design.

view this post on Zulip Anton (May 06 2025 at 09:03):

Oh interesting, I didn't know joy was using wasm.

view this post on Zulip swoorup joshi (May 06 2025 at 14:23):

I hope it will still be easier with Rust. :stuck_out_tongue_wink:

Luke Boswell said:

The story will be much nicer in future with the new zig compiler I think, as there's a few workarounds and challenges to do this using the current rust compiler design.

view this post on Zulip swoorup joshi (May 06 2025 at 15:01):

Unrelated, does zig compile to C or is able to directly compile to native code or wasm. I see some reference to c code, not sure what they are meant for.

view this post on Zulip Brendan Hansknecht (May 06 2025 at 15:08):

It can do all 3

view this post on Zulip Brendan Hansknecht (May 06 2025 at 15:08):

To c, native, and wasm

view this post on Zulip Brendan Hansknecht (May 06 2025 at 15:08):

To c is pretty rare, but is used as part of the zig compiler bootstrapping, so it is well tested.

view this post on Zulip swoorup joshi (May 06 2025 at 17:25):

thanks, still playing around with examples, One thing isn't clear to me. Can roc compiler be itself be embedded as a wasm binary? So that it compiles roc files into other wasm files? So the compiler can be called from either browser directly or via wasmtime.

view this post on Zulip Anton (May 06 2025 at 17:29):

compiler be itself be embedded as a wasm binary? So that it compiles roc files into other wasm files?

Yes, I believe that is how the wasm repl works.

view this post on Zulip swoorup joshi (May 06 2025 at 17:31):

Oh right, that makes sense. Somehow looking at the architecture image I was thinking it was compiled on the server. (Still lot to digest)

view this post on Zulip Anton (May 06 2025 at 17:31):

The wasm repl archive may be useful to clarify things:
roc_repl_wasm.tar.gz

view this post on Zulip Anton (May 06 2025 at 17:32):

thinking it was compiled on the server.

No, it's all wasm and a bit of js

view this post on Zulip swoorup joshi (May 06 2025 at 17:42):

I think I need a index.html file to load those wasm files as well?

view this post on Zulip Anton (May 06 2025 at 17:47):

Yes, that archive is not standalone, see:

https://github.com/roc-lang/roc/blob/main/www/public/site.js
view-source:https://www.roc-lang.org/repl
https://github.com/roc-lang/roc/blob/c320a1bca567b5bcafa8f31f472120b6b5977e0b/www/content/repl/index.md

The build procure is described in https://github.com/roc-lang/roc/blob/c320a1bca567b5bcafa8f31f472120b6b5977e0b/crates/repl_wasm/README.md and https://github.com/roc-lang/roc/blob/c320a1bca567b5bcafa8f31f472120b6b5977e0b/www/README.md (builds the full roc website).

view this post on Zulip swoorup joshi (May 06 2025 at 18:09):

Thank you, does roc has any guidelines for interoping with rust types like algebraic data types? enums?
https://flinect.com/blog/rust-wasm-with-typescript-serde

view this post on Zulip Anton (May 06 2025 at 18:16):

We commonly refer to that interop code as glue.
We have a command to generate it but that generated code requires some manual fixing up. joy code probably provides the best guidance for you.

view this post on Zulip Luke Boswell (May 06 2025 at 22:58):

swoorup joshi said:

I hope it will still be easier with Rust. :stuck_out_tongue_wink:

Luke Boswell said:

The story will be much nicer in future with the new zig compiler I think, as there's a few workarounds and challenges to do this using the current rust compiler design.

I don't mean building the platform in Rust (as compared to Zig) .. but the new compiler that is being re-written in Zig (as opposed to the current one that is written in Rust).

:D

view this post on Zulip swoorup joshi (May 07 2025 at 15:59):

Tried building repl_wasm from main branch. Got errors building :/

error: failed to run custom build command for `roc_bitcode v0.0.1 (/Users/swoorup.joshi/github/roc-programming/roc/crates/compiler/builtins/bitcode)`

Caused by:
  process didn't exit successfully: `/Users/swoorup.joshi/github/roc-programming/roc/target/release/build/roc_bitcode-1b9319928098b482/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=build.rs
  Compiling zig object `object` to: /Users/swoorup.joshi/github/roc-programming/roc/crates/compiler/builtins/bitcode/zig-out/builtins-host.o

  --- stderr
  An internal compiler expectation was broken.
  This is definitely a compiler bug.
  Please file an issue here: <https://github.com/roc-lang/roc/issues/new/choose>
  zig build object -Drelease=true failed 10 times in a row. The following error is unlikely to be a flaky error: object
  +- install generated to builtins-host.o
     +- zig build-obj builtins-host ReleaseFast native-macos 5 errors
  src/main.zig:385:13: error: expected pointer type, found 'fn (dec.RocDec) callconv(.c) i128'
      @export(func, .{ .name = "roc_builtins." ++ func_name, .linkage = .strong });
              ^~~~
  src/main.zig:400:20: note: called from here
      exportBuiltinFn(func, "dec." ++ func_name);

view this post on Zulip Anton (May 07 2025 at 16:08):

Did you use nix develop to set up the dependencies?

view this post on Zulip swoorup joshi (May 07 2025 at 16:09):

Now trying to use nix develop, previously was using directly from system install zig and rust.

view this post on Zulip Anton (May 07 2025 at 16:11):

Yeah, your error seems to come from a wrong zig version. It's best to use nix develop because you need more than just zig and rust.

view this post on Zulip swoorup joshi (May 07 2025 at 16:13):

Looks like its compiling.

Although Kinda prefer devenv to nix develop, because that's all I used before, and doesn't drop me to bash from my fish shell. :sweat_smile:

view this post on Zulip swoorup joshi (May 07 2025 at 16:15):

nvm, looks like I just use fish from the bash shell

view this post on Zulip Anton (May 07 2025 at 16:22):

This is actually the first time I heard about devenv, it looks interesting :eyes:

view this post on Zulip swoorup joshi (May 07 2025 at 16:26):

its built atop of nix, and think covers most of the develop use-cases with extra few bells and whistles.

view this post on Zulip swoorup joshi (May 07 2025 at 17:52):

Does roc support WIT https://component-model.bytecodealliance.org/design/wit.html#enums by any chance?

view this post on Zulip Anton (May 07 2025 at 17:57):

I've never heard of WIT before, If anyone knows, it's @Brian Carroll

view this post on Zulip swoorup joshi (May 07 2025 at 17:58):

I was following along with how zed created their extension model in this blog https://zed.dev/blog/zed-decoded-extensions and came across it. Having a common IDL would make life so much easier.

view this post on Zulip Brian Carroll (May 07 2025 at 21:16):

Hey Anton! We never did anything for WIT and I'm not super familiar with it. Looking at the link, I think you could write a "Roc glue" plugin for it if you wanted to. That would make the most sense.

view this post on Zulip Hannes (May 07 2025 at 23:26):

By the way @swoorup joshi, if you want to use your existing shell with a nix flake you can use direnv and optionally add nix-direnv. Then, in the repo, run direnv allow and it'll add the devshell packages to your current shell.

view this post on Zulip swoorup joshi (May 08 2025 at 16:30):

hello again, I am starting to get a feel and play with roc code, and trying to basically get the repl_wasm running using wasmtime instead of js

But I am currently running into a crash, which I am not sure how to address.

view this post on Zulip swoorup joshi (May 08 2025 at 16:31):

I replace all js runner/functions with WastimeApp like so: https://github.com/Swoorup/roc-wasm-playground/blob/main/src/wasm_runner.rs

Running it gives

Enter an expression to evaluate, or a definition (like x = 1) to use later.

  - ctrl-v + ctrl-j makes a newline
  - :q quits
  - :help shows this text again
>
thread 'main' panicked at library/core/src/panicking.rs:226:5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`

This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/27d6200a70601f6fcf419bf2f9e37989f3624ca4/library/std/src/panicking.rs:697:5
   1: core::panicking::panic_nounwind_fmt::runtime
             at /rustc/27d6200a70601f6fcf419bf2f9e37989f3624ca4/library/core/src/panicking.rs:117:22
   2: core::panicking::panic_nounwind_fmt
             at /rustc/27d6200a70601f6fcf419bf2f9e37989f3624ca4/library/core/src/intrinsics/mod.rs:3196:9
   3: core::panicking::panic_nounwind
             at /rustc/27d6200a70601f6fcf419bf2f9e37989f3624ca4/library/core/src/panicking.rs:226:5
   4: core::slice::raw::from_raw_parts::precondition_check
             at /Users/swoorup.joshi/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ub_checks.rs:68:21
   5: core::slice::raw::from_raw_parts
             at /Users/swoorup.joshi/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ub_checks.rs:75:17
   6: roc_serialize::bytes::deserialize_slice
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/compiler/serialize/src/bytes.rs:35:26
   7: roc_can::abilities::serialize::deserialize_solved_implementations
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/compiler/can/src/abilities.rs:1197:35
   8: roc_can::module::TypeState::deserialize
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/compiler/can/src/module.rs:1212:13
   9: roc_load::deserialize_help
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/compiler/load/src/lib.rs:240:28
  10: roc_load::read_cached_types
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/compiler/load/src/lib.rs:265:39
  11: roc_load::load
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/compiler/load/src/lib.rs:37:24
  12: roc_load::load_and_monomorphize_from_str
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/compiler/load/src/lib.rs:117:11
  13: roc_repl_eval::gen::compile_to_mono
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/repl_eval/src/gen.rs:64:18
  14: roc_repl_ui::repl_state::ReplState::step
             at /Users/swoorup.joshi/.cargo/git/checkouts/roc-5d067ed4e211e472/b552466/crates/repl_ui/src/repl_state.rs:260:36
  15: test_roc_playground::repl::entrypoint_from_wasmtime::{{closure}}::{{closure}}
             at ./src/repl.rs:201:9
  16: std::thread::local::LocalKey<T>::try_with
             at /Users/swoorup.joshi/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:315:12
  17: std::thread::local::LocalKey<T>::with
             at /Users/swoorup.joshi/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:279:15
  18: test_roc_playground::repl::entrypoint_from_wasmtime::{{closure}}
             at ./src/repl.rs:199:18
  19: test_roc_playground::stdin_runner::stdin_to_entrypoint::{{closure}}
             at ./src/stdin_runner.rs:60:62
  20: test_roc_playground::main::{{closure}}
             at ./src/main.rs:44:65
  21: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /Users/swoorup.joshi/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/future.rs:124:9
  22: tokio::runtime::park::CachedParkThread::block_on::{{closure}}
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/park.rs:284:60
  23: tokio::task::coop::with_budget
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/task/coop/mod.rs:167:5
  24: tokio::task::coop::budget
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/task/coop/mod.rs:133:5
  25: tokio::runtime::park::CachedParkThread::block_on
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/park.rs:284:31
  26: tokio::runtime::context::blocking::BlockingRegionGuard::block_on
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/context/blocking.rs:66:9
  27: tokio::runtime::scheduler::multi_thread::MultiThread::block_on::{{closure}}
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/scheduler/multi_thread/mod.rs:87:13
  28: tokio::runtime::context::runtime::enter_runtime
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/context/runtime.rs:65:16
  29: tokio::runtime::scheduler::multi_thread::MultiThread::block_on
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/scheduler/multi_thread/mod.rs:86:9
  30: tokio::runtime::runtime::Runtime::block_on_inner
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/runtime.rs:358:45
  31: tokio::runtime::runtime::Runtime::block_on
             at /Users/swoorup.joshi/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.45.0/src/runtime/runtime.rs:328:13
  32: test_roc_playground::main
             at ./src/main.rs:40:5
  33: core::ops::function::FnOnce::call_once
             at /Users/swoorup.joshi/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread caused non-unwinding panic. aborting.
fish: Job 1, 'echo 1 + 1 | RUST_BACKTRACE=1 c…' terminated by signal SIGABRT (Abort)

view this post on Zulip swoorup joshi (May 08 2025 at 16:31):

Any ideas?

view this post on Zulip Brendan Hansknecht (May 08 2025 at 16:36):

My only guess is that wasm has a different alignment to CPUs. As such, this fails. I would try just running without the undefined behaviour check (might just need to run in release build).

view this post on Zulip Brendan Hansknecht (May 08 2025 at 16:36):

But otherwise debugging probably means checking pointers and alignment.

view this post on Zulip Brendan Hansknecht (May 08 2025 at 16:36):

I wonder if wasmtime aligns differently from browsers

view this post on Zulip swoorup joshi (May 08 2025 at 16:38):

Goodpoint, will try running in release. Trying to grok much information as I can, since i am new to using wasm in general xD

view this post on Zulip swoorup joshi (May 08 2025 at 16:43):

Damn that worked lol. Feels cool.

test-roc-playground on  main [!] is 📦 v0.1.0 via 🦀 v1.88.0-nightly via ❄️  impure (devenv-shell-env) took 4s
❯ ./target/release/test-roc-playground --stdin
>

Enter an expression to evaluate, or a definition (like x = 1) to use later.

  - ctrl-v + ctrl-j makes a newline
  - :q quits
  - :help shows this text again

> 1 + 1

2<span class='color-green'> : </span>Num *
>

Last updated: Jul 26 2025 at 12:14 UTC