Zig for Scripting & PoC(& everything)?

Hello everyone,

I’ve just started learning Zig and have only gone through tutorials so far, without writing any serious code yet.

I’d like to ask for your thoughts on whether it’s a good idea to use Zig for casual, everyday scripting tasks or quick Proof-of-Concept (PoC) prototyping, similar to how one might use Python, TypeScript, or Clojure.

My main motivation for wanting to do this is the potential to smoothly evolve the codebase into a more serious application later on, without needing a major language rewrite. It seems like I could gradually improve performance and maintainability within the same language as the project grows.

(As a side note, I’ve read some articles suggesting that Rust, due to its focus on memory safety trade-offs, might not be as well-suited for rapid iteration and quick experimentation in areas like game development.)

I’ve always wished that I could do most things with just one programming language. While I understand the idea of using the right tool for the job, learning a programming language, depending on the level, is a significant time investment. Someone who wants to make games wants to focus on games, and someone doing scientific computing wants to focus on algorithms and efficiency, not languages. If one versatile language could cover various uses, it would free up time for other things. Ironically, despite thinking that, I’ve ended up studying most major programming languages anyway haha. Still, I would be happy if I could use Zig for as many purposes as possible in the future.

Given my goal of potentially evolving PoC code into production-ready code within the same language, and my desire for a versatile language, what are your thoughts and experiences on using Zig for scripting or rapid prototyping? What are the pros and cons from your perspective compared to languages like Python?

Any insights would be greatly appreciated!

1 Like

Welcome to ziggit!

This is an anti-goal of a PoC. A proof-of-concept is supposed to be completed in a short time. The purpose of the PoC is to help you better define your requirements and get a feel for what the sharp edges of the problem are going to be. You should feel empowered to completely re-write the PoC multiple times, in multiple languages, it will help you find the best solution to the problem.

For the first PoC, I would always choose the language you think will produce the PoC fastest.

So I would never choose to implement a PoC in a language that is new to me, unless my primary goal is personal development, and not necessarily making a boatload of money.

Now, if your goal is to learn systems programming and a deeper understanding of how computers work, I would recommend zig. Its is at least 10x less frustrating that C/C++ (primarily build system being easier to understand). That’s what zig has been for me, an excellent systems programming learning tool.

6 Likes

I think the language would work great for this. I am toying with idea of rewriting my scripts from Rust to Zig. Parsing arguments and shelling out in Zig works much simpler than in Rust:

VS

Two things stop me:

  • I don’t want to be on the hook for updating my scripts to be up-to-date with the language
  • While I don’t need any libraries right now, I want to have an option to pull a library to do whatever from crates.io

My main motivation for wanting to do this is the potential to smoothly evolve the codebase into a more serious application later on

This I think would work worse in Zig than even in Rust. Zig’s a manually memory managed language, so you’ll need to have an idea of who owns what, object lifecycles, etc. While you can get somewhere just allocating fresh objects left&right, not caring about memory leaks or an occasional UAF, my gut feeling is that evolving that kind of prototype into something serious would be a huge pain.

Though, I’d imagine this all depends on a specific domain. I can imagine an HTTP framework or a game engine that gives you certain basic resource discipline (an arena per request/frame), but allows for a rather lax coding standard afterwards.

My current rooster of languages:

  • Zig for serious stuff (TigerBeetle)
  • Rust for things I know I won’t enjoy actively maintaining in the future, and for everything else with uncertainty. Rust is the boring default choice for me, it excels only in one domain, high-performance stuff that has to deal with untrusted inputs, but it is at least mid for anything else. This makes it an excellent language to deal with uncertain future.
  • deno (TypeScript) for times when I want to save on typing&thinking, and I know that I won’t care about performance. This is mostly due to deno — single-binary formatter, type checker, dependency manager, file watcher, HTTP client&server, and task runner is excellent for just hacking on things. Although I must say I also enjoy the lightweight feeling of the type system.
7 Likes

how about no and yes? :slight_smile:

I started here (zig for all things) but found myself wishing, a lot, for things that zig isn’t going to do, because it’s not supposed to. This isn’t a zig problem, but a me problem.

my current benchmark for zig is - can a problem be solved with the std zig lib? If yes, does it require visibility, or clarity? If std lib + viability is important, then zig is a great fit.

I wouldn’t use zig to make a game - here, you can’t solve problems with std zig lib (yet), and you need clarity, not viability.

However, I would use zig, to compile custom shared objects that are included in content packs that my game uses. Say I make a game that features a level. A level might include a variety of Art and Design artifacts (shaders, textures, geometry, metadata, etc). If a level needs something unique, one option might be to use a scripting language to script those things.

Another option, with zig, would be to just code it, cross compile that code, and instead of running a script, the level just runs native code - windows, osx, linux.

I would do this because garbage collection in a script can really impair performance of a game, viability into what shared object is doing is super important - and zig is PERFECT for that.

1 Like

“It depends” :slight_smile:

If you want to do a lot of string processing (e.g. reading, modifying and writing text) nothing beats Python (and especially high level string processing is quite awkward in Zig).

If your prototypes are in any way related to the web or doing a lot of HTTP back and forth, then Typescript is the better choice.

Zig might be the better choice when otherwise you would reach for a language like C, C++ or Rust.

E.g. I would probably use Zig for asset-pipeline cmdline tools in game development (for instance processing 3D geometry and texture data), because this is an are where performance is important, and at the same time Zig tools are easy to build and run across all platforms.

1 Like

I say this with love and a healthy dose of humor:

Zig is a pain in the ass.

In the start any language is a pain in the ass. As you get better, it gets easier. That’s how it works in almost every language ever made. But not Zig. If Zig finds your workflow disagreeable, Zig will continue being a pain in the ass forever.

If the Zig compiler detects Bad Zig Code That Shouldn’t Exist™, Zig will throw a compiler error at you. Even if the code may look perfectly sensible to your eyes, even if the change is only temporary, there is no way to disable this error, and there never will be. If you try to write Bad Zig™, it will not compile. If you want to test your terribly written Bad Zig™, write it again and do it properly this time.

Zig would rather have less people write code than have more people write bad code. If your prototyping results in bad code, Zig will politely yet firmly ask you to stop, and it will continue until you stop writing bad code or you stop writing Zig.

But more seriously:

Zig is very opinionated about your code.

Some people find that it bothers them when they’re prototyping or debugging. Some people don’t. If it does bother you, don’t expect it to change. The team working on Zig is not willing to compromise on being uncompromising, so to say.

For that reason, it’s very hard to say if you’ll find Zig a good language for prototyping or not. It really depends on how your workflow fits with the problem space Zig is designed for and the workflow the Zig compiler wants you to have.

I do find Zig (the abstract language) incredibly easy to reason about, which is really really nice for prototyping, but then Zig (the practical toolchain) expects me to turn that abstract idea of a piece of software into high quality code, and that takes a while.

For me, the effort is very often worth it, even when prototyping, even when compared to some higher level language like Python or Typescript. But your mileage may vary.

(I often wish I could have a language with 70-80% of Zigs semantics but working with an abstract machine/OS layer. A kind of ‘ZigScript’, if you will. Keep the simple straight forward semantics, but abstract away the gritty details that Zig forces you to care about.)

5 Likes