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!
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:
cmpcodesizeis 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
cmpcodesizecan’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 to
cmpcodesize, such as CSV.
Commits and pull requests
Vedant Kumar fixed code coverage not being generated for top-level declarations.
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 proposal has been accepted with one modification: numeric values bridged to
NSNumberwill maintain their type identity (e.g., an
Int8bridged to an
NSNumbercan be cast via
Int8) while other instances of
NSNumber(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.
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 the
Anycomes 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
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
NSNullbrings 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:
NSNullis not widely used in Cocoa APIs, it is better to enable those APIs to work properly when
niloptional 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
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.