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-10261] Unexpected results for compact-mapped lazy sequence #52661

Closed
swift-ci opened this issue Apr 2, 2019 · 4 comments
Closed

[SR-10261] Unexpected results for compact-mapped lazy sequence #52661

swift-ci opened this issue Apr 2, 2019 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. standard library Area: Standard library umbrella

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Apr 2, 2019

Previous ID SR-10261
Radar None
Original Reporter dbplunkett (JIRA User)
Type Bug
Status Resolved
Resolution Invalid
Environment

Xcode 10.2 (10E125)
Swift 5

Additional Detail from JIRA
Votes 0
Component/s Standard Library
Labels Bug
Assignee None
Priority Medium

md5: 7321e0df08f39eaac4671a25ad294be4

Issue Description:

let array = [-1, 0, 1, 2, 3]

do {
    let lazy = array.lazy.compactMap { (int: Int) -> Int? in
        int > 0 ? int * 10 : nil
    }
//    lazy[0] // "Unexpectedly found nil"
//    lazy[1] // "Unexpectedly found nil"
    lazy[2] // 10
    lazy[3] // 20
    lazy[4] // 30
}

The sequence returned from a lazy sequence's compactMap has unexpected behavior.

In the example, subscripting the compact-mapped sequence produces the expected values, but they are located at the indices of the original un-mapped sequence. It's possible this is expected, though the behavior is surprising to me, as I would expect any kind of read into a sequence produced by lazy application of an operation to be the same as if the operation were applied non-lazily. I've been unable to find documentation clarifying this.

Expected: lazy[2] (for example) returns 30
Actual: lazy[2] returns 10

Edit: This ticket originally described two issues. The second issue has been moved to its own ticket: https://bugs.swift.org/browse/SR-10270

@belkadan
Copy link
Contributor

belkadan commented Apr 2, 2019

This is correct behavior. All of the lazy sequences use the same indexes as their underlying collection, so that you can translate between them freely, but that doesn't mean all indexes from the underlying collection are valid. So lazy[0] doesn't mean "the first element of lazy"; it means "the element of lazy that corresponds to array[0]", which of course doesn't exist.

@belkadan
Copy link
Contributor

belkadan commented Apr 2, 2019

cc @lorentey

@swift-ci
Copy link
Collaborator Author

swift-ci commented Apr 2, 2019

Comment by David Plunkett (JIRA)

Thanks for the clarification - I should have made two tickets, since the second problem seems separate.
I've opened a new ticket for the second problem here: https://bugs.swift.org/browse/SR-10270

@lorentey
Copy link
Member

lorentey commented Apr 2, 2019

I agree with Jordan assessment. Index values from one collection (like 0, 1, 2 from Array here) are generally not safe to use in another (like LazyFilterCollection above). LazyFilterCollection’s index type is Int, but this does not imply that it can be treated like an Array. You need to use the index(_:, offsetBy: ) method to access its nth element — directly subscripting by n isn’t valid.

It’s somewhat unfortunate that LazyFilterCollection reuses the index type of its base collection, because it leads to confusion in cases like this. However, at least invalid indices lead to traps in this case, rather than silently succeeding with invalid results.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
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

3 participants