1\. For your first question, it shouldn't introduce overhead as it's an inline iterator. You can check the generated C code.
If we take a simple seq this is equivalent to the following iterator foo_item[T](s: seq[T]): T = for i in 0 ..< s.len: yield s[i] let a = @[1, 2, 3, 4] for val in foo_item(a): echo val The reason why I use an intermediate zip is for Arraymancer. This is a proof of concept before I generalize it to tensors. On tensors, it would be wrapped in an OpenMP template that splits the work on multiple cores like [here](https://github.com/mratsim/Arraymancer/blob/e801b78169b59f1213a2e046997cfecf99ed4feb/src/tensor/higher_order_applymap.nim#L31-L43). I also really need an iterator because the "next" item is not straightforward if the tensor is not contiguous, see [here](https://github.com/mratsim/Arraymancer/blob/e801b78169b59f1213a2e046997cfecf99ed4feb/src/tensor/private/p_accessors.nim#L144-L148). 2\. Thanks, fixed. Yes if they are not the same length it generates an error. 3\. Indeed that's a much better syntax, I have absolutely no idea how to introduce it though. Bonus, I added loopFusion: import loopfusion let a = @[1, 2, 3] let b = @[11, 12, 13] let c = @[10, 10, 10] let d = @[5, 6, 7] loopFusion(d,a,b,c): let z = b + c echo d + a * z