5 ms·
As much as a concept can be translated from one programming language to the next, they're conceptually pretty much identical. However for Zig there are two imp
by Laremere 4y ago
As much as a concept can be translated from one programming language to the next, they're conceptually pretty much identical. However for Zig there are two important differences:
1. It's simpler syntax than reaching for a zip function. I personally like this design because the conceptual load is pretty low as it feels like a natural extension of simple for loops. Eg you could teach someone simple for loops, then later go "hey, you could do this the whole time!"
2. Zig doesn't have support for custom iterators. Zip is doable using the existing metaprogramming features, but it's not as simple. Support for iterators also likely violates Zig's `No hidden control flow.` maxim. Plus I imagine it's a lot easier for the compiler to perform optimizations this way.
Both points combined are related to Zig's design goal for being good at writing code that can run fast on modern CPU architectures. Being able easily to loop over multiple arrays is a good step for making that practical.
- Jayschwa 4y agoWhile with optionals enables some iterator-like behavior. https://ziglang.org/documentation/master/#while-with-Optionals https://ziglang.org/documentation/master/#while-with-Optiona...
- malcolmstill 4y agoTo expand on the parent and grandparent: Laremere is correct in that there is no "magic" built-in understanding of iterators in the language, i.e. under the hood calling a `.next()` method, without explicitly having to call it. That _would_ violate the no hidden flow control maxim. However, as Jayschwa points out, Zig's `while` loop will bind the result of its expression (in its own block scope) if it is non-null and otherwise exit the loop. This gives you essentially the same as a for loop that has some language-level knowledge of the iterator pattern, except there is no hidden flow control (I have to explicitly call `next`). And indeed the Zig standard library is replete with iterators (and in most of the Zig code I write I will will write iterators for my own collections). For example, `mem.split` returns an iterator: var it = mem.split(...); // it.next() returns null after we run out of // split text and the while loop exits while (it.next()) |substr| { // In here we have a non-nil substr } > Plus I imagine it's a lot easier for the compiler to perform optimizations this way. That's an interesting point: does Zig miss out on some optimisation possibilities with iterators given they are not a language-level construct? I don't know.
- kps 4y ago> No hidden control flow. Off-topic, but… I very much like this idea, but I think Zig shares one wart with languages like C++: it's impossible to tell syntactically whether `f()` is a direct or indirect call. An indirect branch is a conditional branch, where the condition can be arbitrarily far away in space and time, and it's invisible. Dynamic control flow can be tricky to reason about even when you know it's there.
- rom-antics 4y agoiirc there was a proposal to have Zig used `funcptr.()` syntax (with a dot) for indirect calls, but it was rejected.
- cultureswitch 4y agoInteresting. To me having "hidden control flow" in your language is the key to create higher level abstractions that are easier to reason about. Same when it comes to "hidden allocation". That is, in a good language you'd replace an explicit but verbose, error-prone and boilerplate for loop with a declaration of the output of said loop. Either through applying a map function or a python-style list comprehension.