The push and pull of Swift’s duality as an open source project that’s intimately tied to closed source products came to a culminating point this week, with the official release of Swift 3.0 🎉, coinciding with Xcode 8, the Swift Playgrounds iPad app, iOS 10, tvOS 10 and watchOS 3. One can’t help but respect the amount of effort it must have taken to coordinate so many moving parts and align all these releases.
The Swift 3.0 release post on swift.org provides a great overview of all the changes that were included, tips to migrate, links to an updated Swift book, and other details about the release.
Apple is the first to share that Swift 3 was made possible by a significant number of community contributions, so all you fine readers deserve a moment to celebrate… ok, break’s over, Swift 4 won’t write itself, so read on!
Starter tasks
The Swift team uses a Python script named cmpcodesize
to measure the size of Swift build products. Improving that script is one way to contribute to reducing the size of Swift code. If you know some Python, try these tasks:
- SR-407:
cmpcodesize
is capable of analyzing the size and segments of macOS Mach-O build products. Complete this task to allow it to analyze code size on Linux, by supporting the ELF object format. - SR-2595: The current output format for
cmpcodesize
can’t be easily parsed by other programs, making it hard to measure code size improvements and regressions over time. This task tracks adding additional output formats tocmpcodesize
, such as CSV.
Submit a task by sending a pull request or opening an issue.
Commits and pull requests
Dmitri Gribenko replaced the String hashing algorithm on non-ObjC platforms with an implementation of SipHash-1-3.
Vedant Kumar fixed code coverage not being generated for top-level declarations.
Doug Gregor added support for implicit self
in lazy var initializers, fixing SR-2203.
Anders Bertelrud improved the Xcode project generation to use a layered data model instead of print statements. Much nicer!
Michael Ilseman refactored around 3,000 lines of code, reducing the code browsing burden of the ClangImporter.
The one and only Jesse Squires updated the Swift Evolution status site to distinguish between withdrawn and rejected proposals.
Accepted proposals
Joe Groff’s proposal, SE-0139: Bridge Numeric Types to NSNumber
and Cocoa Structs to NSValue
, was accepted with modifications.
The proposal has been accepted with one modification: numeric values bridged to
NSNumber
will maintain their type identity (e.g., anInt8
bridged to anNSNumber
can be cast viaas!
/as?
to anInt8
) while other instances ofNSNumber
(e.g., those created in Objective-C) can be cast to any numeric type that can represent their value. This matches the existing bridging behavior introduced in id-to-Any bridging (SE-0116). The proposal text has been updated accordingly.
Joe Groff’s other proposal, SE-0140: Warn when Optional
converts to Any
, and bridge Optional
As Its Payload Or NSNull
, was accepted with one modification.
The proposal is accepted with one modification (described below).
Reviews on this proposal were mixed, with many expressing significant concerns about the ability to place an optional value into an
Any
, particularly when theAny
comes from a nonnull-annotated Objective-C API:
This behavior was introduced as part of id-as-Any bridging (SE-0116)). As an amendment to SE-0140, Swift will produce a warning when an optional value is converted to a value of type
Any
, e.g.,
Such a warning will address most accidental injections of optional values into
Any
, and the core team felt that this addresses accidental boxing of optional values better than leaving the opaque object types to fail fast in Objective-C code that inspects them (e.g., see this message for a negative review partly on these grounds).To the main point of this proposal, which is to bridging to either the payload or
NSNull
, the core team felt that:
- Bridging to the payload or
NSNull
brings to Objective-C code the same behavior that is already present in Swift’s type system, where an optional containing a payload can be dynamically casted to its payload type. For example, this is well-formed in Swift:
- While
NSNull
is not widely used in Cocoa APIs, it is better to enable those APIs to work properly whennil
optional values do get bridged than to have an opaque-to-Objective-C boxed type that does not work well with any Objective-C APIs.
Proposals in review
Andrew Trick’s proposal (SE-0138) from last week has been renamed to UnsafeRawBufferPointer
and its review period was extended by one week.
Mailing lists
Mishal Shah announced that Swift CI is now capable of testing combinations of pull requests. CI can even test pull requests made to two separate repositories! For example, if Swift PR #123 makes a change to the Swift standard library, and swift-corelibs-foundation PR #456 updates Foundation for that change, the two can be tested together by posting the following comment:
Pushkar Kulkarni and Philippe Hausler discussed important differences in bridging on Apple versus other platforms.
Pushkar: There’ve been a few bug reports related to the coercion problems between Swift and Foundation types on Linux. For example this one: https://bugs.swift.org/browse/SR-2477 (Double/Int don’t coerce with NSNumber on Linux).
Philippe: From a technical perspective it is not impossible to do however as of current reference type to structural type bridging is conflated with the objective c runtime being present (specifically present on Darwin targets). Personally I think we need a better answer than what we have today but I don’t see the winds changing in the immediate future to support ref type bridges uniformly in a cross platform manner.
Philippe has been advocating for better bridging support on non-Darwin platforms since Swift was open sourced nearly a year ago, and despite portability having been a strong goal for Swift 3, there are still important areas where the behavior varies between platforms, and this is one of them.
Finally
Sightings of the elusive Swift 3.1 have been reported in the wild, so please stay alert! You may have to migrate your apps again soon… 😳