chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.79k stars 421 forks source link

Python-style `enumerate()` iterator for Chapel #10329

Open bradcray opened 6 years ago

bradcray commented 6 years ago

[capturing a feature request future that @thomasvandoren filed some time ago while working on issue #9222 even though it's a false positive]

To help Python programmers transition to Chapel, this issue proposes supporting an enumerate() iterator which would behave like Python's while also supporting parallel iteration via forall loops.

Supplying such a function is very straightforward (it's taken me more time to write this issue than to write the serial and standalone versions of it in PR #10328). Furthermore, documenting it would provide an opportunity to teach Python programmers who search for its documentation about zippered iteration in Chapel.

I think the hardest aspect of this issue is what to name the module in which it lives, as I don't think we have an existing module for which it's a good match. We could start a general Iterators module. Or we could start a module designed for helping Python programmers feel comfortable in Chapel (maybe call it Pythonic?). Looking for suggestions here, particularly from the Python-savvy.

There's also a minor question as to what the starting value should be. Python uses 0. Thomas seemed to propose 1 in his feature request based on the .good file. My sense is that since the goal of the iterator is presumably to avoid surprises for Python programmers, we should follow Python's lead here.

Associated Future Test(s): test/functions/iterators/thomasvandoren/enumerate.chpl

e-kayrakli commented 6 years ago

I think the hardest aspect of this issue is what to name the module in which it lives, as I don't think we have an existing module for which it's a good match. We could start a general Iterators module. Or we could start a module designed for helping Python programmers feel comfortable in Chapel (maybe call it Pythonic?). Looking for suggestions here, particularly from the Python-savvy.

There's also a minor question as to what the starting value should be. Python uses 0. Thomas seemed to propose 1 in his feature request based on the .good file. My sense is that since the goal of the iterator is presumably to avoid surprises for Python programmers, we should follow Python's lead here.

I did some grepping to see how I use enumerate and numpy.ndenumerate. Almost always, I used it to pick the index of a list I am iterating. Which made me ask whether that the default start value should conceptually be iterable.start where applicable. For simple arrays, this can easily be achieved in Chapel by for (idx,item) in zip(arr.domain, arr) but I am especially wondering what my intuition be if you pass a tuple to enumerate, as tuples are 1-based.

OTOH, maybe enumerate should be thought of as loop counter iterator, which coincidentally can be used as an index iterator in Python, as Python lists and tuples are 0-based. Anyways, from a more practical standpoint, I think the default value should be 0 initially.

Also see some related PEPs: https://www.python.org/dev/peps/pep-0212/, https://www.python.org/dev/peps/pep-0279/

mppf commented 5 years ago

I think the new module should be viewed as generally useful and not just a Python transition. For than reason, I'm happy with the name Iterators. I think the default starting point should be 1 since I view Chapel as 1-based (when it has to choose). Additionally I think it'd be nice if the resulting module is a reasonable place to put module implementation of the removed f[1..n, 1..m] promotion feature that created a 2D promotion.

bradcray commented 5 years ago

PR #10328 was my attempt to close this issue off, but got wrapped up in naming / design issues that I've never found the time to get back to, so I'm closing the PR for now and mentioning it here for the next time we return to this.