With the ServerSide.swift conference having taken place for the second year, there are a lot of exciting updates on Swift on the server — and more!

有兴趣赞助 Swift Weekly Brief?点击这里

Podcasts

In the latest Swift Unwrapped episode, Jesse and JP talk about the new Swift Compiler Driver project.

News and community

The Swift for Tensorflow team wrote an extensive manifesto on differentiable programming in Swift.

Tanner Nelson wrote a blog post with an update on the progress in the Swift Server Work Group over the last year.

Andrea Scuderi wrote a blog post on ServerSide.swift.

Cory Benfield shared some contributions to the SwiftNIO project from a workshop at ServerSide.swift.

Commits and pull requests

Ankit Aggarwal merged two pull requests that simplify the bootstrap script for the Swift Package manager.

Accepted proposals

SE-0267: where clauses on contextually generic declarations was accepted with a modification.

The core team has decided to accept this proposal with one modification. The proposal addresses the issue of conditional protocol requirements by disallowing constraints involving Self from being applied to protocol requirements, but it should also do so for non-final class methods, to avoid the same problem with conditional dynamically-dispatched methods in classes.

Returned proposals

SE-0265: Offset-Based Access to Indices, Elements, and Slices was returned for revision.

Swift’s indexing model is based on solid concepts that have held up well over the years, but the verbosity of expressing positions at integer offsets from known indices has been a persistent pain point. The Core Team feels that this is a significant problem and is very happy to see a proposal aimed squarely at it.

OffsetBound allows the expression of abstract indices that aren’t actually valid in a collection. During the review, it was pointed out that, rather than responding to this by clamping or reporting an error, we could use it to improve expressivity: for example, if the user inserts something at .last + 5, we could pad out to that index with some (user-provided) padding element. The Core Team discussed this idea and ultimately decided to reject it. We feel that it provides a simpler and more consistent programming experience overall if abstract indices can always be thought of simply as sugar for computing a specific valid index.

It was also pointed out that anchoring abstract indices at the beginning and end of a collection is fairly limiting; there are plenty of other interesting ways of deriving indices, like finding the first index that matches a predicate. The Core Team feels that it should not be a goal of this feature to totally replace the need to work with concrete index values. In particular, this shouldn’t become an arbitrarily-complex expression-template language.

That said, it’s important that abstract indices compose nicely with concrete indices. Programmers should feel like they can reliably use abstract indices anywhere they could use concrete indices. That doesn’t appear to be true of the current proposal: in particular, programmers can slice between two abstract indices or between two concrete indices, but not between a mix of either. The Core Team feels it’s important to avoid this kind of inconsistent-feeling experience.

Along the same vein, abstract indices can only be anchored relative to the start and end of a collection. It is frequently useful to be able to anchor relative to a concrete index, e.g. to slice from an index returned by firstIndex(where:) to the fifth element past that. This pattern is not addressed by the current proposal, and it’s not clear whether the proposal can be extended this way in the future.

If necessary, the Core Team is willing to consider new language support for slicing subscripts, either through new syntax or through new interpretations of existing syntax.

The proposal author also requested an opportunity to revise the proposal’s treatment of certain methods on RangeReplaceableCollection.

Accordingly, SE-0265 is returned for revision.

Proposals in review

SE-0269: Increase availability of implicit self in @escaping closures when reference cycles are unlikely to occur is under review.

Modify the rule that all uses of self in escaping closures must be explicit by allowing for implicit uses of self in situations where the user has already made their intent explicit, or where strong reference cycles are otherwise unlikely to occur. There are two situations covered by this proposal. The first is when the user has explicitly captured self in the closure’s capture list, so that the following would compile without error:

class Test {
    var x = 0
    func execute(_ work: @escaping () -> Void) {
        work()
    }
    func method() {
        execute { [self] in
            x += 1
        }
    }
}

Secondly, this proposal would make implicit self available in escaping closures when self is a value type, so that the following would become valid:

struct Test {
    var x = 0
    func execute(_ work: @escaping () -> Void) {
        work()
    }
    func method() {
        execute { 
            x += 1
        }
    }
}

Swift Forums

Kaitlin Mahar shared a proposal to officially support the MongoDB Driver for Swift on the server.

We’re currently working on adding an asynchronous SwiftNIO-based version of our API to meet the SSWG incubation process minimal requirements. This is still in the design phase, and we’d love to hear feedback from the community on what we’ve come up with so far.

Current State and Future Plans We initially developed MongoSwift about 18 months ago with a synchronous API for use with the mobile/embedded version of MongoDB. However, we’ve increasingly shifted our focus toward providing a great server-side experience. We did work over the summer to implement automatic connection pooling in the driver and are now tackling the crucial asynchronous API.

The driver complies with nearly all of the MongoDB driver specifications, which are documents our team writes detailing everything from what a driver’s CRUD API should look like to how it should select which server to send a command to. These specs ensure consistent experiences using MongoDB across languages, while still allowing room for implementations and public APIs to vary in language-appropriate ways.

Owen Voorhees pitched a proposal to add multi-pattern and conditionally compiled catch clauses.

Currently, each catch clause in a do-catch statement may only contain a single pattern and where clause, and may not be conditionally compiled using a #if directive. This is inconsistent with the behavior of cases in switch statements which provide similar functionality. It also makes some error handling patterns awkward to express. This proposal extends the grammar of catch clauses to support #if and a comma-separated list of patterns (with optional where clauses), resolving this inconsistency.

Bryan Clark asked for ideas and concerns on how the GitHub package registry will work with the Swift Package Manager.

Our goal is to present a package management service specification which could be implemented by anyone, not only GitHub. This spec will include necessary API endpoints, package naming (URL spec), versioning system, and other elements required or in addition to the basics. We plan to open source our implementation (written in Go) such that others can contribute back to it and progress can be made in the open.

Gwen Mittertreiner has been working on adding support for Windows in the Swift Package Manager.

I’ve been making progress on Windows support for SPM, and one of the things I’d like to add now is adding Windows as a supported platform in the Package Description.

Paul Fechner pitched a proposal on Codable customization using Property Wrappers.

Currently the only method of adding custom Encoding/Decoding for Codable Types (without a custom implementation) is by adding options to the Encoder/Decoder. Although this is relatively fleshed out in JSON(En/De)Coder, there are still some major pain points.

  1. Options must be set for every (En/De)coder used
  2. The option Types are separate so e.g. dateEncodingStrategy and dateDecodingStrategy have separate implementations and are both required to handle full serialization.
  3. The options aren’t Portable and each (en/de)coder must supply their own options. Not even Swift’s own PropertyList(En/De)coder has support for the same options as it’s JSON cousin.
  4. It’s all or nothing. E.g. If a Type or it’s children need to use more than a single dateEncodingStrategy they must manage it themselves.

Finally

You have lacking documentation, and you have awesome documentation. (yes, the banner here is amazing, too.)