Skip to content

Add conformances to LazySequenceProtocol and LazyCollectionProtocol #47

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

Merged
merged 9 commits into from
Dec 1, 2020

Conversation

danielctull
Copy link
Contributor

This fixes an omission in Intersperse where it doesn't currently conform to LazySequenceProtocol when the base sequence also conforms to LazySequenceProtocol.

Checklist

  • I've added at least one test that validates that my change is working, if appropriate
  • I've followed the code style of the rest of the project
  • I've read the Contribution Guidelines
  • I've updated the documentation if necessary

@CTMacUser
Copy link
Contributor

Probably should add (conditional) LazyCollectionProtocol support too. (It's actually a separate refined protocol, not a typealias of LazySequenceProtocol for collections.)

@timvermeulen
Copy link
Contributor

timvermeulen commented Nov 26, 2020

Huh, I was under the impression that LazyCollectionProtocol was a type alias when I added LazySequenceProtocol conformances in #29. Other collections in this library could benefit from a LazyCollectionProtocol conformance too, then.

The LazyCollectionProtocol docs say

To add new lazy collection operations, extend this protocol with methods that return lazy wrappers that are themselves LazyCollectionProtocols.

so we indeed can't assume that LazySequenceProtocol + Collection conformance is sufficient.

@CTMacUser
Copy link
Contributor

I was surprised too when I re-read the LazyCollectionProtocol definition.

@danielctull
Copy link
Contributor Author

I've just been through all the types and the only one that can be conformed to LazyCollectionProtocol was Indexed as the rest aren't collections, they can't conform to it.

I have renamed the XCTAssertLazy function to XCTAssertLazySequence and added a similar one called XCTAssertLazyCollection and fixed up the Indexed type too.

@danielctull danielctull changed the title Conform Intersperse to LazySequenceProtocol when the base sequence conforms Add conformances to LazySequenceProtocol and LazyCollectionProtocol Nov 27, 2020
@danielctull
Copy link
Contributor Author

danielctull commented Nov 27, 2020

I've just been through all the types and the only one that can be conformed to LazyCollectionProtocol was Indexed as the rest aren't collections, they can't conform to it.

I realised that I was only looking at types that already conform to LazySequenceProtocol. The following three are other types in the package that don't conform to a lazy protocol, which possibly could. I have listed them down so that they can be looked at, as I don't have time to check them myself at this particular moment. 🙂

  • Chain2
  • Product2
  • SlidingWindows

@timvermeulen
Copy link
Contributor

Chain2 and Product2 don't need the LazySequenceProtocol conformance because they're created by the chain and product free functions, not by any methods that can be part of a (lazy) chain.

SlidingWindows does indeed still need the conformance though!

@danielctull
Copy link
Contributor Author

Chain2 and Product2 don't need the LazySequenceProtocol conformance because they're created by the chain and product free functions, not by any methods that can be part of a (lazy) chain.

It would still be beneficial for them to have the conformance though? The following works if Chain2 conforms to LazySequenceProtocol, otherwise you have to go through another lazy operator.

extension LazySequenceProtocol {
  func someLazyOnlyFunction() {}
}

let first = (1...).prefix(10).lazy
let second = (20...).lazy
chain(first, second).someLazyOnlyFunction()

@timvermeulen
Copy link
Contributor

It would still be beneficial for them to have the conformance though?

In theory nothing is stopping them from conforming, but the laziness of sequences is only expected to propagate through method calls (lazy chaining) and not through the parameters of functions like zip/chain/product. It's just convention 🤷

It could also be ambiguous whether both input sequences would need to be lazy for the laziness to propagate, or that just one is enough. Always propagating the laziness of the Self type clears up this ambiguity. (Note how Sequence.flatMap propagates the laziness of the original sequence, and not the laziness of the sequence returned from the closure.)

@danielctull
Copy link
Contributor Author

Thanks for explaining that @timvermeulen.

In that case I believe this PR is ready to go. 🙂

@natecook1000
Copy link
Member

Looks great — thanks so much for noticing and fixing this, @danielctull!

@natecook1000 natecook1000 merged commit 93c8724 into apple:main Dec 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants