Zulip Chat Archive

Stream: general

Topic: best practices: iteration over array items with indices


Michael Rothgang (Sep 05 2024 at 11:46):

What's the most idiomatic way of iterating over all array items with their corresponding index? Something akin to Python's enumerate(array, 1).
One way is the following, but I can't help wondering if there's something better.

  let mut index := 0
  for item in array do
    -- work with index and item
    index := index + 1

Eric Taucher (Sep 05 2024 at 12:05):

Take a look at the Lean tutorial Functional Programming in Lean, in particular the section titled Proving Termination.

Yes you may have to read the entire tutorial to understand the noted section but if you plan to create programs with Lean it is worth the effort even if it takes a few days or more.

Damiano Testa (Sep 05 2024 at 12:13):

I think that you might get some suggestions from this topic.

Michael Rothgang (Sep 05 2024 at 13:53):

Thanks to both of you! I'm going with

  for h : idx in [:array.size] do
    let item := array[idx]
    -- work with index and item

Jz Pan (Sep 06 2024 at 16:35):

docs#Array.zipWithIndex

for (item, index) in array.zipWithIndex do
  ...

(untested)

Eric Wieser (Sep 08 2024 at 09:23):

Strangely, docs#List.enum puts the pairs in the opposite order

Kim Morrison (Sep 08 2024 at 22:56):

It is possibly not too late to fix that. I'm starting soon on making the List/Array APIs more consistent. Besides the churn, does anyone see a downside of flipping List.enum?

Kim Morrison (Sep 08 2024 at 22:56):

(I recall finding the current order slightly unergonomic recently, but can't remember where.)

Yakov Pechersky (Sep 08 2024 at 23:05):

The nice thing about the current order is that you get an obvious lex order on the elements of the attach subtype

Eric Wieser (Sep 08 2024 at 23:07):

enum also matches the order of Python's enumerate

Kim Morrison (Sep 08 2024 at 23:23):

Perhaps the only reason for the disparity is that it is hard to say "indexWithZip" because of English word order. :-)

Eric Wieser (Sep 08 2024 at 23:27):

Taking a step back: is array.zipWithIndex actually an efficient way to do this looping? In python, enumerate returns an iterator, not an list - presumably allocating an Array of pairs is wasteful here?

Thomas Zhu (Sep 09 2024 at 00:13):

What about the best practice for tracking indices in a general for-in loop, such as over MLList?

Jz Pan (Sep 10 2024 at 18:51):

Eric Wieser said:

Taking a step back: is array.zipWithIndex actually an efficient way to do this looping?

Since array.zipWithIndex is constexpr (C++ sense), the best bet is that a very good optimize compiler will reorder loop operations.

In python, enumerate returns an iterator, not an list - presumably allocating an Array of pairs is wasteful here?

Perhaps we should add a array.forWithIndexM.

Kim Morrison (Sep 10 2024 at 23:13):

I think we could even provide a ForIn instance that returns pairs.


Last updated: May 02 2025 at 03:31 UTC