core icon indicating copy to clipboard operation
core copied to clipboard

zip for arrays, iters, etc

Open NKID00 opened this issue 1 year ago • 3 comments

Is seems zip is only implemented for @immut/list.T but not Array or Iter. There seems to be no way to iterate over multiple iterators, and zipping two iterators fits well.

I am willing to contribute this, please assign me if I may give it a try.

NKID00 avatar Sep 13 '24 14:09 NKID00

MoonBit's Iter and Iter2 are internal iterators, where the user of iterators pass a callback to the provider of data. This is in contrast to external iterators, where the iterator produce one element every time the user requests, and save internal state about the current progress of iteration.

In internal iterators, the provider of data (e.g. Array::iter) owns the control flow, while for external iterators, the user of the iterator (e.g. for .. in) owns the control flow. This difference is subtle, because only the one who owns the control flow can stop the iterator in the middle. As a consequence, it is impossible to implement zip for internal iterators unless you have control effect constructs such as call/cc. So sadly, the absence of Iter::zip is a theoretic limitation of the Iter type.

At this point, you may wonder why MoonBit chooses the less flexible internal style to implement iterators. This is because internal iterators are simpler to write and optimize, and is adequate for the most common scenario.

Of course there are many cases where it is handly or even necessary to zip two iterators, and a iterator type that support zipping (i.e. external iterator) would be a good addition to MoonBit's current Iter and Iter2 types. If you are interested in this task, you may consider writing a package for external iterators on https://mooncakes.io , which is also a highly encouraged and appreciated way to contribute to the MoonBit community.

Guest0x0 avatar Sep 14 '24 09:09 Guest0x0

There is no problem with `Array::iter`` though, it would be great if you could implement it

Guest0x0 avatar Sep 14 '24 09:09 Guest0x0

How about

fn Iter::zipWith[T1, T2](self: Iter[T1], seq: Unit -> Option[T2]) -> Iter[T1, T2]

hackwaly avatar Oct 12 '24 04:10 hackwaly

The zip for array has been implemented. Community may try to implement an external iterator library.

peter-jerry-ye avatar May 07 '25 06:05 peter-jerry-ye