Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Is there other rationale behind this `for` and `while` syntax? Why not:

   for x in elms {}

   for x in elms, i in 0.. {}
In my view, this seems simpler to read and understand. In particular, the iteration variable is close to the iterated structure. In the Zig proposal you have to think about the position of the iterated structure and the position of the iteration variable.

   for (elms, 0..) |x, i| {}
              ^^^      ^
              Ok it is in second position
I still don't get why `||`. Is this a lambda? Can I write something like:

  fn func(x: i8, i: i8) void {}
  for (elms, 0..) func
In the same vein I do not understand the rationale behind the `while` syntax. Why `:`?

   while (condition) : (i += 1) {


The richness of syntax in Zig has kinda put me off from learning it.

At the risk of sounding like a total ass: when I was checking Zig out (albeit briefly), it reminded me of the "Awful Taste, Great Execution" meme. I remember loving the ideas, but groaning internally when I saw how they need to be used. If someone is interested I could skim docs to see if I can still find an example of what put me off.

Things also seemed arbitrary and inconsistent sometimes, but that could've been a wrong impression since I didn't give it a proper shot overall.

It's a very new language, so I'm sure a lot of it is still in flux anyways. Also, this was all about a year and a half ago, maybe a bit more. So, maybe things improved since then.


Zig is one of the most highly consistent languages I've ever worked with. Often time I think, I wonder if I can... And then I find out that, yes, it does work that way, and, yes, I can. It just isn't often consistent with the way any given other language does things, and often angrily picks a construct/name from another language and uses it totally differently, but honestly, on reflection I often come to realize that my initial anger is ultimately because that other language has been inconsistent or special casing stuff.


I would love to see some examples, as i am not entirely sure what's so of-putting by it. My personal subjective opinion is, that yes, the syntax can in some cases look a bit off-putting (like the || capture) but overall, i don't think it is really ugly.


Because it’s consistent with the rest of Zig’s capture syntax:

    if (foo()) |result| {

    while (it.next()) |elem| {

    bar() catch |err| …


I think that's a valid criticism. The capture syntax and while colon are probably my least favorite aspects of zig.

The capture syntax is syntactically consistent across different constructs that support it, but it isn't semantically consistent. This consistency actually hurts because it's not expressing a general principle across the constructs, rather it's a convenience particular to each construct that we have unified syntax for, giving you the wrong impression the same sort of thing might be happening when it isn't.

The for capture takes elements of whatever kind in an array.

The catch capture only takes errors.

The if capture only takes optionals.

So, it's the same syntax for things that are totally semantically distinct. I get they're trying to make the language "guessable" to an extent and easy to remember/simple enough to fit in one's head, but imo this actually makes it harder to remember. I wind up getting confused because I have to stop to think about what gets captured and what it means etc. It's a writer convenience over a reader convenience. I'd much rather have to remember more, visually distinct syntax for different semantics than I would have to remember special, subtly different overloads of the same syntax across a range of semantics--ironing some syntax into the brain isn't as costly, imo as having to constantly remind oneself how these similar structures differ ever so slightly each time and untangle choices that are pragmatic but not semantically grounded.

All that said, the rest of the language is shaping up pretty fantastically.

Edit: As an example as to how it could be done differently, for null checks go just has the obvious "if (x == nil)". People complain about go's error check verbosity, but imo this is way clearer than zig's approach which requires remembering special magic "unwrap and bind to this only if not null" while saving only a few characters at most.


It is legitimately harder to parse if `in` is a special keyword. Zig's parser is defined in a context-free grammar and having implemented it, trust me the way it's done now is waaaaaay simpler.


Does Zig use `in` for anything else?


No.


Addressing just the capture: I don't see the problem with `||` at all, in-fact I think it's elegant. I do like (most of) Ruby's syntax so that's probably where my fondness of this comes from but I am not a veteran or seasoned Ruby expert by any means.


Agree with the iteration variable being far from the iterated structure.

Also so many special characters for such a simple construct! While I do like {} languages, this has () || {} whereas e.g. Rust would only have {} in that case:

    for x in xs {}
However, Rust's zip is much more cumbersome:

    for (x, y) in xs.iter().zip(ys.iter()) {}
A bit more reasonable with the zip function:

    use std::iter::zip;
    for (x, y) in zip(xs, ys) {}
You still need the () to match the tuple. Would be cool if that wouldn't be needed. And it still removes the connection between multiple iteration variables and their iterated structure. hmmm




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: