Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-8406] Confusing behavior of LazyFilterCollection subscript #50931

Open
mpangburn opened this issue Jul 29, 2018 · 4 comments
Open

[SR-8406] Confusing behavior of LazyFilterCollection subscript #50931

mpangburn opened this issue Jul 29, 2018 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. standard library Area: Standard library umbrella

Comments

@mpangburn
Copy link

Previous ID SR-8406
Radar None
Original Reporter @mpangburn
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Standard Library
Labels Bug
Assignee None
Priority Medium

md5: e404bd5234740680078cff16b28e6307

Issue Description:

Currently, LazyFilterCollection's subscript operation forwards directly to the base collection without performing any filter, which can produce some confusing results.

let evens = Array(1...10).lazy.filter { $0 % 2 == 0 } 
print(evens.count) // prints '5'
print(evens[8])    // prints '9'

Confusingly, the collection can be subscripted with an index not contained by the `indices` property. Is this behavior intentional?

@belkadan
Copy link
Contributor

I don't think we want to pay the cost of validating the index, but I guess we could. @airspeedswift?

@airspeedswift
Copy link
Member

Right. This would be a big perf hit because you would, on subscript access, have to execute the predicate a second time, which might be costly. I think I'd consider this behaves-correctly. We could perhaps add an assert in debug builds.

@swift-ci
Copy link
Collaborator

Comment by Jens Jakob Jensen (JIRA)

I guess it would help if this was documented for the LazyFilterCollection.

I actually first thought that a lazy collection was memoizing. Are there any plans to add a memoizing LazyCollection? Then each element would only be created once. So if you did evens[3], then the first elements 1...8 of the underlying array in the case above would be consumed and wouldn't be accessed anymore. The point of course would be that the lazy closures could be costly, so ensuring that they were only run once could make sense.

We have a method taking a LazyConnection instead of a factory closure. I was surprised when the "factory closure" (i.e. a lazy map closure) was executed several times because the client used .lazy.compactMap() and we first accessed .count() then traversed the lazy collection 🙂

@swift-ci
Copy link
Collaborator

Comment by Jens Jakob Jensen (JIRA)

Actually IMHO every aspect where adding .lazy makes the collection behaving differently would be great to have documented. I would consider any non-documented change in semantics bugs.

The documentation of LazyFilterCollection states "A sequence whose elements consist of the elements of some base sequence that also satisfy a given predicate.". I think it would be fair to assume that either the "sequence" did not have a subscript operator, or that the subscript operator behaves as if not using lazy.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

4 participants