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-2065] Quell forloopian distemper by extending sequence to include a terminating condition #44674

Open
swift-ci opened this issue Jul 13, 2016 · 2 comments
Labels
improvement standard library Area: Standard library umbrella

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-2065
Radar None
Original Reporter erica (JIRA User)
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Standard Library
Labels Improvement
Assignee None
Priority Medium

md5: bc63fb8ca1703ff8a55432e333074074

Issue Description:

/// Returns a sequence formed from `first` and repeated lazy applications of
/// `next` until a user-supplied `while` test fails.
///
/// The first element in the sequence is always `first`, and each successive
/// element is the result of invoking `next` with the previous element. The
/// sequence ends when `next` returns `nil` or when the user-supplied test
/// returns false. If `next` never returns `nil` and the test never fails,
/// the sequence is infinite.
///
/// This function can be used to replace many cases that were previously handled
/// using C-style `for` loops and includes a stopping test without requiring
/// a secondary prefix function.
///
/// Example:
///
/// The following Swift 2.2-and-earlier C-style loop prints
/// out numbers from 0 to 49:
///
///    for var i = 0, j = 100; i < j; i++, j-- {
///        print(i)
///     }
///
/// This can be refactored in Swift using the same first, next, and test
/// components:
///
///    for (i, j) in sequence(
///        first: (i: 0, j: 100),
///        next: { ($0.i + 1, $0.j - 1) },
///        while: { $0.i < $0.j })
///    {
///        print (i) // count to 49
///    }
///
///
/// - Parameter first: The first element to be returned from the sequence.
/// - Parameter next: A closure that accepts the previous sequence element and
///   returns the next element.
/// - Parameter while: A closure that tests the next value and returns true or
///   false, forcing the sequence to end
/// - Returns: A sequence that starts with `first` and continues with every
///   value returned by passing the previous element to `next` until test(value)
///   fails
///
/// - SeeAlso: `sequence(state:next:)`, `sequence(first:next:)`
public func sequence<T>(first: T, next: (T) -> T?, while test: (T) -> Bool) -> UnfoldSequence<T, (T?, Bool)> {
  return sequence(state: (first, true), next: { (state: inout (T?, Bool)) -> T? in
    switch state {
      case (let value?, true):
        state.1 = false
        if !test(value) {
          state.0 = nil; return nil
        }
        return value
      case (let value?, false):
        let nextValue = next(value)
        if 
          let nextValue = nextValue, 
          !test(nextValue) {
            state.0 = nil; return nil
        }
        state.0 = nextValue
        return nextValue
      default:
        return nil
    }
  })
}
@Dante-Broggi
Copy link
Contributor

Is this resolved, or no longer valid? If either, this should be closed.

@swift-ci
Copy link
Collaborator Author

Comment by erica sadun (JIRA)

It is still valid, not resolved, would probably take the SE process to include, and I can already hear @lattner's voice saying: "This is an abomination". Even so, it would be sweet as a little nice thing.

@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
improvement standard library Area: Standard library umbrella
Projects
None yet
Development

No branches or pull requests

2 participants