-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[Stdlib] Implement sequence(first:next:) and sequence(state:next:) #2717
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
[Stdlib] Implement sequence(first:next:) and sequence(state:next:) #2717
Conversation
I'm submitting this now to get eyes on it, because I'm getting some very strange errors trying to compile the included unit test:
For the first and third errors, I have no clue why it's considering this call to be ambiguous with candidates For the second error, I can't figure out why it's saying I'm missing a parameter for argument #1 in the call to |
expectEqual(i, s1.next()) | ||
expectEqual(i, calls) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+ runAllTests()
If I rewrite line 15 (the second error) to the following: let s2 = sequence(state: (1...5).makeIterator(), next: { (iter: inout CountableRange<Int>.Iterator) -> Int? in return iter.next() }) I get the equally-bizarre error
The only type involved with a generic parameter named |
@@ -49,6 +49,7 @@ | |||
"Indices.swift", | |||
"Existential.swift", | |||
"WriteBackMutableSlice.swift", | |||
"UnfoldSequence.swift", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no clue at all what GroupInfo.json is. I stuck this in here because the compiler complained otherwise. I hope I put it in the right place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the right place, thanks.
Turns out the second error stems from the fact that |
return _next(&_state) | ||
} | ||
|
||
internal init(state: State, next: (inout State) -> Element?) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Internal inits should have an underscore:
internal init(_state state: State, next: (inout State) -> Element?)
I take it back, even if I use |
/// - Returns: A sequence that yields each successive value from `next. | ||
/// | ||
/// - SeeAlso: `sequence(first:next:)` | ||
public func sequence<T, State>(state: State, next: (inout State) -> T?) -> UnfoldSequence<T, State> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
80 columns?
public func sequence<T, State>(state: State, next: (inout State) -> T?)
-> UnfoldSequence<T, State> {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, T
=> Element
? (Here and in other APIs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding T
=> Element
, I checked before writing this and our functions like map
still use type parameters that look like T
. My impression was that we renamed T
to Element
, etc when used as parameters to types themselves, but left them as T
on the functions that return the types, because the type here is not defined as "the element of the sequence", but is instead defined as e.g. "the return value of the closure", and then the resulting sequence uses that return value for its elements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the right call—repeatElement
is probably the most similar existing function to sequence
. It uses T
, as well, to generate a Repeated<T>
instance, while Repeated
has an Element
generic parameter.
Turns out that providing a full type signature for the closure fixes the first and third errors too. This is troubling. Why is the compiler unable to figure out the type involved without the full signature, and why is the error message so bad? |
Oh great. Adding the full type signatures to all the closures now triggers a compiler crash ("Unhandled conversion to exploded tuple"). |
Ah, that can be solved by replacing |
1ec085f
to
89e881c
Compare
@gribozavr I've updated the PR with all of your suggestions, save for |
|
||
/// A sequence whose elements are produced via repeated applications of a | ||
/// closure to some mutable state. The elements are computed lazily and the | ||
/// sequence may potentially be infinite in length. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The abstract should be a single sentence. Can you break this up? It also might help to state how you get an UnfoldSequence
, since there's no initializer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured the - SeeAlso:
line was the hint for how to get this, but I can certainly be more explicit.
89e881c
to
97ce1db
Compare
@gribozavr PR updated. I put the |
@@ -0,0 +1,48 @@ | |||
// RUN: %target-run-simple-swift |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need two test files? Could we move everything into validation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, but validation tests are run much less often so I kind of assumed anything that is reasonable to put into the normal test suite, should be put into the normal test suite. Am I wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After giving it another minute's thought, I suppose this is fine. StdlibCollectionUnittest
isn't exposed to normal tests, so it's probably safe to assume most of the sequence/collection tests are already validation tests, so I guess it wouldn't be unusual to put all of the sequence(...)
tests into the validation test file.
97ce1db
to
d1d0e05
Compare
@gribozavr PR updated |
@swift-ci Please test and merge |
The failures seem to be unrelated. |
Nice, thanks @kballard! |
What's in this pull request?
This implements SE-0094 (
sequence(first:next:)
andsequence(state:next:)
).Resolved bug number: (SR-1622)
Before merging this pull request to apple/swift repository:
Triggering Swift CI
The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
Smoke Testing
Validation Testing
Lint Testing
Note: Only members of the Apple organization can trigger swift-ci.