What embedded language would you implement in Zig projects?

There is also roc, maybe ? https://roc-lang.org/

I wouldn’t consider Roc an embeded language. It uses platforms, which is a different concept. It’s designed to have the main runtime be in Roc.

2 Likes

I’ve never heard of Wren before, but it looks like an interesting language to
use. I write things in Rust more often which led me to check if there was a
maintained library on crates.io to seemingly the two most popular versions
being unmaintained for at least five years. There is a Zig library that
implements Wren but it’s eight months old and the library has probably changed
a lot since then.

In the meantime, I think Lua is probably the best I’m getting.

2 Likes

This looks really cool! I’d love to try this when I get the chance. I’ve always
had personal gripes about error handling in Lua (pcall is not a favourite of
mine), and to see a language with Zig-style error handling is a treat for me.
Moreover, it being natively written in Zig and not dependent on whatever C is
up to sounds good too.

Hope you are enjoying writing the examples and documentation as much as you did
writing the language itself. Currently, I don’t know enough Zig to help out
with understanding how to use the library but I hope that can change sooner or
later. Again, good job on getting Ray that far!

2 Likes

I have seen this before, although I didn’t know it could be embedded. I should
look more into Roc, looks familiar to other functional languages like Haskell,
Elixir, and OCaml. I’m a really big fan of OCaml’s pattern matching, and I have
enjoyed the few times I’ve used Haskell and Elixir so I might end up enjoying
this too. I’ll just have to hope I can embed it :).

Thanks :slight_smile: I’d like to work more on it because a lot is still missing but I’ll post about it when I’ll consider it more or less ready!

1 Like

Yes my first introduction to language development was indeed Lox
When calling C functions, you have to use a Lua’ style function table that uses the call frame because there is no reflection.
Regarding calling Zig functions, I map Zig types to Ray types and create a custom caller for each functions registered and them call them with @call() and manage the arguments with a custom std.meta.ArgsTuple.

Considering performance, I didn’t see major differences.

I am at the point where I wonder if I should go down the rabbit hole of adding enforced type hints etc

All of this is only possible thanks to static typing though

2 Likes

I must say I’m not very familiar with Roc - just read a few things about it when they rewrote their compiler in Zig.

With that said, I hae the impression that one could write a program in zig and expose an API through a platform. Would that count as embedded? Or is it that the main thread would be handled by Roc, hence delegating your zig as the one being embedded in Roc? I guess it’s a matter of who is calling who…

I really want to learn more about Guile (and Guix in general). I’d like to try to bridge Zig and Guile.

I have implemented zmpl templates. Also quickjs in zig.

If we are being liberal with the term “embedded”, then one could say that Roc is embedded. And one could write their platform in such a way that it “embeds” Roc.
Roc is in a weird middle ground. I personally wouldn’t consider it an embedded language like Lua et. al. because it doesn’t run 3rd party code at all. So you can’t write a Roc “script” that is distributed and loaded at runtime. This is different from Lua, Wren, etc. You also can’t reload the Roc part. You would have to recompile the binary.

Roc does have a symbiotic relationship with it’s host language (i.e. Zig, Rust) in that the platform/host provides functions for interacting with the outside world. The main thread is handled by Roc. Code execution will jump back and forth between the roc compiled code and the host compiled code. This is all put together in one binary. There is no runtime loading (unless you are loading shared libraries or specifically loading dlls or something like that in the host.