What follows is a proposal draft for initial feedback. This is a link to a gist version. The gist will be updated as feedback from community members is processed. The cut-and-paste into this post will not.
We would greatly appreciate your thoughtful feedback on this pitch. Thank you.
available to introduce
- Proposal: SE-nnnnnnnn
- Authors: Erica Sadun, Chris Lattner
- Review Manager: TBD
- Status: Awaiting implementation
available attribute documents characteristics of a declaration's lifecycle. The attribute specifies when a declaration became available on a given platform, and if it's been deprecated, obsoleted, or renamed. We feel there's room to further nuance
available . This proposal expands
available to introduce
discouraged , making declarations harder to accidentally use.
Swift-evolution thread: Proposing to expand
available to introduce
Public declarations exist for many reasons. Most typically, you want to create nice things. You expand your API surface, granting callers access to your declarations. That's not the only reason, though. Sometimes you expose implementation details when a declaration must be public. At other times, declarations are needed for compatibility, even when there's a newer more preferred approach.
As an API designer, you may want to steer adopters away from certain declarations. We believe you should be able to communicate when declarations are visible but should not be used. Your development environment should be able to pick up these cues and help coders to avoid using those calls.
For example, initializer requirements in the
LiteralConvertible protocols are redundant with the initializers on the type conforming to the protocols. They are meant to be implemented, but not called. Marking them
discouraged documents this reality. It also helps the development environment hide the discouraged declarations from cues like code completion.
You may also want to discourage a declaration that has been modernized or redesigned. Even when the original form is required for compatibility and cannot be deprecated, discouraging older forms helps move coders to newer declarations.
Discouraging visible-but-not-meant-for-use declarations provides tangible benefits:
- It increases coding safety.
- It supports clarity, as the current uses of
availabledo, by co-locating availability status information with code documentation.
- It offers a way to connect a declaration with development environment policy. A discouraged declaration may be warned or hidden from code completion depending on the implementation provided in an IDE.
We propose to extend
available , introducing
discouraged . A discouraged declaration is publicly accessible but not meant for general use.
available attribute currently supports the following arguments:
||The first platform or language version that supported the declaration.|
||A name that entirely replaces the old declaration, emitting a compile-time error.|
||A message to display when emitting a warning or error for deprecated and obsoleted declarations.|
||The first platform or language version where the declaration was deprecated.|
||The first platform or language version where the declaration was removed and can no longer be used.|
||Indicates a declaration is not available for a given platform.|
@available(swift, introduced: 4.0, message: "Please use failable String.init?(_:UTF8View) when in Swift 3.2 mode") @available(swift, deprecated: 5.0, renamed: "firstIndex(of:)") @available(*, deprecated, message: "all index distances are now of type Int") @available(iOS 14.0, watchOS 7.0, tvOS 14.0, *) @available(OSX, unavailable)
Our proposed design expands
||A message to display that describes why this declaration is discouraged|
Here's what this might look like. For implementation details, the message explains the circumstances leading to discouraging use. For updated and refactored APIs, the message drives "what to use" over "why this is discouraged".
@available(*, discouraged: "`_ShapeView` not for public use") @available(*, discouraged: "`IntersectionSolver` is O(N^2). Use `ConfluenceSolver` instead.") @available(discouraged: "Use newer Combine-based publisher instead")
Discouraged declarations can be enforced by the IDE experience in several ways:
- They could be suppressed from code completion or only show up in code completion once they are the only unambiguous option.
- They could given a strikethrough treatment.
Further, the new
discouraged argument can be picked up and integrated into Quick Help.
This change is purely additive and will not affect source compatibility.
Effect on ABI stability
Effect on API resilience
Not accepting the proposal and leaving
availability as currently designed.