Hacker News new | ask | show | jobs
by pseudonymcoward 2933 days ago
I think this may be exactly what I've been looking for. I've been wanting a "Better C" type of language, but all the existing candidates fall down on some point like - too complicated (Rust/D/C++), no manual memory management (Go), etc. I've even made some half baked attempts at writing my own language.

It seems that the design goals of this language are exactly what I'm after. Going to have to give it a try later.

2 comments

What part(s) of Rust do you find too complicated, and why?
I'm not the person who you asked, and I'm an absolute rust lover, but--

Rust is for people with C-level problems who don't like C's ergonomics. Zig appears to be for people with C-level problems who do like C's ergonomics.

Some of that is from essential complexity that we've been lying to ourselves about (memory safety, mutability, safe parallelism) and rust makes explicit.

C has a simplicity for it, for better _and_ worse.

In general I prefer languages to be small and simple - like Go and C. This doesn't seem to be a design goal for Rust, which puts me off. Some specifics:

Trying to do anything non-trivial with ownership/lifetimes/borrowing always ends up in a tangle, fighting with the compiler.

Everything in the stdlib seems to have a giant api with pages and pages of functions. Example: https://doc.rust-lang.org/std/string/struct.String.html Scrolling down through those methods is overwhelming.

The overhead imposed by the goal of maximising safety is big, and not that important to me (as I'm not writing Very Important Crypto code or whatever, I don't find it hard to write good enough code for my purposes in C).

Click the [-] at the top right of that doc page. You won't find it so overwhelming.
Why not Ctrl-F instead of scrolling ?
One place they're thinking of might be integration with C. zig's C integration is crazy good from what I can tell toying around with it. It was as easy as

@cImport({@cInclude("header.h")})

The language is also evolving rapidly, this may have changed, but if it did, it probably changed for the better.

Zig might be a good fit for you. Nim also seems to answer all your requirements.
Nim doesn't meet all his requirements, it's garbage-collected. Complexity is hard to measure and rather subjective, but Nim in my opinion seems to be more complex than Zig.
> Nim in my opinion seems to be more complex than Zig

That may be so, but Zig is still in a very early stage of development. A language may look simple and fresh in the beginning, but the real test comes when 1.0 is right around the corner. Nim is at this stage now, I am one of the Nim core devs and I will even admit that it is by no means simple, there are features that I would like to see removed to reduce the complexities, but how do you do that when a vocal percentage of your user base loves the feature?

Do keep this in mind when trying to compare a language like Zig (which is just starting out) to a language like Nim (which has been around for a while). Perhaps Zig will do a better job than Nim in this regard, but only time can tell.

You can also point out that people can use subsets with minimal features. They can do it for extra safety, consistency, or even low-level control. Safety-critical field has done that with both C++ and Java for some time now.

Regarding that, does Nim allow one to turn off GC, mess with pointers, and twiddle bits like in C? As in, is there an optional set of C's features in there that one can use? Or improve with macros, type-safe wrappers, and so on?

> Safety-critical field has done that with both C++ and Java for some time now.

Every company/project uses a subset of C++ for a variety of reasons. The problem is, all those subsets are different, and as a result, if you want to rely on the ecosystem, you eventually have to deal with the entire language. Maybe you avoid exceptions/pointers/new&delete/template-meta-programming/the-coprocessor, but the libraries you need don't.

This is visible already in Nim, where the GC is optional, but most libraries (and most of the standard library) does depend on it.

It works well without GC, but you lose out on most of the existing libraries and many parts of the ecosystem.

> Regarding that, does Nim allow one to turn off GC, mess with pointers, and twiddle bits like in C?

It lets you twiddle bits without having to turn off the GC - it has GC-tracked pointers ("ref"s) and non-GC ones ("ptr"s). the GC is per-thread, with time limits but it can also be turned off.

> Or improve with macros, type-safe wrappers, and so on?

Nim macros are not quite at the Lisp level, but they are extremely powerful.

There are various features for type safety that DON'T require wrappers, e.g. you could define "meters" and "yards" as two distinct 64-bit double types, which means you can't add them or assign one to a variable of the other kind, even though they are still essentially a C-style typedef. This is a much more elegant solution than the C++/Python/SmallTalk/Java/C# crowd, where you have to define a class with a lot of methods, which is still clunky, and hope that the compiler will be able to optimize it back down to a plain old double.

> Nim macros are not quite at the Lisp level, but they are extremely powerful.

I'm not fully familiar with Lisp macros so I'm curious, what is Nim missing that Lisp has in terms of metaprogramming?

> Regarding that, does Nim allow one to turn off GC, mess with pointers, and twiddle bits like in C? As in, is there an optional set of C's features in there that one can use? Or improve with macros, type-safe wrappers, and so on?

Yep, and in fact I would say that Nim is a perfect "better C" language. You get things like modules, a better type system and metaprogramming. Of course you'll have to forgo a lot of the stdlib, but if you're already using C that won't be a tough pill to swallow.

Nim is optionally garbage collected. Most of the standard library opts to use the garbage collector, true, but here's an example of a beginning of a tiny OS kernel in nim[0], that does not.

I do not know enough of Zig to compare the complexity, and Nim is indeed not simple. To borrow from the zen of Python, it is complex but not complicated; and most of its complexity is of a kind you can almost entirely ignore until you need it, and when you need it, you're in trouble if your programming language doesn't provide it. e.g. operational transforms, macros, compile time execution. pragmas.

[0] https://github.com/dom96/nimkernel