6 ms·
There are some very clever concepts in Zig (I like the fact that types are compile time values), but the language doesn't seem to be as carefully designed as so
by nynx 6y ago
There are some very clever concepts in Zig (I like the fact that types are compile time values), but the language doesn't seem to be as carefully designed as some others. For example, for-loops only work on a few, blessed types.
- dhruvdh 6y agohttps://www.nmichaels.org/zig/interfaces.html https://www.nmichaels.org/zig/interfaces.html There is an example here for a kind of iterator.
- dbandstra 6y agoI wouldn't call that careless. So far, proposals to extend the for-loop have not passed the cost/benefit test. I think supporting iterators would require something like magic-methods, which so far are not a thing in Zig (language syntax doesn't interact with userland code). The status quo for iterators is this: var it = getSomeIterable(); while (it.next()) |item| { ... } IMO it's "good but not great" (not great because it adds a var and the variable pollutes the outer scope). But the alternative is a bit of a pandora's box.
- Leherenn 6y agoHonestly, I know it's minor, but when I tried Zig the fact I couldn't do the classic for loop to do a "for (int i = 0; i < n; ++i)" was quite annoying. It pollutes the scope, so you need to add scope braces every time, and I find it's much easier to forget the ++i at the end of the while loop. I understand where it's coming from, but having something like "for (i32 i in [0,n[)" would be so much nicer in my opinion.
- pron 6y ago> and I find it's much easier to forget the ++i at the end of the while loop. You can do: var i: usize = 0; while (i < 10) : (i += 1) { ... } or var i: usize = 0; while (i < 10) { defer i += 1; ... } although the two have slightly different semantics (the latter would increment even after a break; the former wouldn't).
- jeltz 6y agoGiven how Zig does not allow variable shadowing (which is a choice which makes sense on its own) I find the scope leak to be very annoying in practice.
- dilap 6y agoNeither of those fix the scope leak, tho.
- AnIdiotOnTheNet 6y agoThis is true. There have been proposals to alter the `while` syntax to fix the scope leak, as well as proposals to extend `for` to support ranges, but none have been accepted (and they aren't very compelling in my opinion). Honestly, I'm not sure why people think it is such a big deal. I've written a lot of zig, mostly gamedev stuff, and I rarely use that construction. I find that the vast majority of loops are over arrays or slices.
- dilap 6y agoWhile I don't have much experience with Zig, I agree -- from my little bit of playing around, it also hasn't been a big deal. (The biggest thing I've hit that I want is a way to return information with an error. If that were fixed, I think Zig's error handling would be perfect.)
- jorangreef 6y agoLoris Cro did a great talk on error handling in Zig, which also deals with how to return information with an error if you need to, and why the common case optimizes for simpler error values: https://www.youtube.com/watch?v=TOIYyTacInM https://www.youtube.com/watch?v=TOIYyTacInM
- dilap 6y agoThanks, that was a nice talk. But the answer there is basically, "if you care about payload, don't use zig's built-in error handling." Which, obviously, you can do, but I'm not convinced it's a great answer! Even for something as simple as parseInt, it would be nice, I would argue, if it returned, along with InvalidCharacter, which character was invalid. This would enable e.g. very precise indications in messages to the end user of what was wrong with the input. In general, because currently it's super-ergonomic to return just error codes but more of a pain to return errors w/ payloads, what you'll get in practice is no error payload even when it would be useful, which will end up turning into less-helpful-than-ideal errors for end users, which is contrary to zig's goal of enabling the creation of perfect software. :-) I found this thread interesting https://github.com/ziglang/zig/issues/2647 https://github.com/ziglang/zig/issues/2647
- pfalcon 6y ago> while (it.next()) |item| { Talk about confusing, implicit syntax of Zig - there's no connection between "it.next()" and "|item|". It's implicit and you need to make it up. Compare that to other languages: "for item in it" or "while (item = it.next())".
- AnIdiotOnTheNet 6y agoIt isn't confusing. The meaning of the syntax isn't obvious if you didn't bother to learn zig syntax, but it is entirely consistent with how zig does this sort of thing. The for loop payload syntax, where you can also give a name to the counter, is the only weirdness with it.
- pfalcon 6y agoI'm sorry, but I do programming languages for decades, and familiar with a bunch of them. There's absolutely nothing special about Zig, it's yet another wannabe proglingo. What sets it apart is strong desire "to replace C" while being apparently "as different as possible from it". I understand such a strategy (among many possible), and that will be a fun strategy if it pans out. The current situation though is that people question: why that dude purposely make it harder than needed for everyone?
- AnIdiotOnTheNet 6y agoI feel like what you're complaining about is the equivelent of Calculon's critique of a screenplay: "no, I don't like the font". I am very much not a genius (check the user name) and it took me less than a minute to understand the payload operator (which IIRC was taken from Ruby or something). Let's say `for (x in y) {}` replaced the payload operator. It would still exist in: - if(some_error_union) |value| {} else |err| {} - if(some_nullable) |value| {} - while(some_nullable) |value| {} - switch(some_tagged_union) { .some_tag => |value| {} } And any that I might be forgetting. Is your suggestion that each of these should have separate syntax, thus complicating the language with one-off syntax?
- 6y ago
- pron 6y agoConsider the domain Zig targets -- low-level programming -- and other languages targeting it: C, C++, Ada and Rust. The first is very simple but severely lacks in both expressive power and safety, and the other three would all easily make any list of the top five most complex programming languages in the history of software; they're byzantine temples for those who worship at the altar of accidental complexity. Zig offers a radical design. It seeks to be as simple as C — which is particularly important in low-level programming for both portability [1] and humans and machine analysis — while also giving you safety and high expressivity. Obviously, radical design means doing things differently. Zig rejects any kind of implicitness; all calls must appear as calls. This means no operator overloading, no destructors, and no magical traits. It does so, however, without giving up on expressivity by using other mechanisms. All low-level programming languages suffer from low abstraction. That comes with the territory. By that I mean that implementation details (especially around memory management) are hard to hide. Changing those details in some component often require changing the clients of that component as well. But C++ and Rust have a design philosophy that tries to hide this intrinsic quality of low-level programming by making the final code appear on the page as if it has abstraction capabilities similar to high-level languages. Of course, that illusion breaks as soon as you try to change code, and it's debatable whether this design helps or harms program comprehension. Zig rejects the C++ philosophy in favour of a brand new, and pretty revolutionary one, that reimagines how low-level programming is done. Unlike Rust, Zig isn't a cleaned-up C++ with a few extra tricks, but it isn't a new C, either. It's something completely different. You might prefer Zig's design for this domain (as I do) or you might prefer the more traditional C++ design, but the great thing is that Zig is so simple and easy to learn that it's easy to try and find out. [1]: Consider what it would take to port C++ (or a C++-like language) to new microcontroller you build. You would either need to port LLVM or an extremely complex compiler — a huge undertaking. This is why C (well, there's a tiny bit of Ada, too) still reigns supreme even in domains where correctness is of utmost importance: https://youtu.be/uqan23518Yc?t=632 https://youtu.be/uqan23518Yc?t=632
- eklavya 6y agoWhat would be accidentally complex about Rust? Sure, if you don't provide the static guarantees that Rust does (and only Rust provides AFAIK), you can be a lot simpler :) The more I use Rust the more I am convinced I can write high level performant code. I mean it's ridiculous that sometimes I forget I am writing Rust and not Scala!!