bazelbuild / starlark

Starlark Language
Apache License 2.0
2.48k stars 163 forks source link

spec: make reversed return an iterable instead of a list? #29

Open josharian opened 5 years ago

josharian commented 5 years ago

[originally discussed at https://github.com/google/starlark-go/issues/127; it may be fruitful to read that issue first]

The spec says:

reversed(x) returns a new list [...]

Python 2 and 3 made a different decision: It returns an iterable instead.

This affords possible performance optimizations by doing work lazily. See
https://github.com/google/starlark-go/issues/127#issuecomment-459080474 for an example.

On the other hand, starlark lacks next, which means that making reversed return an iterable removes the most convenient idiom for getting the last item of an iterable: In Python, it is next(reversed(x)), whereas for starlark it is reversed(x)[0].

One conservative decision is to change the spec to return an iterable, even if in practice most implementations return lists. That makes it possible to add optimizations down the line.

Discuss. :)

josharian commented 5 years ago

Similar case: Python evaluates enumerate lazily, but starlark does not. They thus disagree about subscriptability of enumerate expressions as well.

josharian commented 5 years ago

Another case: zip.

laurentlb commented 5 years ago

Python behavior can be surprising:

>>> a = [1, 2, 3]
>>> b = reversed(a)
>>> list(b)
[3, 2, 1]
>>> list(b)
[]
>>> a = [1, 2, 3]
>>> b = reversed(a)
>>> a[0] = 4
>>> list(b)
[3, 2, 4]

I'm not sure we really want this.