News for hackers. Stuff that matters.
Re:Revisiting the design approach to Zig by an_ko on Tuesday September 06, 2022 @06:01AM (#32735013)
This article praises everything Zig does and lists no negatives of its design. I'd recommend a different article for a balanced take, particularly regarding comparisons with Rust: https://www.scattered-thoughts.net/writing/assorted-thoughts...
Re:Revisiting the design approach to Zig by naikrovek on Tuesday September 06, 2022 @10:41AM (#32737721)
I don't trust any language comparison one-on-one with Rust, because fans of Rust today are just like fans of Python 20 years ago: "this language is the greatest accomplishment of humanity, easily," if I had to sum up the vibe I'm talking about.

compare [language] with C, fairly and accurately, if you want me to believe a word you say.

Re:Revisiting the design approach to Zig by Yoric on Tuesday September 06, 2022 @11:29AM (#32738463)
That's funny, I read this affirmation (and variants thereof) rather often, but I've been using Rust on and off since 0.4 and I've always been discussing with developers who have balanced and careful opinions of Rust, starting with the Rust language and compiler teams.

Rust has never been publicized as a solution to all problems. It happens to be my current favorite language for many tasks, but I don't think any serious Rust developer harbors the impression that Rust is designed to implement everything.

That being said, the community is much larger these days, so I assume that there are users who do not have a sufficient PL background to understand the tradeoffs made in the design of Rust.

Re:Revisiting the design approach to Zig by otabdeveloper4 on Tuesday September 06, 2022 @12:51PM (#32739767)
> Rust has never been publicized as a solution to all problems.
Re:Revisiting the design approach to Zig by anonymoushn on Tuesday September 06, 2022 @11:38AM (#32738611)
As a Zig fan, I thought GP's link was pretty favorable to Zig and pretty likely to be informative to users of other languages.
Re:Revisiting the design approach to Zig by kaba0 on Tuesday September 06, 2022 @12:12PM (#32739152)
There is not many languages that would fair worse next to C. For starters, not being able to create any form of even minimal, zero-cost abstractions like a vector is criminal.
Re:Revisiting the design approach to Zig by naikrovek on Tuesday September 06, 2022 @01:16PM (#32740092)
I think it's an apt comparison, Zig vs. C, given that Zig intends to replace C.

Go was aiming to be a replacement for C as well, but they didn't even try to reach that goal because Go programs require an OS to run on; something must host the runtime, even though it's included in the binary. I love Go and I dislike C quite a bit.

Zig vs. C seems fair to me, because there are no Zig zealots (or very few, at least not yet) and there are no C zealots who have lots of experience with C.

Re:Revisiting the design approach to Zig by xorvoid on Tuesday September 06, 2022 @10:00AM (#32737220)
This 100%

I’m darn sick of reading articles that don’t consider tradeoffs. Engineering can be defined as “a search for the optimal set of tradeoffs”. But, it seems like every article I ever read about new tech only discussed pros, not cons. I don’t get it. The cons are just as important, if not more so. Unfortunately, for some reason, people associate cons with flaws/weaknesses/failures rather than just a “point on the tradeoff curve”. Often: no perfect solution exists and those claiming otherwise are being dishonest. I would love to see this culture change at least for engineering literature where we should know better.

All that said: I DO think that Zig has selected a reasonable point in the tradeoff curve. I just really want to understand that point better. How am I supposed to use it most effectively if I don’t understand it?

Re:Revisiting the design approach to Zig by bsder on Tuesday September 06, 2022 @05:38PM (#32743549)
Here is the question I think that you need to answer to choose between Rust and Zig:

If your dependencies wrap more than 2 external libraries that have poor architecture, you're about to have a miserable time in Rust.

Rust creates a lot of friction if an external library has a poor architecture. And, by default, most libraries have a very poor architecture. This leads to things like:

"Giving up on wlroots-rs"--http://way-cooler.org/blog/2019/04/29/rewriting-way-cooler-i...

Talk about the issues of RLua--https://www.reddit.com/r/rust/comments/biq864/giving_up_on_w... "The thing that was SO tiring about writing this for me wasn't Rust, it was reasoning about the C library that I was binding. I'm just... tired of using C APIs! I'm tired of not having the compiler reason for me, I'm tired of having to second guess at what invariants the API expects and guess at what of a myriad of interesting non-local behavior a function call will do. I know that the Lua C API is a really, especially bad example, but I just don't know what the general solution is here."

Consequently, this is where you get "Rewrite All The Things In Rust!" What's the point of fighting with Rust over all these nice safety guarantees and then throwing them out at the API boundary? If you can keep everything in Rust, this simply isn't an issue.

This is where Zig shines. It catches some of the main classes of bugs but still lets you talk to libraries with crap architecture. Zig gets the fact that infrastructure and ecosystem matter--unlike everybody else operating in the C space (the cross compiling is phenomenal, for example, because they put a lot of work into it). Zig is doing some interesting things, but it's mostly some very solid choices with a lot of elbow grease applied. And that's worth a LOT.

As an aside, I will also say that Zig feels better for embedded programming than Rust. Rust feels like it has stalled in embedded areas (things like sized integers, bitfield packing, placement construction of data structures, statics and globals that don't have locking overhead, lack of do-while, etc. although I would like to point out in Rust's favor that Rust finally got label-break-value which is a godsend when porting embedded code with goto error handling) while Zig has explicitly targeted those from the beginning. That makes Zig feel better for embedded from an ergonomic perspective, to my (obviously quite subjective) taste.

Re:Revisiting the design approach to Zig by girvo on Tuesday September 06, 2022 @09:40PM (#32745427)
I also agree that Zig has more promise for embedded than Rust, in my opinion. I use Nim daily for embedded firmware development for similar reasons that I like Zig, but Nim has some baggage that can get in the way at times around it’s compiler (though fixing those issues is surprisingly accessible I’ve found).

That said, until someone works out how to properly integrate Zig or Nim or etc. into CMake, then there’s always going to be friction. Too much of the IDF world relies on it and it’s quirks.

In Nim land I get around this by --compileOnly to C sources, which works but is a little cumbersome. Rust is rebuilding the embedded world from scratch, which is a non starter for my work. I do have hope Zig will have a better story than both for this, but we will see!

Re:Revisiting the design approach to Zig by tialaramex on Tuesday September 06, 2022 @09:44PM (#32745450)
> I would like to point out in Rust's favor that Rust finally got label-break-value

Oh, interesting, I was wondering if this (breaking with both a label and a value) existed (in a different context), and I concluded it didn't exist and so probably nobody had wanted it, but turns out it's in the next version and I didn't hear about it.

I don't understand a desire for do-while, I can't imagine what I might write where that looks reasonable and the loop equivalent in Rust is not very good.

If all you wanted was nicer C then yeah, Zig is that and Rust isn't -- I just don't think "nicer C" is a reasonable goal any more.

Re:Revisiting the design approach to Zig by bsder on Tuesday September 06, 2022 @10:42PM (#32745782)
> I don't understand a desire for do-while

It has to do with porting code, generally. If I'm writing original Rust, I rarely miss it. It's not a huge deal, but you bump into it juuuust often enough to (probably unfairly) curse Rust out when you hit it yet again.

Here's code from CMSIS DAP debug probe firmware from ARM: https://github.com/ARMmbed/DAPLink/blob/main/source/daplink/...

Note the nested do { do { } while (); if (err) break;} while(); if (err) break;

Should that code be rewritten? Most certainly it should, and it should be given a proper Error type. However, when you are first porting it, you need to match semantics or you get a bunch of off-by-one, missed error, or missed end of stream bugs. And, as you point out, the Rust loop{} equivalents suck.

We've all written suboptimal code, and we all live in a suboptimal world. :)

Re:Revisiting the design approach to Zig by tialaramex on Wednesday September 07, 2022 @08:09AM (#32749538)
I definitely don't miss it while writing my own code. In porting well, I think because we've got volatile flag nonsense, we need to do some significant surgery to even make this compile anyway, and so perhaps

  do { ... } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
becomes something like

  loop {
    ...
    if data & DAP_Data.transfer.match_mask) == match_value {
      break;
    }
    match_retry -= 1;
    if match_retry == 0 {
      break;
    }
    if check_transfer_abort() { // Replaces DAP_TransferAbort
      break;
    }
  }
I think that's actually more clear, and my mental focus is DAP_TransferAbort. I think it's just C programmers being C programmers, and we just want AtomicBool for this but I'm more comfortable wrapping it in this check_transfer_abort() function while I investigate whether anybody thinks this is a counter, or there's actually physical hardware backing it despite the way it looks like it's just a global variable.
Re:Revisiting the design approach to Zig by pjmlp on Wednesday September 07, 2022 @05:19AM (#32748368)
This is one of the things I happen to agree with you. :)

If we take comptime feature away, Zig is basically Modula-2 (1978) with friendlier syntax for folks with C background.

Everything else in terms of security Modula-2 did better (yes it did have null pointers, but supports null checking).

And the tagging mechanisms for use-after-free are anyway available for C and C++ compilers for at least 20 years (Insure++, PurifyPlus and VC++ 6.0 debug allocator being part of the first ones).

Re:Revisiting the design approach to Zig by capr on Wednesday September 07, 2022 @07:05AM (#32749019)
The Lua C API is now bad because you can't easily make Rust bindings to it?
Re:Revisiting the design approach to Zig by openfuture on Tuesday September 06, 2022 @08:39AM (#32736284)
Well zig could be a no tradeoff improvement over C while rust definitely has tradeoffs. So I think "all good" is a plausible assessment.
Re:Revisiting the design approach to Zig by steveklabnik on Tuesday September 06, 2022 @10:00AM (#32737216)
Everything has tradeoffs. Be careful, lest the "Zig Evangelism Strike Force" becomes a thing!
Re:Revisiting the design approach to Zig by sakras on Tuesday September 06, 2022 @11:10AM (#32738129)
A bit pedantic, but a trade off with any new programming language is “having to learn a new language”. I haven’t programmed in zig but the syntax looks different enough from C that it would take a while to pick up.
Re:Revisiting the design approach to Zig by karmakaze on Tuesday September 06, 2022 @10:30AM (#32737578)
I watched the video rather than read the short post. It did a good job getting into details that illustrate some of the tradeoffs. e.g. Do you want a small language that you can fully learn, or do you want a language with many features that you can spend time learning?

Other things that are made explicit such as specifying an allocator on every allocation is an inconvenience that you pay for that flexibility. The choice of safety being added rather than assumed and later satisfied or declared an unsafe area is vastly different with a tradeoff in how developers use the language. An example given was how the self-hosted complier can use cache optimized untagged unions with the tags in a separate array.

If I had to guess what the single biggest pattern of tradeoffs is, I'd say it's about being explicit rather than implicit. You gain fine-grained control at the cost of brevity/convenience.

Re:Revisiting the design approach to Zig by dafneee on Tuesday September 06, 2022 @07:04AM (#32735420)
>we can't type-check zig libraries which contain generics. >comptime is_odd_perfect_number(n)

I assume zig has a finite bound on comptime_int, so we can in fact always know what is_odd_perfect_number() returns.

Re:Revisiting the design approach to Zig by andrepd on Tuesday September 06, 2022 @08:23AM (#32736148)
You misunderstand.

> we can't type-check zig libraries which contain generics. We can only type-check specific uses of those libraries.

I.e. you cannot say whether this compiles for all n, only for the instances you actually instantiate

Re:Revisiting the design approach to Zig by littlestymaar on Tuesday September 06, 2022 @08:40AM (#32736302)
Right, and this should be discussed a lot more when talking about Zig, because I suspect this is going to be a significant burden at the ecosystem level:

- library users will find compilation errors in the library code (his is annoying, but when you get used to it, you can treat it as any kind of library bugs and submit a PR)

- library users are going to rely on accidental behaviors (that is “in the library author's mind this isn't been used this way”) and then you'll have breaking changes without noticing.

(I say that as someone currently working on a DSL for the train industry, and this language (started in 2012) has something really close to Zig's comptime and we're currently trying to move away from it, because of the aforementioned issues. And it's actually pretty hard because big chunks of the existing code don't actually compile unconditionally and only compile when a given set of compile-time conditions are met, which makes the migration process hard)

Re:Revisiting the design approach to Zig by usefulcat on Tuesday September 06, 2022 @09:45AM (#32737033)
C++ has this problem too, but the funny thing is that I rarely run into it in practice.

There is a lot of templatized c++ library code out there, yet in everyday practice I find it's very rare that I need to instantiate a template with a type that causes a compile error.

Re:Revisiting the design approach to Zig by littlestymaar on Tuesday September 06, 2022 @10:15AM (#32737382)
> C++ has this problem too

That's true. C++ templates are exactly like that too.

They are a bit arcane though, and many developers are afraid of them and use them very conservatively or even avoid them altogether so maybe this helps mitigate the issue.

Comptime (at least with the language I'm currently working on) are a lot less scary, and people use them quite a lot without thinking too much, so maybe it's the main difference. And I think Zig is closer to this than it is to C++ templates, but I can't be sure since I've never seen people writing Zig code.

Re:Revisiting the design approach to Zig by pjmlp on Tuesday September 06, 2022 @01:18PM (#32740121)
I am afraid of being robbed in a dark alley, now in regards to programming languages I never understood what one should be afraid of.
Re:Revisiting the design approach to Zig by littlestymaar on Tuesday September 06, 2022 @04:51PM (#32743034)
I've fortunately never been robbed in a dark alley and that's not something that sounds like a real threat to me, but I had to intervene on nightmarish code-bases and some “convenient” feature sometime turn to be real curses (JavaScript `with` anyone?).

Edit: it's late in here, and I completely missed your point. I'm personally not usually afraid with language features, but some requires more work than others to be accustomed to, and not everyone is willing to spend their spare time doing so.

Re:Revisiting the design approach to Zig by Yoric on Tuesday September 06, 2022 @11:30AM (#32738491)
Lucky you :)

I used to code in C++ and I had that problem quite often. Including in implementations of the STL.

Re:Revisiting the design approach to Zig by verdagon on Tuesday September 06, 2022 @09:18AM (#32736712)
I suspect this might not be a problem for Zig long-term. One can imagine a blend of comptime, concepts, and generics which which can help mitigate (and often solve) these kinds of problems. When combined with compiler enforcement (or even a community-adopted linter) this could help the library author detect problems while still being able to use comptime's unique benefits.
Re:Revisiting the design approach to Zig by skywal_l on Tuesday September 06, 2022 @11:21AM (#32738339)
I fail to see how this is a problem. The compiler ensured that the compiled code will always work.

And if you put that in you API and someone call foo with an odd perfect number, well it will fail to compile.

It's conditional compilation, exactly what C does with macros. Except here, you don't have to learn an awful and honestly, sometimes, incomprehensible parallel language.

Zig has some shortcomings but I fail to see how this is one.

Re:Revisiting the design approach to Zig by foldr on Wednesday September 07, 2022 @08:46AM (#32749839)
It's not the end of the world, but there are significant disadvantages. For example, it makes it difficult for generic libraries to expose stable interfaces. The interface is 'use any type that doesn't make this exact implementation break', rather than (e.g.) 'use any type that implements these traits'. So you could potentially upgrade from v1.0.0 to v1.0.1 of a library and find that instantiating a generic function with a particular type no longer compiles. If you want to know why it doesn't compile, you'll just have to dig into the implementation of the library.
Re:Revisiting the design approach to Zig by skywal_l on Thursday September 08, 2022 @02:51PM (#32770238)
Ok I get you. The absence of traits (or concept) make documentation and reading the API harder. You see a `comptime T` somewhere and you don't what is expected of this type unless you either read the code in full or just try your type and see if it compiles.

That's a valid point indeed and there's an issue for that: https://github.com/ziglang/zig/issues/1268

Re:Revisiting the design approach to Zig by dingdingdang on Tuesday September 06, 2022 @11:26AM (#32738412)
No standard utf8 string library is scary - I would happily learn all the mem gymnastics to make this work but fiddling with competing UTF8 libraries as is the case with C/C++ is just not my cuppa.
Re:Revisiting the design approach to Zig by anonymoushn on Tuesday September 06, 2022 @11:38AM (#32738617)
There are functions for handling utf8 in the standard library.
Re:Revisiting the design approach to Zig by dingdingdang on Tuesday September 06, 2022 @04:48PM (#32742997)
Well, there's functions for working with code points within the bytes that (may) make up utf8 strings.. in order to do actual string level manipulation a library is needed (such as https://github.com/jecolon/ziglyph or others)
Re:Revisiting the design approach to Zig by wzwy on Tuesday September 06, 2022 @06:22AM (#32735150)
That’s what I felt as well when I read it. Maybe it’s as industry-redefining as it claims to be, but surely there must be some tradeoffs.

Rust’s tradeoff in providing safe and faster code is mentioned. Why not Zig’s?

Re:Revisiting the design approach to Zig by socialdemocrat on Tuesday September 06, 2022 @09:42AM (#32736993)
Having played with Zig I would say the tradeoff is complexity. Zig is harder to learn than C with more difficult concepts. Something like Go is much quicker. Yet I think Zig is finding an okay balance. You can still get productive much faster than in Rust.

Manual memory management gives obvious downsides which should be well known. Zig does this in the best way I have seen though.

Re:Revisiting the design approach to Zig by ikskuh on Tuesday September 06, 2022 @11:07AM (#32738087)
> Zig is harder to learn than C with more difficult concepts.

I'm using Zig and C for a good amount of time now and i disagree. Zig has simpler concepts as C, but in C you can just ignore them.

Consider

   char buf[4];
   float * f = buf;
   *f = 32;
Seems simple, compiles, and even executes. Everyone is happy. But that code will just explode randomly on non-x86 platforms as it violates alignment rules. In Zig, this code will give you a compile error, as []u8 does have alignment 1, while a []f32 will have alignment 4. This means you have to learn about alignment before accidently writing code that will randomly crash at runtime depending on the stack position of buf.

And Zig has a lot of these things that require implicit knowledge in C as explicit knowledge implemented in the language itself. Same goes for integer casting, shifting more than sizeof() bits, and so on.

It moves the footguns from the code to the user, and so the user has to learn about all of these concepts before writing Zig code. In C, the code will silently compile and misbehave at runtime. This might feel like additional complexity in a lot of places, but the complexity is there in both languages. One just makes it explicit.

But this is obviously not true for all things in Zig. comptime is a whole new feature that wasn't seen in a lot of languages before and afaik not as it is used in Zig, so it's something new to learn even if you already can do perfect C. The same goes for more precise data types (struct vs extern struct) and so on.

One hard footgun in Zig right now is implicit aliasing of parameter types, which sometimes get passed as a reference and sometimes as a value. This is a known footgun is already on the table to be adressed by better semantics and more safety guards

For me, writing Zig feels way less complex than C because a lot of brain load that went into writing correct C was offloaded to the compiler, which is good. But it also increases the friction when writing code as the compiler forces you to think about alignment and such.

Re:Revisiting the design approach to Zig by Ygg2 on Tuesday September 06, 2022 @07:09AM (#32735459)
Well, yeah the article is meant to promote it. They had podcast and everything. Same with Rust podcast.
Re:Revisiting the design approach to Zig by tialaramex on Tuesday September 06, 2022 @08:10AM (#32736007)
Yes, I think we should understand that this is what Andrew says, so e.g. "This type of optimization, Andrew explains, would not be possible in languages like Rust" is akin to when football players tell you they're confident they can win. Of course they're confident they can win, but at least half of them are going to be disappointed.

I actually don't know what Andrew is getting at with that particular case though. If the situation is that the types are obvious, so the Zig isn't ever looking at the tags, the Rust won't look at the tags either. Worse, I don't think Zig has niche optimisation, so there are a bunch of cases where Zig has to choose, have tags (more space, slower, but same safety as Rust) or go without (same size as Rust, but less safety). Rust only guarantees the niche in certain narrow cases like Option<&T> (is the same size as &T) but it actually delivers a lot more than that, and this continues to improve.