profile
viewpoint

apple/swift 54868

The Swift Programming Language

apple/swift-evolution 11803

This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.

apple/swift-package-manager 8136

The Package Manager for the Swift Programming Language

apple/swift-corelibs-foundation 4106

The Foundation Project, providing core utilities, internationalization, and OS independence

apple/swift-corelibs-libdispatch 1962

The libdispatch Project, (a.k.a. Grand Central Dispatch), for concurrency on multicore hardware

apple/swift-corelibs-xctest 872

The XCTest Project, A Swift core library for providing unit test support

briancroom/BlindsidedStoryboard 15

Example of passing a Blindside injector through a storyboard

briancroom/BCBalancedMultilineLabel 14

A label which draws itself such that each of its lines have as close to the same length as possible.

briancroom/BackgroundFetchLogger 4

Gather data on how often iOS wakes apps via Background Fetch

pull request commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

@lattner Yes, that works for me. I'll make sure this is merged by Wednesday.

filip-sakel

comment created time in 21 minutes

Pull request review commentapple/swift-evolution

[Concurrency] Task Local Values

 A task local key declaration nested under in the `TaskLocalValues` and consists  > This design may remind you of SwiftUI's `@Environment` concept, and indeed the shape of how values are declared is fairly similar. However, it differs tremendously in *where* the child/parent relationship is expressed. In a later section we'll make a more detailed comparison with SwiftUI. -Next, in order to access the value one has to `await Task.local(_:)` it:+Next, in order to access the value one has to `Task.local(_:)` it:  ```swift-func printRequestID() async {-  let id = await Task.local(\.requestID) ?? "<unknown>"+func asyncPrintRequestID() async {+  let id = Task.local(\.requestID)   print("request-id: \(id)") }-``` -Since it is not known statically if the value will be present or not, the returned value is an `Optional<String>`.+func syncPrintRequestID() async {

Is this meant to be non-async?

ktoso

comment created time in 4 hours

push eventapple/swift-evolution

Chris Lattner

commit sha 5b72af9135317d9522057a12895efc2176d970bc

fix typo

view details

push time in 11 hours

push eventapple/swift-evolution

Frederick Kellison-Linn

commit sha d3f19b3ed92e0bb00d9d8e7ce4764c1e11bec743

Add Acknowledgements section to proposal template (#1254)

view details

push time in 11 hours

PR merged apple/swift-evolution

Reviewers
Add Acknowledgements section to proposal template

@hborla recently added this section to SE-0293, and it seemed like it would be a good thing to prompt all contributors to think about over the course of their work on a proposal.

cc @hborla @airspeedswift

+6 -0

1 comment

1 changed file

Jumhyn

pr closed time in 11 hours

delete branch Quick/Quick

delete branch : dependabot/bundler/danger-8.2.1

delete time in 11 hours

PR closed Quick/Quick

Bump danger from 8.1.0 to 8.2.1 dependencies ruby

Bumps danger from 8.1.0 to 8.2.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/danger/danger/releases">danger's releases</a>.</em></p> <blockquote> <h2>8.2.1</h2> <ul> <li>Add <code>danger.import_dangerfile(url:)</code> to import Dangerfile from custom URL - <a href="https://github.com/dstranz">@dstranz</a></li> <li>Fixes issue with not being able to update comments, and instead always posting new comments regardless of settings for Bitbucket Cloud <a href="https://github.com/tskulbru">@tskulbru</a></li> <li>Fix incorrect command in error message <a href="https://github.com/revolter">@revolter</a></li> </ul> <p><a href="https://github-redirect.dependabot.com/danger/danger/issues/1192">#1192</a>: <a href="https://github-redirect.dependabot.com/danger/danger/pull/1192">danger/danger#1192</a> <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">#1191</a>: <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">danger/danger#1191</a></p> <h2>8.2.0</h2> <ul> <li>Add support for Concourse-CI <a href="https://github.com/matthewellis">@matthewellis</a></li> <li>Add support for <code>pull_request_target</code> in GitHub actions. - <a href="https://github.com/chesire">@chesire</a></li> </ul> <p><a href="https://github-redirect.dependabot.com/danger/danger/issues/1192">#1192</a>: <a href="https://github-redirect.dependabot.com/danger/danger/pull/1192">danger/danger#1192</a> <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">#1191</a>: <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">danger/danger#1191</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/danger/danger/blob/master/CHANGELOG.md">danger's changelog</a>.</em></p> <blockquote> <h2>8.2.1</h2> <ul> <li>Add <code>danger.import_dangerfile(url:)</code> to import Dangerfile from custom URL - <a href="https://github.com/dstranz">@dstranz</a></li> <li>Fixes issue with not being able to update comments, and instead always posting new comments regardless of settings for Bitbucket Cloud <a href="https://github.com/tskulbru">@tskulbru</a></li> <li>Fix incorrect command in error message <a href="https://github.com/revolter">@revolter</a></li> </ul> <h2>8.2.0</h2> <ul> <li>Add support for Concourse-CI <a href="https://github.com/matthewellis">@matthewellis</a></li> <li>Add support for <code>pull_request_target</code> in GitHub actions. - <a href="https://github.com/chesire">@chesire</a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/danger/danger/commit/973bd6cdaf43bb08bab78cc1c98dd1e9ecc1a82b"><code>973bd6c</code></a> Prepares for release</li> <li><a href="https://github.com/danger/danger/commit/b9104455baf578bce61b30fea1900fb525927c37"><code>b910445</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1271">#1271</a> from danger/feature/import-dangerfile-from-url</li> <li><a href="https://github.com/danger/danger/commit/e1970cc52f1e9076dcd945865f92d23e82f5bd63"><code>e1970cc</code></a> Merge branch 'master' into feature/import-dangerfile-from-url</li> <li><a href="https://github.com/danger/danger/commit/43639e16151b628f399ddfa137d6a3c5e47e60c4"><code>43639e1</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1270">#1270</a> from tskulbru/update-comments-bitbucket-cloud</li> <li><a href="https://github.com/danger/danger/commit/e6228d941f4b8d1774346b96f01a73af14cbb66b"><code>e6228d9</code></a> Merge branch 'master' into update-comments-bitbucket-cloud</li> <li><a href="https://github.com/danger/danger/commit/253c191322aadc13b2e746d9bd7ba85a565b60d2"><code>253c191</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1272">#1272</a> from revolter/patch-1</li> <li><a href="https://github.com/danger/danger/commit/c3b7d767622bff18384b0edef1ce2a2fab99dec1"><code>c3b7d76</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1273">#1273</a> from revolter/fix/code-blocks</li> <li><a href="https://github.com/danger/danger/commit/417d2177ac6b6ae72f395ee0325566107f0ac66d"><code>417d217</code></a> Merge branch 'master' into feature/import-dangerfile-from-url</li> <li><a href="https://github.com/danger/danger/commit/7ea047833271794b7a7c0420dcf17fc732a3c48a"><code>7ea0478</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1274">#1274</a> from revolter/fix/error-message</li> <li><a href="https://github.com/danger/danger/commit/17813a86dc65275682436788dd012f3e96662135"><code>17813a8</code></a> Fix incorrect command in error message</li> <li>Additional commits viewable in <a href="https://github.com/danger/danger/compare/8.1.0...8.2.1">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

</details>

+2 -2

1 comment

1 changed file

dependabot[bot]

pr closed time in 11 hours

pull request commentQuick/Quick

Bump danger from 8.1.0 to 8.2.1

Superseded by #1036.

dependabot[bot]

comment created time in 11 hours

create barnchQuick/Quick

branch : dependabot/bundler/danger-8.2.2

created branch time in 11 hours

PR opened Quick/Quick

Bump danger from 8.1.0 to 8.2.2

Bumps danger from 8.1.0 to 8.2.2. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/danger/danger/releases">danger's releases</a>.</em></p> <blockquote> <h2>8.2.2</h2> <ul> <li>Silence the ObjectifiedHash warnings when iterating over GitLab notes. - <a href="https://github.com/dstull"><code>@dstull</code></a></li> <li>Replace <code>URI.escape</code> which is obsolete in Ruby 3. - <a href="https://github.com/mataku"><code>@mataku</code></a></li> <li>Fix run with Azure Pipelines as CI Source and Azure Repos Git as Request Source - <a href="https://github.com/damien-danglard"><code>@damien-danglard</code></a></li> <li>Delegate explicitly keyword arguments for Ruby 3. - <a href="https://github.com/mataku"><code>@mataku</code></a></li> </ul> <p><a href="https://github-redirect.dependabot.com/danger/danger/issues/1192">#1192</a>: <a href="https://github-redirect.dependabot.com/danger/danger/pull/1192">danger/danger#1192</a> <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">#1191</a>: <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">danger/danger#1191</a></p> <h2>8.2.1</h2> <ul> <li>Add <code>danger.import_dangerfile(url:)</code> to import Dangerfile from custom URL - <a href="https://github.com/dstranz"><code>@dstranz</code></a></li> <li>Fixes issue with not being able to update comments, and instead always posting new comments regardless of settings for Bitbucket Cloud <a href="https://github.com/tskulbru"><code>@tskulbru</code></a></li> <li>Fix incorrect command in error message <a href="https://github.com/revolter"><code>@revolter</code></a></li> </ul> <p><a href="https://github-redirect.dependabot.com/danger/danger/issues/1192">#1192</a>: <a href="https://github-redirect.dependabot.com/danger/danger/pull/1192">danger/danger#1192</a> <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">#1191</a>: <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">danger/danger#1191</a></p> <h2>8.2.0</h2> <ul> <li>Add support for Concourse-CI <a href="https://github.com/matthewellis"><code>@matthewellis</code></a></li> <li>Add support for <code>pull_request_target</code> in GitHub actions. - <a href="https://github.com/chesire"><code>@chesire</code></a></li> </ul> <p><a href="https://github-redirect.dependabot.com/danger/danger/issues/1192">#1192</a>: <a href="https://github-redirect.dependabot.com/danger/danger/pull/1192">danger/danger#1192</a> <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">#1191</a>: <a href="https://github-redirect.dependabot.com/danger/danger/issues/1191">danger/danger#1191</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/danger/danger/blob/master/CHANGELOG.md">danger's changelog</a>.</em></p> <blockquote> <h2>8.2.2</h2> <ul> <li>Silence the ObjectifiedHash warnings when iterating over GitLab notes. - <a href="https://github.com/dstull"><code>@dstull</code></a></li> <li>Replace <code>URI.escape</code> which is obsolete in Ruby 3. - <a href="https://github.com/mataku"><code>@mataku</code></a></li> <li>Fix run with Azure Pipelines as CI Source and Azure Repos Git as Request Source - <a href="https://github.com/damien-danglard"><code>@damien-danglard</code></a></li> <li>Delegate explicitly keyword arguments for Ruby 3. - <a href="https://github.com/mataku"><code>@mataku</code></a></li> </ul> <h2>8.2.1</h2> <ul> <li>Add <code>danger.import_dangerfile(url:)</code> to import Dangerfile from custom URL - <a href="https://github.com/dstranz"><code>@dstranz</code></a></li> <li>Fixes issue with not being able to update comments, and instead always posting new comments regardless of settings for Bitbucket Cloud <a href="https://github.com/tskulbru"><code>@tskulbru</code></a></li> <li>Fix incorrect command in error message <a href="https://github.com/revolter"><code>@revolter</code></a></li> </ul> <h2>8.2.0</h2> <ul> <li>Add support for Concourse-CI <a href="https://github.com/matthewellis"><code>@matthewellis</code></a></li> <li>Add support for <code>pull_request_target</code> in GitHub actions. - <a href="https://github.com/chesire"><code>@chesire</code></a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/danger/danger/commit/a7b927f1ef8af671cc7b4d6efe5a8195b90a9234"><code>a7b927f</code></a> Prepare for release</li> <li><a href="https://github.com/danger/danger/commit/9a27312fb10f4277b4fff8f10788aaa6c2676547"><code>9a27312</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1284">#1284</a> from damien-danglard/master</li> <li><a href="https://github.com/danger/danger/commit/444801f390c7da694f170d28efe176e78c0087e8"><code>444801f</code></a> Merge branch 'master' into master</li> <li><a href="https://github.com/danger/danger/commit/11b38d27fff8be309cca31bf7841a5f03e5cd67a"><code>11b38d2</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1286">#1286</a> from mataku/keyword-arguments</li> <li><a href="https://github.com/danger/danger/commit/bef6b0dadc7d466d6624b251f2ce04c2eb06b2a5"><code>bef6b0d</code></a> Handle empty keyword argument correctly in danger plugin</li> <li><a href="https://github.com/danger/danger/commit/566478fdb6d198db86525625283f062828bf3304"><code>566478f</code></a> Add changelog for keyword arguments in Ruby 3</li> <li><a href="https://github.com/danger/danger/commit/9c64d9cf9221ce8170f6f3a0dd7b50d2ecfac835"><code>9c64d9c</code></a> Add spec for keyword argument behavior in danger plugin</li> <li><a href="https://github.com/danger/danger/commit/056ed06bcd00939c5dbe66a7fc1379b81247190b"><code>056ed06</code></a> Delegate keyword arguments for Ruby 3.0</li> <li><a href="https://github.com/danger/danger/commit/4e488ee3924a8ef39e9d380a3455ec87c836533d"><code>4e488ee</code></a> Merge branch 'master' into master</li> <li><a href="https://github.com/danger/danger/commit/45c6469f44cefe0fd8c1011e86f5a3611180b2e2"><code>45c6469</code></a> Merge pull request <a href="https://github-redirect.dependabot.com/danger/danger/issues/1285">#1285</a> from mataku/uri-escape-is-deprecated</li> <li>Additional commits viewable in <a href="https://github.com/danger/danger/compare/8.1.0...8.2.2">compare view</a></li> </ul> </details> <br />

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


<details> <summary>Dependabot commands and options</summary> <br />

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

</details>

+7 -5

0 comment

1 changed file

pr created time in 11 hours

pull request commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

Hey @hborla, Ted would like to kick off the second round of review for this proposal on Wednesday. Will that work for you, and will it be merged in by then?

filip-sakel

comment created time in 15 hours

pull request commentapple/swift-evolution

Add Acknowledgements section to proposal template

This LGTM, any concerns merging this @tkremenek or @DougGregor ?

Jumhyn

comment created time in 15 hours

created tagapple/swift-corelibs-xctest

tagswift-DEVELOPMENT-SNAPSHOT-2021-01-23-a

The XCTest Project, A Swift core library for providing unit test support

created time in a day

pull request commentmuter-mutation-testing/muter

HTML Report

Similarly, maybe removals could just be removals, i.e. ditch the green line here:

image

I'd also make the border skinnier and the colors more muted; maybe use GitHub's diff view as a starting point.

Curve ball: dark mode 🕶

I thought that leaving removed line would help, but I think we can drop it since it's what the operator is doing anyways.

Yeah, the colors are not great, I'll follow your advice and copy Github's diff colors.

Curve ball: responsive 📱

rakaramos

comment created time in 2 days

pull request commentmuter-mutation-testing/muter

HTML Report

Similarly, maybe removals could just be removals, i.e. ditch the green line here:

image

I'd also make the border skinnier and the colors more muted; maybe use GitHub's diff view as a starting point.

Curve ball: dark mode 🕶

rakaramos

comment created time in 2 days

pull request commentmuter-mutation-testing/muter

HTML Report

Is it possible to show the entire line modified instead of only the operator?

Captura de Tela 2021-01-23 às 15 19 55

Yes it is, but it's not as easy and it has a couple of edge cases. For instance:

if a && b || c { }

There's no easy way (with the code as is today) to detect which statement is being mutated. A further exploration of SwiftSyntax is necessary (and it is time consuming)

In a future version that's something we would like to have, for sure!

rakaramos

comment created time in 2 days

pull request commentmuter-mutation-testing/muter

HTML Report

Is it possible to show the entire line modified instead of only the operator?

Captura de Tela 2021-01-23 às 15 19 55

rakaramos

comment created time in 2 days

push eventmuter-mutation-testing/muter

Zev Eisenberg

commit sha d3b08a82da3e5b6d4b7e623b330c7003e702c3a4

Update and lock versions of gems.

view details

Rafael Machado

commit sha 255b495292d123ec6e81317a06efcd70cdea9022

Merge pull request #192 from muter-mutation-testing/bugfix/zeveisenberg/update-gems Update and lock versions of gems

view details

Rafael Machado

commit sha 51b0f1d676e83f42d4b6be37532d818dadb840dd

Merge branch 'master' into feature/html-report

view details

push time in 2 days

PR opened muter-mutation-testing/muter

HTML Report

This draft introduces a new report to Muter.

A preview can be found here

+3082 -50

0 comment

13 changed files

pr created time in 2 days

push eventmuter-mutation-testing/muter

Rafael Machado

commit sha b58c3e84d1ac8859c048e84ea689ccf9fc8c29cd

Fix off by one error

view details

push time in 2 days

push eventmuter-mutation-testing/muter

Rafael Machado

commit sha 5ee850b8a92b0913aec82771323a4b70e389517c

Fix off by one error

view details

push time in 2 days

Pull request review commentapple/swift-evolution

[Proposal Revision] Extend property wrappers to functions and closure parameters.

 struct TextEditor { } ``` +### Extending property wrappers to patterns++Property-wrapper backing-storage initialization in the the pattern of a closure argument was supported in first revision. Building on this syntax, the core team suggested the extension of property-wrapper application to places where patterns exist. Of course, the design has been amended so as to preserve the expectation that the backing storage be private; extending property wrappers to patterns, though, is still a viable future direction. ++Enabling the application of property wrappers where patterns are available is quite straightforward and could be introduced in as part of two separate features. The first could be to enable utility wrappers –– such as `@Asserted` –– in patterns. The second could be enabling projected-value initialization, which would facilitate intuitive and effortless access to property wrappers in native language constructs, as shown below:

I don't understand the "two separate features" approach. For this line of code:

let (@Traceable userRatings, ... ) = ...

What type is the user providing on the right side? Is this initializing a new property wrapper, or "binding" userRatings to the wrapped value of an existing property wrapper? I thought the goal of property wrappers in patterns was the latter.

filip-sakel

comment created time in 3 days

push eventmuter-mutation-testing/muter

Rafael Machado

commit sha 8d1d13514b2e8950b8e9dcec99bbf2a1d908a734

Fixes and refactor tests

view details

push time in 3 days

push eventapple/swift-evolution

Joe Groff

commit sha a362a8d505344bc89458c9c218c3a4a9e2e74f69

SE-300: Remove unnecessary invariant

view details

push time in 3 days

pull request commentapple/swift-evolution

Community feedback: Remove explicit cancellation

Sounds good to me.

parkera

comment created time in 3 days

pull request commentapple/swift-evolution

Community feedback: Remove explicit cancellation

Thanks, Tony. I'm going to hold off on merging this right now because we generally don't want the proposal to change substantially in the middle of a review.

parkera

comment created time in 3 days

pull request commentapple/swift-evolution

Community feedback: Remove explicit cancellation

+1, thanks Tony

parkera

comment created time in 3 days

PR opened apple/swift-evolution

Community feedback: Remove explicit cancellation

Updates from community feedback. Thank you!

+27 -49

0 comment

1 changed file

pr created time in 3 days

Pull request review commentapple/swift-evolution

AsyncSequence

+# Async/Await: Sequences++* Proposal: [SE-NNNN](Async-Await-Series.md.md)+* Authors: [Tony Parker](https://github.com/parkera), [Philippe Hausler](https://github.com/phausler)+* Review Manager: TBD+* Status: **Awaiting review**+* Implementation: [apple/swift#35224](https://github.com/apple/swift/pull/35224)++## Introduction++Swift's [async/await](https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md) feature provides an intuitive, built-in way to write and use functions that return a single value at some future point in time. We propose building on top of this feature to create an intuitive, built-in way to write and use functions that return many values over time.++This proposal is composed of the following pieces:++1. A standard library definition of a protocol that represents an asynchronous sequence of values+2. Compiler support to use `for...in` syntax on an asynchronous sequence of values+3. A standard library implementation of commonly needed functions that operate on an asynchronous sequence of values++## Motivation++We'd like iterating over asynchronous sequences of values to be as easy as iterating over synchronous sequences of values. An example use case is iterating over the lines in a file, like this:++```swift+for try await line in myFile.lines() {+  // Do something with each line+}+```++Using the `for...in` syntax that Swift developers are already familiar with will reduce the barrier to entry when working with asynchronous APIs. Consistency with other Swift types and concepts is therefore one of our most important goals. The requirement of using the `await` keyword in this loop will distinguish it from synchronous sequences.+### `for/in` Syntax++To enable the use of `for in`, we must define the return type from `func lines()` to be something that the compiler understands can be iterated. Today, we have the `Sequence` protocol. Let's try to use it here:++```swift+extension URL {+  struct Lines: Sequence { /* ... */ }+  func lines() async -> Lines+}+```++Unfortunately, what this function actually does is wait until *all* lines are available before returning. What we really wanted in this case was to await *each* line. While it is possible to imagine modifications to `lines` to behave differently (e.g., giving the result reference semantics), it would be better to define a new protocol to make this iteration behavior as simple as possible.++```swift+extension URL {+  struct Lines: AsyncSequence { /* ... */ }+  func lines() async -> Lines+}+```++`AsyncSequence` allows for waiting on each element instead of the entire result by defining an asynchronous `next()` function on its associated iterator type.++### Additional AsyncSequence functions++Going one step further, let's imagine how it might look to use our new `lines` function in more places. Perhaps we only want the first line of a file because it contains a header that we are interested in:++```swift+let header: String?+do {+  for try await line in myFile.lines() {+    header = line+    break+  }+} catch {+  header = nil // file didn't exist+}+```++Or, perhaps we actually do want to read all lines in the file before starting our processing:++```swift+var allLines: [String] = []+do {+  for try await line in myFile.lines() {+    allLines.append(line)+  }+} catch {+  allLines = []+}+```++There's nothing wrong with the above code, and it must be possible for a developer to write it. However, it does seem like a lot of boilerplate for what might be a common operation. One way to solve this would be to add more functions to `URL`:++```swift+extension URL {+  struct Lines : AsyncSequence { }++  func lines() -> Lines+  func firstLine() throws async -> String?+  func collectLines() throws async -> [String]+}+```++It doesn't take much imagination to think of other places where we may want to do similar operations, though. Therefore, we believe the best place to put these functions is instead as an extension on `AsyncSequence` itself, specified generically -- just like `Sequence`.++## Proposed solution++The standard library will define the following protocols:++```swift+public protocol AsyncSequence {+  associatedtype AsyncIterator: AsyncIteratorProtocol where AsyncIterator.Element == Element+  associatedtype Element+  func makeAsyncIterator() -> AsyncIterator+}++public protocol AsyncIteratorProtocol {+  associatedtype Element+  mutating func next() async throws -> Element?+  __consuming mutating func cancel()+}+```++The compiler will generate code to allow use of a `for in` loop on any type which conforms with `AsyncSequence`. The standard library will also extend the protocol to provide familiar generic algorithms. Here is an example which does not actually call an `async` function within its `next`, but shows the basic shape:++```swift+struct Counter : AsyncSequence {+  let howHigh: Int++  struct AsyncIterator : AsyncIteratorProtocol {+    let howHigh: Int+    var current = 1+    mutating func next() async -> Int? {+      guard current <= howHigh else {+        return nil+      }++      let result = current+      current += 1+      return result+    }++    mutating func cancel() {+      current = howHigh + 1 // Make sure we do not emit another value+    }+  }++  func makeAsyncIterator() -> AsyncIterator {+    return AsyncIterator(howHigh: howHigh)+  }+}+```++At the call site, using `Counter` would look like this:++```swift+for await i in Counter(howHigh: 3) {+  print(i)+}++/* +Prints the following, and finishes the loop:+1+2+3+*/+++for await i in Counter(howHigh: 3) {+  print(i)+  if i == 2 { break }+}+/*+Prints the following, then calls cancel before breaking out of the loop:+1+2+*/+```++Any other exit (e.g., `return` or `throw`) from the `for` loop will also call `cancel` first.++## Detailed design++Returning to our earlier example:++```swift+for try await line in myFile.lines() {+  // Do something with each line+}+```++The compiler will emit the equivalent of the following code:++```swift+var it = myFile.lines().makeAsyncIterator()+while let value = try await it.next() {

Thank you -- I'll fix this in an update.

parkera

comment created time in 3 days

CommitCommentEvent
more