3 ms·
> It's zip with an arbitrary amount of array parameters. So… zip? Python’s does that, and for most other langages you could use overloading, basic macros, or
by masklinn 4y ago
> It's zip with an arbitrary amount of array parameters.
So… zip?
Python’s does that, and for most other langages you could use overloading, basic macros, or traits trickery to get there if you really wanted to support unreasonable widths (IME you almost never need more than 3, and combining two zip/2 works fine then).
- klyrs 4y agoZig's "zip" is purely syntactical, where Python's zip is a generator. This is significant both in terms of performance (Zig wins) and flexibility (Python wins). Unlike Python, you can't pass a zip generator around. It's just a for-loop. While zig loops are expressions, they only return a single value.
- masklinn 4y ago> This is significant both in terms of performance (Zig wins) Does it, actually? Does Zig's built-in pseudo-zip outperform Rust's? Or C++23's? > It's just a for-loop. Except it's not "just" a for loop, it's a weird special case for a for loop. And one which is actively dangerous too.
- klyrs 4y agoPlease check the context, I was comparing to Python. And please chill out. It's only "dangerous" when you decide to run it that way.
- masklinn 4y ago[flagged]
- klyrs 4y agoHi, no need to be so abrasive about it. > Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith. Python's zip function returns a generator. A generator in zig would look like a function pointer with a closure. If zig were to implement the Python-style "zip" function, constructing the closure, and iterating over the generator, would be significantly slower than the naked "just a for loop" that we see in TFA. And that's not even considering the tuple construction (oops, now we need an allocator) & unpacking. Ergo, the zig-style "syntactical zip" is higher performance than the Python-style "functional zip". Even when you cut through the baseline performance differences between the languages.
- masklinn 4y ago> Hi, no need to be so abrasive about it. That's just projection. > Please respond to the strongest plausible interpretation of what someone says, not a weaker one that's easier to criticize. Assume good faith. I'll get right on that as soon as you extend the same courtesy, which you have refused to do at every opportunity.
- deleted 4y ago[deleted]
- judofyr 4y ago> Except it's not "just" a for loop, it's a weird special case for a for loop. You could also argue that a for loop which can only iterate over a _single_ sequence is a special case of a multi-sequence for loop. > And one which is actively dangerous too. In safe builds (ReleaseSafe, Debug) it will cause a controlled panic if the sequences are not of the same size. Most likely it's a logical bug if you iterate over two sequences of different sizes. In ReleaseFast the compiler will make assumptions to improve performance. If it's very important for your code you can force a certain code block to always have runtime safety. Yes, there are trade-offs, but I don't feel it's _unreasonable_.
- lmm 4y ago> You could also argue that a for loop which can only iterate over a _single_ sequence is a special case of a multi-sequence for loop. When a "for loop" in virtually every language is not multi-sequence, not really. People expect a "for loop" to be a certain kind of thing.
- jeroenhd 4y agoThere is no single "zip". Java's .zip() will work on two sources, as will C#'s Zip(). Haskell's zip is no different, only accepting two parameters. I don't know any language other than Python that shares Python's iterator zip() implementation. In implementation, Python's zip will return a generator that is iterated over using the iterator functionality, while Zig's .zip is compiled as a loop. Python's iteration may be turned into a loop, it may be interpreted, or it may be turned into some other kind of bytecode, who knows. The standard cpython implementation is much more complex, though: https://github.com/python/cpython/blob/main/Python/bltinmodule.c#L2703 https://github.com/python/cpython/blob/main/Python/bltinmodu... Concatenating zip()s is an unnecessarily complex solution, both in terms of syntax and in code generated. In Python this may not matter because it's a relatively slow programming language in general (the language often being "glue between fast C methods"), but in Zig this can easily become untennable. I also disagree that you don't need more than 3. As the article states, if you leverage array-of-structs rather than struct-of-arrays you can use this to "deconstruct" objects without paying the memory usage penalty of struct padding. The 15% wasted RAM in this example is relatively small compared to some real use scenarios; something as common as a 3D vector will often have a whopping 25% space waste. Other languages allow this as well (and often using such iterations are much faster than zip()ing lists together) but the lack of guarantees and repetitive syntax becomes a pain.
- masklinn 4y ago> There is no single "zip". Which means you can implement yours to fit your needs. > I don't know any language other than Python that shares Python's iterator zip() implementation. https://docs.rs/itertools/latest/itertools/macro.izip.html https://docs.rs/itertools/latest/itertools/macro.izip.html > In implementation Which is hardly relevant. Python's entire implementation has aims, means, and purpose with no relation to Zig's. > I also disagree that you don't need more than 3. Which is not what I wrote. > As the article states, if you leverage array-of-structs rather than struct-of-arrays you can use this to "deconstruct" objects without paying the memory usage penalty of struct padding. Sure? And the article uses an example with 3 values. > The 15% wasted RAM in this example is relatively small compared to some real use scenarios; something as common as a 3D vector will often have a whopping 25% space waste. It also could hardly be less relevant: it's an issue in an AoS structure because all your objects have that overhead, therefore that's your total overhead. Here it's 15 or 25% padding in a single value within a stackframe. You're probably wasting more stackframe space due to the compiler not bothering reusing temporally dead locations. And that's if the compiler reifies the tuple instead of eliding the entire thing. > Other languages allow this as well OK? > (and often using such iterations are much faster than zip()ing lists together) Until they are not.