What does HackerNews think of zigler?

zig nifs in elixir

Language: Elixir

I admit for a long time this was my primary motivation to learn Rust, but, sadly, I haven't come across problems in years that were CPU bound/where I needed something like Rust... Rustler still looks like a great fit if needed, but, depending on the use case, if I were CPU bound and needed to write my own code/not just use a Rust library, I'd be as or more likely to look at using Zig and Zigler[0], for much faster learning curve, and from what I've read, easier tighter integration into elixir, including I think language server integration. Some discussion here[1] though I forget if I listened to this one or not.

[0]https://github.com/ityonemo/zigler [1]https://podcast.thinkingelixir.com/83

That looks great, it's a pet peeve of mine that it's difficult to format languages that are encased in another language. Most (all?) editors are only expecting a single "language" in a file. You have a js file? Must contain only JavaScript!

Unrelated to 1.13 but thanks to the release notes, I now know about Zigler; which looks really neat.

https://github.com/ityonemo/zigler

No separation between header and code, structs are better than records (because they bear their data labels when you inspect them, even if you send to another node that doesn't recognize them), and also since elixir requires that the tags are modules, you can use them for polymorphism (this is the best of OOP without OOP).

Much better documentation support, better compile time infrastructure, smart metaprogramming (this package would be a PITA in erlang: https://github.com/ityonemo/zigler), opinionated but optional directory organization. Module namespaces which are trivially subdivided and aliased, easier time making anonymous GenServers. The Task module, full stop. The registry module, as well.

You can also write Elixir/BEAM NIF extensions in Nim and Zig as well using Nimler or Zigler, resp [1,2]. Also I’ve found writing native extensions for the BEAM is simpler than many other dynamic languages since it relies on immutable data. It’s roughly the same as just a function to deserialize/serialize data with some extra references to GC’ed data. Especially with dirty “NIF”s (they allow the functions to run for as long as they want without messing up the BEAM scheduler).

1: https://github.com/wltsmrz/nimler 2: https://github.com/ityonemo/zigler

Working on a major refactor of my elixir FFI interface for the Zig programming language. Lets you write zig inline in elixir, and takes care of all of the fiddly bits around setting up a nif correctly, in such a way that you can't mess it up.

https://github.com/ityonemo/zigler/

By the end of the refactor, an additional setting will be included that makes the beam vm "garbage collect" your zig for you, that is, you can lazily allocate memory in your nif, and it will be cleaned up for you afterwards. This is a major first step in making "safe nifs" which are OTP-supervised OS threads with, at least, memory resource recovery performed by a BEAM process if the thread happens to crash.

Also, why use zig over rust? because zig is aggresively unopinionated about its memory allocation, so Zigler makes it easy to use the internal BEAM allocator, which 1) lets the BEAM be aware of allocations that are happening for observability and telemetry purposes, 2) lets your memory allocations play nice with the BEAM's fragmentation preferences and 3) leads to potentiallly better performance as you can make fewer trips to the kernel for allocations.

haha ok so this is going to be complicated.

1) A bit about what I'm doing with zig. I am working on an FFI interface between elixir and zig, with the intent to let you write zig code inline in elixir and have it work correctly (it does). https://github.com/ityonemo/zigler/. Arguably with zigler it's currently easier to FFI a C library than it is with C (I'm planning on making it even more easy; see example in readme).

2) The specific not-in-master-branch feature I'm working on now is running your zig code in a branched-off thread. Fun fact about the erlang VM: if you run native code it can cause the scheduler to get out of whack if the code runs too long. You can run it in a "dirty FFI" but your system restricts how many of these you can run at any given time. A better choice is to spawn a new OS thread, but that requires a lot of boilerplate to do and it's probably easy to get wrong. Making it also be a comprehensive part of erlang's monitoring and resource safety system is also challenging, and so there's a lot to do to keep it in line with Zigler's philosophy of making correctness simple.

3) Zig does have its own, opinionated way of doing concurrency. I honestly find it to be a bit confusing, but it's new (as of 6 months) and is not well documented. I believe the design constraints of this are guided by "not having red/blue functions", "being able to write concurrent library code that is safe to run on nonthreaded/nonthreadable systems"

4) The native zig way of doing concurrency is incompatible with exporting to a C ABI (without a shim layer) so I prefer not to use it anyways.

5) Zig ships with std.thread. I believe it's in the stdlib and not the language because some systems will not support threading. But since I'm writing something that is intended to bind into the erlang VM (BEAM), it's probably on a system that supports threading. Also I believe that std.thread will seamlessly pick either pthreads or not-pthreads based on the build target, which makes cross-compiling easy.

6) So yes, figuring this all out is not easy (zig is young, docs are not mature), but once you figure out what you're supposed to do, the actual code itself is a breeze, this is the code that I use to pack information to connect the beam to linux thread and launch it: https://github.com/ityonemo/zigler/blob/async/lib/zigler/lon.... I really hope the docs come with guides that will make this easy in the near future.

not as interesting or as world-changing as many of the other problems here, but it scratches that 'language itch' for me: I'm building an interop bridge between Elixir and Zig that makes calling Zig from Elixir safe, elegant, easy, and comprehensible:

https://github.com/ityonemo/zigler/

On my plate currently: Figure out how to make a long-running zig function run in an OS thread alongside the BEAM so that it doesn't have to be dirty-scheduled.

if that combination is interesting to you, this is what I'm working on (on the side from my main job):

https://github.com/ityonemo/zigler

if I may do a bit of self-promotion, even though zig is not ready for prod (yet) I'm writing a nif system for zig that will make that whole process dead-easy.

https://github.com/ityonemo/zigler