The last two weeks have brought us some exciting progress on Swift 5 and Xcode 9.3 (which brings us Swift 4.1). Regarding Xcode, we’re now on beta 3.

We can also expected some news on WWDC soon - last year, Apple announced WWDC on February 16th.

That being said, I don’t want to distract you from all the topics discussed in the newsletter. Thanks for reading!

Swift Unwrapped

46: Restricting cross-module struct initializers: Jesse and JP discuss the accepted SE-0189 proposal, which makes structs less source-breaking.

In 47: Revamping QuickLook Playground APIs, they discuss SE-0198 which, well, revamps the Quicklook Playground APIs.

News and community

Ted Kremenek announced that Swift will participate in Google Summer of Code this year!

With Xcode 9.3 beta 3 came a new tool for parsing code coverage output, xccov.

Erik Eckstein wrote a blog post on the official Swift.org blog on a new code size optimization mode in Swift 4.1. If you are already testing projects in Xcode 9.3, feel free to give this a try!

Joe Groff wrote a blog post on optimizing global constant data structures.

Paul Hudson gives on overview of what SE-0195: Introduce User-defined “Dynamic Member Lookup” Types brings to the table to make Swift more dynamic.

Keith Harrison explains why one of flatMap’s implementations is now called compactMap, as per SE-0187: Introduce Sequence.compactMap(_:).

Ben Cohen gave a talk on “Extending the Standard Library”.

Dave DeLong wrote a blog post about how he’d want to change how Swift deals with protocols.

Commits and pull requests

Xiaodi Wu merged a pull request that improves the performance of floating-point constants after Jens Persson discovered performance issues for Floats.

Takeru Chuganji merged a pull request with an improvement to Swift diagnostics, offering fix-its to insert numeric conversions when needed.

Accepted proposals

SE-0195: Introduce User-defined “Dynamic Member Lookup” Types was accepted.

On February 8 2018, the Core Team decided to accept this proposal.

After reviewing the feedback from the community, the Core Team felt the spelling of the attribute should remain as proposed — @dynamicMemberLookup. The alternative of @dynamic(...) was also considered, but the Core Team felt that spelling to be too close to the dynamic keyword and a potential source of confusion.

The rationale for the marker being an attribute instead of a protocol (as in the original proposal) was well-articulated by Chris Lattner in the review thread in that the marker protocol would not provide the expected affordances of a normal protocol.

Proposals in review

SE-0199: Adding toggle to Bool is under review.

For Bool variables, it is common to want to toggle the state of the variable. In larger (nested) structs, the duplication involved can become especially annoying:

myVar.prop1.prop2.enabled = !myVar.prop1.prop2.enabled

It’s also easy to make a mistake in the code above if there are multiple Bool vars. [The proposed solution is to] add a method toggle on Bool:

extension Bool {
    mutating func toggle() {
        self = !self
    }
}

This allows us to write the example above without duplication:

myVar.prop1.prop2.enabled.toggle()

Swift Forums

Max Moiseev pitched a proposal to improve the Standard Library’s Stride types.

With the addition of conditional conformances to the language, the result of zip(_:_:) can now be a Collection if both containers being zipped conform to Collection.

Unfortunately, without StrideTo conforming to Collection as proposed, expressions such as the following do not take advantage of zip’s conditional conformance.

zip([1,2,3], stride(from: 2, to: 42, by: 2))

The result of this expression only conforms to Sequence and as such provides none of the Collection APIs.

Daiki Matsudate pitched a proposal to introduce compactMapValue to Dictionary.

This proposal adds a combined filter/map operation to Dictionary, as a companion to the mapValues and filter methods introduced by SE-0165. The new compactMapValues operation corresponds to compactMap on Sequence.

We sometimes need to transform and filter values of a Dictionary at the same time, and Dictionary does not currently provide an operation that directly supports this.

Doug Gregor pitched a proposal to replace OpaquePointer.

I propose to replace the OpaquePointer struct with a deprecated typealias for UnsafeRawPointer. Then, change the import of C pointers-to-incomplete-types to produce UnsafeMutableRawPointer or UnsafeRawPointer, depending on whether the pointee const.

Doug also pitched eliminating NSObjectProtocol.

I propose to completely eliminate the NSObject protocol (called NSObjectProtocol) from Swift, leaving only a deprecated typealias (to AnyObject) as a backward-compatibility shim.

Dave DeLong pitched a proposal to add a #context keyword.

This would make it much easier to capture the context in which some code is executed rather than having to put file: StaticString = #file, line: UInt = #line parameters everywhere. A context: Context = #context would be much easier.

Letanyan Arumugam pitched a proposal to introduce a shorthand for offsetting startIndex and endIndex in subscripts.

Using collection indexes are a bit of a bother when you want to do simple slicing and a type is not indexed by Int.

For a simple example take the code here:

let s = "Hello, Swift"
let m = s[...s.index(s.startIndex, offsetBy: 4)]

The intent of advancing startIndex gets a bit muddled.

So to ease this I think we could add startIndex(offsetBy:) and endIndex(offsetBy:) to Collection.

Making the example above:

let s = "Hello, Swift"
let m = s[...s.startIndex(offsetBy: 4)]

@tanner0101 pitched a proposal that adds support for static dependencies in the Swift Package Manager.

This proposal introduces the ability to rely on a dependency statically (meaning that it will be available for import in your Package.swift file). The idea is that this will greatly increase the usability and customization of the Package.swift file.

Finally

The API does not work as expected? Can’t be. Its unit tested and all. Did you read its documentation?