on Thu Sep 22 2016, Graydon Hoare <swift-evolution@swift.org> wrote:
> Hi, > > The following is a proposal for a very minor extension of the @available > system. Hopefully uncontroversial! > > Thanks, > > -Graydon > > # Availability by Swift version > > * Proposal: [SE-NNNN](NNNN-available-by-swift-version.md) > * Authors: [Graydon Hoare](https://github.com/graydon) > * Review Manager: TBD > * Status: **Awaiting review** > > ## Introduction > > Swift's existing `@available(...)` attribute indicates the lifecycle of a > given declaration, either unconditionally or relative to a particular > platform or OS version range. > > It does not currently support indicating declaration lifecycle relative to > Swift language versions. This proposal seeks to extend it to do so. > > ## Motivation > > As the Swift language progresses from one version to the next, some > declarations will be added, renamed, deprecated or removed from the > standard library. Existing code written for earlier versions of Swift will > be supported through a `-swift-version N` command-line flag, that runs the > compiler in a backward-compatibility mode for the specified "effective" > language version. > > When running in a backward-compatibility mode, the set of available > standard library declarations should change to match expectations of older > code. Currently the only mechanism for testing a language version is the > compiler-control statement `#if swift(>= N)` which is a static construct: > it can be used to compile-out a declaration from the standard library, but > evolving the standard library through this mechanism would necessitate > compiling the standard library once for each supported older language > version. > > It would be preferable to compile the standard library _once_ for all > supported language versions, but make declarations _conditionally > available_ depending on the effective language version of a _user_ of the > library. The existing `@available(...)` attribute is similar to this > use-case, and this proposal seeks to extend the attribute to support it. > > ## Proposed solution > > The `@available(...)` attribute will be extended to support specifying > `swift` version numbers, in addition to its existing platform versions. > > As an example, an API that is removed in Swift 3.1 will be written > as: > > ~~~~ > @available(swift, obsoleted: 3.1) > class Foo { > //... > } > ~~~~ > > When compiling _user code_ in `-swift-version 3.0` mode, this declaration > would be available, but not when compiling in subsequent versions. > > ## Detailed design > > The token `swift` will be added to the set of valid initial arguments > to the `@available(...)` attribute. It will be treated similarly, > but slightly differently, than the existing platform arguments. In > particular: > > - As with platform-based availability judgments, a declaration's > `swift` version availability will default to available-everywhere > if unspecified. > > - A declaration's `swift` version availability will be considered > in logical conjunction with its platform-based availability. > That is, a given declaration will be available if and only > if it is _both_ available to the current effective `swift` version > _and_ available to the current deployment-target platform. > > - Similar to the abbreviated form of platform availability, an > abbreviated form `@available(swift N)` will be permitted as a synonym > for `@available(swift, introduced: N)`. However, adding `swift` to > a platform availability abbreviation list will not be allowed. That is, > writing the following examples is not permitted: > > - `@available(swift 3, *)` > - `@available(swift 3, iOS 10, *)` > > This restriction is due to the fact that platform-availability lists > are interpreted disjunctively (as a logical-_OR_ of their arguments), > and adding a conjunct (logical-_AND_) to such a list would make > the abbreviation potentially ambiguous to readers. > > ## Impact on existing code > > Existing code does not use this form of attribute, so will not be > affected at declaration-site. > > As declarations are annotated as unavailable or obsoleted via > this attribute, some user code may stop working, but the same risk exists > (with a worse user experience) in today's language any time declarations > are removed or conditionally-compiled out. The purpose of this proposal > is to provide a better user experience around such changes, and facilitate > backward-compatibility modes. > > ## Alternatives considered > > The main alternative is compiling libraries separately for each language > version and using `#if swift(>=N)` to conditionally include varying APIs. > For a library used locally within a single project, recompiling for a > specific language version may be appropriate, but for shipping the standard > library it is more economical to compile once with all declarations, and > select a subset based on language version. I am +1 on providing this facility but I am concerned that there are several kinds of library evolutions, which we know we'll need for the standard library, that it doesn't support. One example is our plan to inject a new base protocol of Comparable that will henceforth be known as Comparable (to support the <=> proposal). Another thing we think we'll need to do is to turn what was one type in Swift 3 into two distinct types in Swift 4. And these are just the needs we can anticipate at this early stage. I am concerned that we will need a system of much greater power and flexibility in the long term. -- -Dave _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution