(String, inout: Bool) -> Void
```
## Impact on existing code
This functionality is strictly additive, and does not break any existing
code: it only makes some previously ill-formed code well-formed, and
does not change the behavior of any well-formed code.
## Alternatives considered
The primary alternative here is to do nothing: Swift APIs will
continue to avoid keywords for argument labels, even when they are the
most natural word for the label, and imported APIs will either
continue to use backticks or will need to be renamed. This alternative
leaves a large number of imported APIs (nearly 200) requiring either
some level of renaming of the API or backticks at the call site.
A second alternative is to focus on `in` itself, which is by far the
most common keyword argument in imported APIs. In a brief survey of
imported APIs, `in` accounted for 90% of the conflicts with existing
keywords. Moreover, the keyword `in` is only used in two places in the
Swift grammar--for loops and closures--so it could be made
context-sensitive. However, this solution is somewhat more complicated
(because it requires more context-sensitive keyword parsing) and less
general.
================================================
FILE: proposals/0002-remove-currying.md
================================================
# Removing currying `func` declaration syntax
* Proposal: [SE-0002](0002-remove-currying.md)
* Author: [Joe Groff](https://github.com/jckarter)
* Status: **Implemented (Swift 3.0)**
* Implementation: [apple/swift@983a674](https://github.com/apple/swift/commit/983a674e0ca35a85532d70a3eb61e71a6d024108)
## Introduction
Curried function declaration syntax `func foo(x: Int)(y: Int)` is of limited
usefulness and creates a lot of language and implementation complexity. We
should remove it.
## Motivation
The presence of curried function syntax has knock-on effects, complicating
other language features:
- The presence of currying invites confusion over keyword rules and the
declaration name of functions. We've argued several times over whether
curried arguments represent a continuation of the function's arguments, begin
the argument list of a new function, or deserve to follow different rules
altogether.
- It has subtle interactions with 'var' and 'inout' argument
annotations. A curried function with 'inout' parameters anywhere other than
its first clause cannot be partially applied without surprising semantic
restrictions, limiting its usefulness. With 'var' parameters, there's the
question of at what level the 'var' gets bound; many users expect it at the
outermost partial application, but we currently bind at the innermost partial
application.
The idioms of the standard library, Cocoa, and most third-party code don't
really make ML-style argument currying of free functions profitable. In
Cocoa and the standard library, most things are methods, where we can still get
useful partial application via `self.method` and maybe someday `.map { f($0)
}` as well. The curried function design also predates the design of the
keyword argument model. We have plans to move away
from the arguments-are-a-single-tuple model too (which is already belied by
things like `@autoclosure` and `inout`), which pushes us even further away from
the ML argument model.
Many users have observed the uselessness of our currying feature, and asked for
Scala-style `f(_, 1)` freeform partial application as an alternative. The fact
that even functionally-oriented users don't see much value in our currying
feature makes me feel like we might be better off without it. It definitely fails
the "would we add it if we didn't have it already" test.
## Detailed design
We remove support for multiple argument patterns in `func` declarations,
reducing the grammar for `func-signature` to allow only one `argument` clause.
For migration purposes, existing code that uses currying declaration syntax
can be transformed to explicitly return a closure instead:
```swift
// Before:
func curried(x: Int)(y: String) -> Float {
return Float(x) + Float(y)!
}
// After:
func curried(x: Int) -> (String) -> Float {
return {(y: String) -> Float in
return Float(x) + Float(y)!
}
}
```
I don't propose changing the semantics of methods, which formally remain
functions of type `Self -> Args -> Return`.
## Impact on existing code
This is removing a language feature, so will obviously break existing code
that uses the feature. We feel that currying is of sufficiently marginal
utility, runs against the grain of emerging language practice, and there's a
reasonable automatic migration, so the impact is acceptable in order to
simplify the language.
## Alternatives considered
The alternative would be to preserve currying as-is, which as discussed above,
is not ideal. Although I don't propose taking any immediate action, future
alternative designs to provide similar functionality in a more idiomatic way
include:
- Scala-like ad-hoc partial application syntax, such that something like
`foo(_, bar: 2)` would be shorthand for `{ x in foo(x, bar: 2) }`. This
has the benefit of arguably being more readable with our keyword-argument-
oriented API design, and also more flexible than traditional currying,
which requires argument order to be preconsidered by the API designer.
- Method and/or operator slicing syntax. We have `self.method` to partially
bind a method to its `self` parameter, and could potentially add
`.method(argument)` to partially bind a method to its non-self arguments,
which would be especially useful for higher-order methods like `map`
and `filter`. Haskell-like `(2+)`/`(+2)` syntax for partially applying
operators might also be nice.
================================================
FILE: proposals/0003-remove-var-parameters.md
================================================
# Removing `var` from Function Parameters
* Proposal: [SE-0003](0003-remove-var-parameters.md)
* Author: [Ashley Garland](https://github.com/bitjammer)
* Review Manager: [Joe Pamer](https://github.com/jopamer)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/se-0003-removing-var-from-function-parameters-and-pattern-matching/1230)
* Implementation: [apple/swift@8a5ed40](https://github.com/apple/swift/commit/8a5ed405bf1f92ec3fc97fa46e52528d2e8d67d9)
## Note
This proposal underwent some major changes from its original form. See
the end of this document for historical information and why this
proposal changed.
## Introduction
There has been some confusion of semantics when a function parameter is
marked as `inout` compared to `var`. Both give a mutable local copy of a
value but parameters marked `inout` are automatically written back.
Function parameters are immutable by default:
```swift
func foo(i: Int) {
i += 1 // illegal
}
func foo(var i: Int) {
i += 1 // OK, but the caller cannot observe this mutation.
}
```
Here, the *local copy* of `x` mutates but the write does not propagate back to
the original value that was passed, so the caller can never observe the change
directly. For that to happen to value types, you have to mark the parameter
with `inout`:
```swift
func doSomethingWithVar(var i: Int) {
i = 2 // This will NOT have an effect on the caller's Int that was passed, but i can be modified locally
}
func doSomethingWithInout(inout i: Int) {
i = 2 // This will have an effect on the caller's Int that was passed.
}
var x = 1
print(x) // 1
doSomethingWithVar(x)
print(x) // 1
doSomethingWithInout(&x)
print(x) // 2
```
## Motivation
Using `var` annotations on function parameters have limited utility,
optimizing for a line of code at the cost of confusion with `inout`,
which has the semantics most people expect. To emphasize the fact these
values are unique copies and don't have the write-back semantics of
`inout`, we should not allow `var` here.
In summary, the problems that motivate this change are:
- `var` is often confused with `inout` in function parameters.
- `var` is often confused to make value types have reference semantics.
- Function parameters are not refutable patterns like in *if-*,
*while-*, *guard-*, *for-in-*, and *case* statements.
## Design
This is a trivial change to the parser. In Swift 2.2, a deprecation
warning will be emitted while in Swift 3 it will become an error.
## Impact on existing code
As a purely mechanical migration away from these uses of `var`, a temporary
variable can be immediately introduced that shadows the immutable copy in all of
the above uses. For example:
```swift
func foo(i: Int) {
var i = i
}
```
However, shadowing is not necessarily an ideal fix and may indicate an
anti-pattern. We expect users of Swift to rethink some of their existing
code where these are used but it is not strictly necessary to react to
this language change.
## Alternatives considered
This proposal originally included removal of `var` bindings for all
refutable patterns as well as function parameters.
[Original SE-0003 Proposal](https://github.com/swiftlang/swift-evolution/blob/8cd734260bc60d6d49dbfb48de5632e63bf200cc/proposals/0003-remove-var-parameters-patterns.md)
Removal of `var` from refutable patterns was reconsidered due to the
burden it placed on valid mutation patterns already in use in Swift 2
code. You can view the discussion on the swift-evolution mailing list
here:
[Initial Discussion of Reconsideration](https://forums.swift.org/t/reconsidering-se-0003-removing-var-from-function-parameters-and-pattern-matching/1159)
The rationale for a final conclusion was also sent to the
swift-evolution list, which you can view here:
[Note on Revision of the Proposal](https://forums.swift.org/t/se-0003-removing-var-from-function-parameters-and-pattern-matching/1230)
================================================
FILE: proposals/0004-remove-pre-post-inc-decrement.md
================================================
# Remove the `++` and `--` operators
* Proposal: [SE-0004](0004-remove-pre-post-inc-decrement.md)
* Author: [Chris Lattner](https://github.com/lattner)
* Status: **Implemented (Swift 3.0)**
* Implementation: [apple/swift@8e12008](https://github.com/apple/swift/commit/8e12008d2b34a605f8766310f53d5668f3d50955)
## Introduction
The increment/decrement operators in Swift were added very early in the
development of Swift, as a carry-over from C. These were added without much
consideration, and haven't been thought about much since then. This document
provides a fresh look at them, and ultimately recommends we just remove them
entirely, since they are confusing and not carrying their weight.
As a quick refresher, there are four operators in this family:
```swift
let a = ++x // pre-increment - returns input value after mutation
let b = x++ // post-increment - returns copy of input value before mutation
let c = --x // pre-decrement - returns input value after mutation
let d = x-- // post-decrement - returns copy of input value before mutation
```
However, the result value of these operators are frequently ignored.
## Advantages of These Operators
The primary advantage of these operators is their expressive capability. They
are shorthand for (e.g.) `x += 1` on a numeric type, or `x.advance()` on an
iterator-like value. When the return value is needed, the Swift `+=` operator
cannot be used in-line, since (unlike C) it returns `Void`.
The second advantage of Swift supporting this family of operators is continuity
with C, and other common languages in the extended C family (C++, Objective-C,
Java, C#, Javascript, etc). People coming to Swift from these other languages
may reasonably expect these operators to exist. That said, there are also
popular languages which have kept the majority of C operators but dropped these
(e.g. Python).
## Disadvantages of These Operators
1. These operators increase the burden to learn Swift as a first programming
language - or any other case where you don't already know these operators from a
different language.
2. Their expressive advantage is minimal - `x++` is not much shorter
than `x += 1`.
3. Swift already deviates from C in that the `=`, `+=` and other assignment-like
operations returns `Void` (for a number of reasons). These operators are
inconsistent with that model.
4. Swift has powerful features that eliminate many of the common reasons you'd
use `++i` in a C-style for loop in other languages, so these are relatively
infrequently used in well-written Swift code. These features include
the `for-in` loop, ranges, `enumerate`, `map`, etc.
5. Code that actually uses the result value of these operators is often
confusing and subtle to a reader/maintainer of code. They encourage "overly
tricky" code which may be cute, but difficult to understand.
6. While Swift has well defined order of evaluation, any code that depended on
it (like `foo(++a, a++)`) would be undesirable even if it was well-defined.
7. These operators are applicable to relatively few types: integer and floating
point scalars, and iterator-like concepts. They do not apply to complex numbers,
matrices, etc.
Finally, these fail the metric of "if we didn't already have these, would we add
them to Swift 3?"
## Proposed Approach
We should just drop these operators entirely. In terms of roll-out, we should
deprecate them in the Spring Swift 2.x release (with a nice Fixit hint to cover
common cases), and remove them completely in Swift 3.
## Alternatives considered
Simplest alternative: we could keep them. More interesting to consider, we could
change these operators to return Void. This solves some of the problems above,
but introduces a new question: once the result is gone, the difference between
the prefix and postfix form also vanishes. Given that, we would have to pick
between these unfortunate choices:
1) Keep both `x++` and `++x` in the language, even though they do the same
thing.
2) Drop one of `x++` or `++x`. C++ programmers generally prefer the prefix
forms, but everyone else generally prefers the postfix forms. Dropping either
one would be a significant deviation from C.
Despite considering these options carefully, they still don't justify the
complexity that the operators add to Swift.
================================================
FILE: proposals/0005-objective-c-name-translation.md
================================================
# Better Translation of Objective-C APIs Into Swift
* Proposal: [SE-0005](0005-objective-c-name-translation.md)
* Authors: [Doug Gregor](https://github.com/DougGregor), [Dave Abrahams](https://github.com/dabrahams)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-with-modification-se-0005-better-translation-of-objective-c-apis-into-swift/1668)
## Reviewer notes
This review is part of a group of three related reviews, running
concurrently:
* [SE-0023 API Design Guidelines](0023-api-guidelines.md)
([Review](https://forums.swift.org/t/review-se-0023-api-design-guidelines/1162))
* [SE-0006 Apply API Guidelines to the Standard Library](0006-apply-api-guidelines-to-the-standard-library.md)
([Review](https://forums.swift.org/t/review-se-0006-apply-api-guidelines-to-the-standard-library/1163))
* [SE-0005 Better Translation of Objective-C APIs Into Swift](0005-objective-c-name-translation.md)
([Review](https://forums.swift.org/t/review-se-0005-better-translation-of-objective-c-apis-into-swift/1164))
These reviews are running concurrently because they interact strongly
(e.g., an API change in the standard library will correspond to a
particular guideline, or an importer rule implements a particular
guideline, etc.). Because of these interactions, and to keep
discussion manageable, we ask that you:
* **Please get a basic understanding of all three documents** before
posting review commentary
* **Please post your review of each individual document in response to
its review announcement**. It's okay (and encouraged) to make
cross-references between the documents in your review where it helps
you make a point.
## Introduction
This proposal describes how we can improve Swift's "Clang Importer", which is responsible for mapping C and Objective-C APIs into Swift, to translate the names of Objective-C functions, types, methods, properties, etc. into names that more closely align with the [Swift API Design Guidelines][api-design-guidelines] being developed as part of Swift 3. Our approach focuses on the differences between the Objective-C [Coding Guidelines for Cocoa][objc-cocoa-guidelines] and the Swift API Design Guidelines, using some simple linguistic analysis to aid the automatic translation from Objective-C names to more "Swifty" names.
The results of this transformation can be seen in the [Swift 3 API Guidelines Review](https://github.com/apple/swift-3-api-guidelines-review) repository, which contains Swift projections of Objective-C APIs in Swift 2 ([`swift-2` branch](https://github.com/apple/swift-3-api-guidelines-review/tree/swift-2)) and Swift 3 ([`swift-3` branch](https://github.com/apple/swift-3-api-guidelines-review/tree/swift-3)) along with partially-migrated sample code. One can also see the overall changes by [comparing the two branches](https://github.com/apple/swift-3-api-guidelines-review/compare/swift-2...swift-3).
## Motivation
The Objective-C [Coding Guidelines for Cocoa][objc-cocoa-guidelines]
provide a framework for creating clear, consistent APIs in
Objective-C, where they work extraordinarily well. However, Swift is a
different language: in particular, it is strongly typed and provides
type inference, generics, and overloading. As a result, Objective-C
APIs that feel right in Objective-C can feel wordy when used in
Swift. For example:
```swift
let content = listItemView.text.stringByTrimmingCharactersInSet(
NSCharacterSet.whitespaceAndNewlineCharacterSet())
```
The APIs used here follow the Objective-C guidelines. A more "Swifty"
version of the same code might instead look like this:
```swift
let content = listItemView.text.trimming(.whitespaceAndNewlines)
```
The latter example more closely adheres to the [Swift API Design
Guidelines][api-design-guidelines], in particular, omitting "needless"
words that restate the types already enforced by the compiler (view,
string, character set, etc.). The goal of this proposal is to make
imported Objective-C feel more "Swifty", providing a more fluid
experience for Swift programmers using Objective-C APIs.
The solution in this proposal applies equally to the Objective-C
frameworks (e.g., all of Cocoa and Cocoa Touch) and any Objective-C
APIs that are available to Swift in mix-and-match projects. Note that
the [Swift core libraries][core-libraries]
reimplement the APIs of Objective-C frameworks, so any API changes to
those frameworks (Foundation, XCTest, etc.) will be reflected in the
Swift 3 implementations of the core libraries.
## Proposed solution
The proposed solution involves identifying the differences between the
Objective-C [Coding Guidelines for Cocoa][objc-cocoa-guidelines] and
the [Swift API Design Guidelines][api-design-guidelines] to build a
set of transformations that map from the former to the latter based on
the guidelines themselves and other observed conventions in
Objective-C. This is an extension of other heuristics in the Clang
importer that translate names, e.g., the mapping of global enum
constants into Swift's cases (which strips common prefixes from the
enum constant names) and the mapping from Objective-C factory methods
(e.g., `+[NSNumber numberWithBool:]`) to Swift initializers
(`NSNumber(bool: true)`).
The heuristics described in this proposal will require iteration,
tuning, and experimentation across a large body of Objective-C APIs to
get right. Moreover, it will not be perfect: some APIs will
undoubtedly end up being less clear in Swift following this
translation than they had been before. Therefore, the goal is to make
the vast majority of imported Objective-C APIs feel more "Swifty", and
allow the authors of Objective-C APIs that end up being less clear to
address those problems on a per-API basis via annotation within the
Objective-C headers.
The proposed solution involves several related changes to the Clang importer:
1. **Generalize the applicability of the `swift_name` attribute**: The
Clang `swift_name` attribute currently allows limited renaming of enum
cases and factory methods. It should be generalized to allow arbitrary
renaming of any C or Objective-C entity when it is imported into
Swift, allowing authors of C or Objective-C APIs more fine-grained
control over the process.
2. **Prune redundant type names**: The Objective-C Coding Guidelines
for Cocoa require that the method describe each argument. When
those descriptions restate the type of the corresponding parameter,
the name conflicts with the
[omit needless words](https://swift.org/documentation/api-design-guidelines#omit-needless-words)
guideline for Swift APIs. Therefore, we prune these type names
during import.
3. **Add default arguments**: In cases where the Objective-C API strongly hints at the need for a default argument, infer the default argument when importing the API. For example, an option-set parameter can be defaulted to `[]`.
4. **Add first argument labels**: If the first parameter of a method
is defaulted,
[it should have an argument label](https://swift.org/documentation/api-design-guidelines#first-argument-label). Determine
a first argument label for that method.
5. **Prepend "is" to Boolean properties**:
[Boolean properties should read as assertions on the receiver](https://swift.org/documentation/api-design-guidelines#boolean-assertions),
but the Objective-C Coding Guidelines for Cocoa
[prohibit the use of "is" on properties](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE). Import
such properties with "is" prepended.
6. **Lowercase values**: The Swift API Design Guidelines have non-type
declarations lowercased. Lowercase non-prefixed values whenever they
are imported, including enumerators (whether they end up in Swift as
enum cases or option sets) and any other properties/functions (e.g., a
property named `URLHandler` will be lowercased to `urlHandler`).
7. **Adopt Comparable to classes that implement** `compare(_:) -> NSComparisonResult`: The objective-c classes that implement compare all have declared a capability of being compared in an ordered manner. `Comparable` formalizes this declaration into an implementable operator by the import process.
To get a sense of what these transformations do, consider a portion of
the imported `UIBezierPath` API in Swift 2:
```swift
class UIBezierPath : NSObject, NSCopying, NSCoding {
convenience init(ovalInRect: CGRect)
func moveToPoint(_: CGPoint)
func addLineToPoint(_: CGPoint)
func addCurveToPoint(_: CGPoint, controlPoint1: CGPoint, controlPoint2: CGPoint)
func addQuadCurveToPoint(_: CGPoint, controlPoint: CGPoint)
func appendPath(_: UIBezierPath)
func bezierPathByReversingPath() -> UIBezierPath
func applyTransform(_: CGAffineTransform)
var empty: Bool { get }
func containsPoint(_: CGPoint) -> Bool
func fillWithBlendMode(_: CGBlendMode, alpha: CGFloat)
func strokeWithBlendMode(_: CGBlendMode, alpha: CGFloat)
func copyWithZone(_: NSZone) -> AnyObject
func encodeWithCoder(_: NSCoder)
}
```
And the same API imported under our current, experimental implementation of this proposal:
```swift
class UIBezierPath : NSObject, NSCopying, NSCoding {
convenience init(ovalIn rect: CGRect)
func move(to point: CGPoint)
func addLine(to point: CGPoint)
func addCurve(to endPoint: CGPoint, controlPoint1 controlPoint1: CGPoint, controlPoint2 controlPoint2: CGPoint)
func addQuadCurve(to endPoint: CGPoint, controlPoint controlPoint: CGPoint)
func append(_ bezierPath: UIBezierPath)
func reversing() -> UIBezierPath
func apply(_ transform: CGAffineTransform)
var isEmpty: Bool { get }
func contains(_ point: CGPoint) -> Bool
func fill(_ blendMode: CGBlendMode, alpha alpha: CGFloat)
func stroke(_ blendMode: CGBlendMode, alpha alpha: CGFloat)
func copy(with zone: NSZone = nil) -> AnyObject
func encode(with aCoder: NSCoder)
}
```
In the latter case, a number of words that restated type information
in the original APIs have been pruned. The result is closer to
following the Swift API Design Guidelines. For example, this shows
that Swift developers can now copy any object conforming to the
NSCopying with a simple call to `foo.copy()` instead of calling
`foo.copyWithZone(nil)`.
## Implementation Experience
An experimental implementation of this proposal is available in the
main Swift repository. There are a set of compiler flags that one can
use to see the results of applying this proposal to imported
Objective-C APIs (e.g., via the script in
`utils/omit-needless-words.py`) and to Swift code itself. The flags
are:
* `-enable-omit-needless-words`: this flag enables most of the changes
to the Clang importer (bullets 1, 2, 4, and 5 in the prior
section). It is currently suitable only for printing the Swift
interface to Objective-C modules (e.g., via `swift-ide-test`) in the
Swift master branch and [Swift 2.2 branch][swift-2_2-branch], and is enabled on the [Swift 3 API Guidelines branch][swift-3-api-guidelines-branch].
* `-enable-infer-default-arguments`: this flag enables inference of
default arguments in the Clang importer (bullet 3 in the prior
section).
* `-swift3-migration`: only available on the [Swift 2.2
branch][swift-2_2-branch], this flag performs basic migration from
Swift 2 names to the Swift 3 names via Fix-Its. Tied together with
other compiler flags (e.g., `-fixit-code`, `-fixit-all`) and a
script to collect and apply Fix-Its (in
`utils/apply-fixit-edits.py`), this flag provides a rudimentary
migrator that lets us see how Swift code would look under the
proposed changes, updating both declarations and use sites.
To actually get the "Swift 3 experience" of compiling code using these
names, one can use the [Swift 3 API Guidelines
branch][swift-3-api-guidelines-branch], which enables these features
by default along with the changes to the standard library.
## Detailed design
This section details the experimental implementation of rules 2-5 in prose. The actual implementation is available in the Swift source tree, mostly in the `omitNeedlessWords` functions of [lib/Basic/StringExtras.cpp](https://github.com/apple/swift/blob/master/lib/Basic/StringExtras.cpp).
The descriptions in this section are described in terms of the incoming Objective-C API. For example, Objective-C method names are "selectors", e.g., `startWithQueue:completionHandler:` is a selector with two selector pieces, `startWithQueue` and `completionHandler`. A direct mapping of this name into Swift would produce `startWithQueue(_:completionHandler:)`.
### Prune redundant type names
Objective-C API names often contain names of parameter and/or result
types that would be omitted in a Swift API. The following rules are
designed to identify and remove these
words. [[Omit Needless Words](https://swift.org/documentation/api-design-guidelines#omit-needless-words)]
#### Identifying type names
The matching process described below searches in a selector piece for
a suffix of a string called the **type name**, which is defined as follows:
* For most Objective-C types, the *type name* is the name under which
Swift imports the type, ignoring nullability. For example,
|Objective-C type | *Type Name* |
|-----------------------|--------------------------------------------|
|`float` |`Float` |
|`nullable NSString` |`String` |
|`UIDocument` |`UIDocument` |
|`nullable UIDocument` |`UIDocument` |
|`NSInteger` |`NSInteger` |
|`NSUInteger` |`NSUInteger` |
|`CGFloat` |`CGFloat` |
* When the Objective-C type is a block, the *type name* is "`Block`."
* When the Objective-C type is a pointer- or reference-to-function,
the *type name* is "`Function`."
* When the Objective-C type is a typedef other than `NSInteger`,
`NSUInteger`, or `CGFloat` (which follow the first rule above), the
*type name* is that of the underlying type. For example, when the
Objective-C type is `UILayoutPriority`, which is a typedef for
`float`, we try to match the string
"`Float`". [[Compensate for Weak Type Information](https://swift.org/documentation/api-design-guidelines#weak-type-information)]
#### Matching
In order to prune a redundant type name from a selector piece, we
need to match a substring of the selector that identifies the type.
A couple of basic rules govern all matches:
* **Matches begin and end at word boundaries** in both type names and
selector pieces. Word boundaries occur at the beginning and end of
a string, and before every capital letter.
Treating every capital letter as the beginning of a word allows us
to match uppercased acronyms without maintaining a special lists of
acronyms or prefixes:
func documentForURL(_: NSURL) -> NSDocument?
while preventing partial-word mismatches:
var thumbnailPreview : UIView // not matched
* **Matched text extends to the end of the type name**. Because we
accept a match for *any suffix* of the type name, this code:
func constraintEqualToAnchor(anchor: NSLayoutAnchor) -> NSLayoutConstraint?
can be pruned as follows:
func constraintEqualTo(anchor: NSLayoutAnchor) -> NSLayoutConstraint?
Conveniently, matching by suffix also means that module prefixes
such as `NS` do not prevent matching or pruning.
Matches are a sequence of one or more of the following:
* **Basic matches**
* Any substring of the selector piece matches an identical
substring of the type name, e.g., `String` in `appendString`
matches `String` in `NSString`:
func appendString(_: NSString)
* `Index` in the selector piece matches `Int` in the type name:
func characterAtIndex(_: Int) -> unichar
* **Collection matches**
* `Indexes` or `Indices` in the selector piece matches `IndexSet` in
the type name:
func removeObjectsAtIndexes(_: NSIndexSet)
* A plural noun in the selector piece matches a collection type name
if the noun's singular form matches the name of the collection's
element type:
func arrangeObjects(_: [AnyObject]) -> [AnyObject]
* **Special suffix matches**
* The empty string in the selector piece matches `Type` or `_t` in the type name:
func writableTypesForSaveOperation(_: NSSaveOperationType) -> [String]
func objectForKey(_: KeyType) -> AnyObject
func startWithQueue(_: dispatch_queue_t, completionHandler: MKMapSnapshotCompletionhandler)
* The empty string in the selector piece matches *one or more digits
followed by "D"* in the type name:
func pointForCoordinate(_: CLLocationCoordinate2D) -> NSPoint
In the examples above, the italic text is effectively skipped, so the
bold part of the selector piece can be matched and pruned.
#### Pruning Restrictions
The following restrictions govern the pruning steps listed in the
next section. If any step would violate one of these rules, it is
skipped.
* **Never make a selector piece entirely empty**.
* **Never transform the first selector piece into a Swift keyword**,
to avoid forcing the user to escape it with backticks. In Swift, the
first Objective-C selector piece becomes:
* the base name of a method
* or the full name of a property
neither of which can match a Swift keyword without forcing the
user to write backticks. For example,
extension NSParagraphStyle {
class func defaultParagraphStyle() -> NSParagraphStyle
}
let defaultStyle = NSParagraphStyle.defaultParagraphStyle() // OK
would become:
extension NSParagraphStyle {
class func `default`() -> NSParagraphStyle
}
let defaultStyle = NSParagraphStyle.`default`() // Awkward
By contrast, later selector pieces become argument labels, which
are allowed to match Swift keywords without requiring backticks:
receiver.handle(someMessage, for: somebody) // OK
* **Never transform a name into "get", "set", "with", "for", or
"using"**, just to avoid creating absurdly vacuous names.
* **Never prune a suffix from a parameter introducer unless the suffix
is immediately preceded by a preposition, verb, or gerund**.
This heuristic has the effect of preventing us from breaking up
sequences of nouns that refer to a parameter. Dropping just the
suffix of a noun phrase tends to imply something unintended about
the parameter that follows. For example,
func setTextColor(_: UIColor)
...
button.setTextColor(.red()) // clear
If we were to drop `Color`, leaving just `Text`, call sites
would become confusing:
func setText(_: UIColor)
...
button.setText(.red()) // appears to be setting the text!
Note: We don't maintain a list of nouns, but if we did, this
rule could be more simply phrased as "don't prune a suffix
leaving a trailing noun before a parameter".
* **Never prune a suffix from the base name of a method that matches a property of the enclosing class**:
This heuristic has the effect of preventing us from producing
too-generic names for methods that conceptually modify a property
of the class.
var gestureRecognizers: [UIGestureRecognizer]
func addGestureRecognizer(_: UIGestureRecognizer)
If we were to drop `GestureRecognizer`, leaving just `add`, we end
up with a method that conceptually modifies the
`gestureRecognizers` property but uses an overly generic name to
do so:
var gestureRecognizers: [UIGestureRecognizer]
func add(_: UIGestureRecognizer) // should indicate that we're adding to the property
#### Pruning Steps
The following pruning steps are performed in the order
shown:
1. **Prune the result type from the head of type-preserving
transforms**. Specifically, when
* the receiver type is the same as the result type
* and the type name is matched at the head of the first selector piece
* and the match is followed by a preposition
then prune the match.
You can think of the affected operations as properties or
non-mutating methods that produce a transformed version of the
receiver. For example:
extension NSColor {
func colorWithAlphaComponent(_: CGFloat) -> NSColor
}
let translucentForeground = foregroundColor.colorWithAlphaComponent(0.5)
becomes:
extension NSColor {
func withAlphaComponent(_: CGFloat) -> NSColor
}
let translucentForeground = foregroundColor.withAlphaComponent(0.5)
2. **Prune an additional hanging "By"**. Specifically, if
* anything was pruned in step 1
* and the remaining selector piece begins with "`By`" *followed by a gerund*,
then prune the initial "`By`" as well.
This heuristic allows us to arrive at usage of the form `a =
b.frobnicating(c)`. For example:
extension NSString {
func stringByApplyingTransform(_: NSString, reverse: Bool) -> NSString?
}
let sanitizedInput = rawInput.stringByApplyingTransform(NSStringTransformToXMLHex, reverse: false)
becomes:
extension NSString {
func applyingTransform(_: NSString, reverse: Bool) -> NString?
}
let sanitizedInput = rawInput.applyingTransform(NSStringTransformToXMLHex, reverse: false)
3. **Prune a match for any type name in the signature from the tail of
the preceding selector piece**. Specifically,
|From the tail of: |Prune a match for: |
|------------------------------------------------|--------------------------------|
|a selector piece that introduces a parameter |the parameter type name |
|the name of a property |the property type name |
|the name of a zero-argument method |the return type name |
For example,
extension NSDocumentController {
func documentForURL(_ url: NSURL) -> NSDocument? // parameter introducer
}
extension NSManagedObjectContext {
var parentContext: NSManagedObjectContext? // property
}
extension UIColor {
class func darkGrayColor() -> UIColor // zero-argument method
}
...
myDocument = self.documentForURL(locationOfFile)
if self.managedObjectContext.parentContext != changedContext { return }
foregroundColor = .darkGrayColor()
becomes:
extension NSDocumentController {
func documentFor(_ url: NSURL) -> NSDocument?
}
extension NSManagedObjectContext {
var parent : NSManagedObjectContext?
}
extension UIColor {
class func darkGray() -> UIColor
}
...
myDocument = self.documentFor(locationOfFile)
if self.managedObjectContext.parent != changedContext { return }
foregroundColor = .darkGray()
3. **Prune a match for the enclosing type from the base name of a method so long as the match starts after a verb**. For example,
extension UIViewController {
func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)? = nil)
}
becomes:
extension UIViewController {
func dismissAnimated(flag: Bool, completion: (() -> Void)? = nil)
}
##### Why Does Order Matter?
Some steps below prune matches from the head of the first selector
piece, and some prune from the tail. When [pruning restrictions](#pruning-restrictions)
prevent both the head and tail from being pruned, prioritizing
head-pruning steps can keep method families together. For example,
in NSFontDescriptor:
```swift
func fontDescriptorWithSymbolicTraits(_: NSFontSymbolicTraits) -> NSFontDescriptor
func fontDescriptorWithSize(_: CGFloat) -> UIFontDescriptor
func fontDescriptorWithMatrix(_: CGAffineTransform) -> UIFontDescriptor
...
```
becomes:
func withSymbolicTraits(_: UIFontDescriptorSymbolicTraits) -> UIFontDescriptor
func withSize(_: CGFloat) -> UIFontDescriptor
func withMatrix(_: CGAffineTransform) -> UIFontDescriptor
...
If we instead began by pruning `SymbolicTraits` from the tail of
the first method name, the prohibition against creating absurdly
vacuous names would prevent us from pruning "`fontDescriptorWith`"
down to "`with`", resulting in:
func fontDescriptorWith(_: NSFontSymbolicTraits) -> NSFontDescriptor // inconsistent
func withSize(_: CGFloat) -> UIFontDescriptor
func withMatrix(_: CGAffineTransform) -> UIFontDescriptor
...
#### Add Default Arguments
For any method that is not a single-parameter setter, default
arguments are added to parameters in the following cases:
* **Nullable trailing closure parameters** are given a default value of `nil`.
* **Nullable NSZone parameters** are given a default value of `nil`. Zones are essentially unused in Swift and should always be ``nil``.
* **Option set types** whose type name contain the word "Options" are given a default value of `[]` (the empty option set).
* **NSDictionary parameters** with names that involve "options", "attributes", or "info" are given a default value of `[:]`.
Together, these heuristics allow code like:
rootViewController.presentViewController(alert, animated: true, completion: nil)
UIView.animateWithDuration(
0.2, delay: 0.0, options: [], animations: { self.logo.alpha = 0.0 }) {
_ in self.logo.hidden = true
}
to become:
```swift
rootViewController.present(alert, animated: true)
UIView.animateWithDuration(
0.2, delay: 0.0, animations: { self.logo.alpha = 0.0 }) { _ in self.logo.hidden = true }
```
#### Add First Argument Labels
If the first selector piece contains a preposition, **split the first
selector piece at the last preposition**, turning everything
starting with the last preposition into a *required* label for the
first argument.
As well as creating first argument label for a significant number of
APIs, this heuristic eliminates words that refer only to the first
argument from call sites where the argument's default value is
used. For example, instead of:
extension UIBezierPath {
func enumerateObjectsWith(_: NSEnumerationOptions = [], using: (AnyObject, UnsafeMutablePointer) -> Void)
}
array.enumerateObjectsWith(.Reverse) { // OK
// ..
}
array.enumerateObjectsWith() { // ?? With what?
// ..
}
we get:
extension NSArray {
func enumerateObjects(options _: NSEnumerationOptions = [], using: (AnyObject, UnsafeMutablePointer) -> Void)
}
array.enumerateObjects(options: .Reverse) { // OK
// ..
}
array.enumerateObjects() { // OK
// ..
}
#### Use getter names for Boolean Properties
**For Boolean properties, use the name of the getter as the property
name in Swift*. For example:
```swift
@interface NSBezierPath : NSObject
@property (readonly,getter=isEmpty) BOOL empty;
```
will become
extension NSBezierPath {
var isEmpty: Bool
}
if path.isEmpty { ... }
### Conformance of implementers of compare method
Currently, in comparing protocols, for example developers usually have
to extend `NSDate` to make it to conform to `Comparable`, or use
`compare(_:) -> NSComparisonResult` method of `NSDate` directly. In
this case Using comparison operators on `NSDate`s will make the code
more readable, such as `someDate < today`, rather than
`someDate.compare(today) == .OrderedAscending`. Since the import process
can determine if a class implements the objective-c method for
comparison all classes that implement this method will then be imported
as adopting `Comparable`.
A survey of Foundation classes reveals not just NSDate but a few
other classes that would be affected by this change.
```swift
func compare(other: NSDate) -> NSComparisonResult
func compare(decimalNumber: NSNumber) -> NSComparisonResult
func compare(otherObject: NSIndexPath) -> NSComparisonResult
func compare(string: String) -> NSComparisonResult
func compare(otherNumber: NSNumber) -> NSComparisonResult
```
## Impact on existing code
The proposed changes are massively source-breaking for Swift code that
makes use of Objective-C frameworks, and will require a migrator to
translate Swift 2 code into Swift 3 code. The `-swift3-migration`
flag described in the [Implementation
Experience](#implementation-experience) section can provide the basics
for such a migrator. Additionally, the compiler needs to provide good
error messages (with Fix-Its) for Swift code that refers to the old
(pre-transformed) Objective-C names, which could be achieved with some
combination of the Fix-Its described previously and a secondary name
lookup mechanism retaining the old names.
## Acknowledgments
The automatic translation described in this proposal has been
developed as part of the effort to produce the [Swift API Design
Guidelines][api-design-guidelines] with Dmitri Hrybenko, Ted Kremenek,
Chris Lattner, Alex Migicovsky, Max Moiseev, Ali Ozer, and Tony Parker.
The addendum of comparable was originally proposed to the [core-libraries]
mailing list by [Chris Amanse](https://github.com/chrisamanse) and modified
to fit to this proposal after review by Philippe Hausler.
[objc-cocoa-guidelines]: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html "Coding Guidelines for Cocoa"
[api-design-guidelines]: https://swift.org/documentation/api-design-guidelines "API Design Guidelines"
[core-libraries]: https://swift.org/core-libraries/ "Swift Core Libraries"
[swift-3-api-guidelines-branch]: https://github.com/apple/swift/tree/swift-3-api-guidelines "Swift 3 API Guidelines branch"
[swift-2_2-branch]: https://github.com/apple/swift/tree/swift-2.2-branch "Swift 2.2 branch"
================================================
FILE: proposals/0006-apply-api-guidelines-to-the-standard-library.md
================================================
# Apply API Guidelines to the Standard Library
* Proposal: [SE-0006](0006-apply-api-guidelines-to-the-standard-library.md)
* Authors: [Dave Abrahams](https://github.com/dabrahams), [Dmitri Gribenko](https://github.com/gribozavr), [Maxim Moiseev](https://github.com/moiseev)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-with-modifications-se-0006-apply-api-guidelines-to-the-standard-library/1667)
## Reviewer notes
This review is part of a group of three related reviews, running
concurrently:
* [SE-0023 API Design Guidelines](0023-api-guidelines.md)
([Review](https://forums.swift.org/t/review-se-0023-api-design-guidelines/1162))
* [SE-0006 Apply API Guidelines to the Standard Library](0006-apply-api-guidelines-to-the-standard-library.md)
([Review](https://forums.swift.org/t/review-se-0006-apply-api-guidelines-to-the-standard-library/1163))
* [SE-0005 Better Translation of Objective-C APIs Into Swift](0005-objective-c-name-translation.md)
([Review](https://forums.swift.org/t/review-se-0005-better-translation-of-objective-c-apis-into-swift/1164))
These reviews are running concurrently because they interact strongly
(e.g., an API change in the standard library will correspond to a
particular guideline, or an importer rule implements a particular
guideline, etc.). Because of these interactions, and to keep
discussion manageable, we ask that you:
* **Please get a basic understanding of all three documents** before
posting review commentary
* **Please post your review of each individual document in response to
its review announcement**. It's okay (and encouraged) to make
cross-references between the documents in your review where it helps
you make a point.
## Introduction
[Swift API Design Guidelines][api-design-guidelines] being developed as
part of Swift 3. It is important that the Standard Library is an exemplar of
Swift API Design Guidelines: the APIs from the Standard Library are, probably,
the most frequently used Swift APIs in any application domain; the Standard
Library also sets precedent for other libraries.
In this project, we are reviewing the entire Standard Library and updating it
to follow the guidelines.
## Proposed solution
The actual work is being performed on the [swift-3-api-guidelines
branch][swift-3-api-guidelines-branch] of the [Swift repository][swift-repo].
On high level, the changes can be summarized as follows.
* Strip `Type` suffix from protocol names. In a few special cases
this means adding a `Protocol` suffix to get out of the way of type
names that are primary (though most of these we expect to be
obsoleted by Swift 3 language features).
* The concept of `generator` is renamed to `iterator` across all APIs.
* The type `Bit`, which was only used as the index for `CollectionOfOne`, was
removed. We recommend using `Int` instead.
* The generic parameter name in unsafe pointer types was renamed from `Memory`
to `Pointee`.
* No-argument initializers were removed from unsafe pointer types. We
recommend using the `nil` literal instead.
* `PermutationGenerator` was removed.
* `MutableSliceable` was removed. Use `Collection where SubSequence :
MutableCollection` instead.
* `sort()` => `sorted()`, `sortInPlace()` => `sort()`.
* `reverse()` => `reversed()`.
* `enumerate()` => `enumerated()`.
* `partition()` API was simplified. It composes better with collection slicing
now.
* `SequenceType.minElement()` => `.min()`, `.maxElement()` => `.max()`.
* Some initializers for sequence and collection adapters were removed. We
suggest calling the corresponding algorithm function or method instead.
* Some functions were changed into properties and vice versa.
* `String` factory methods dealing with nul-terminated UTF-8 data (a.k.a.
C-strings) became initializers.
## API diffs
Differences between Swift 2.2 Standard library API and the proposed API are
added to this section as they are being implemented on the
[swift-3-api-guidelines branch][swift-3-api-guidelines-branch].
For repetitive changes that affect many types, only one representative instance
is shown in the diff. For example, `generate()` was renamed to
`makeIterator()`. We only show the diff for the protocol requirement, and all
other renames of this method are implied. If a type was renamed, we show only
the diff for the type declaration, all other effects on the API where the name
is used are implied.
* Strip `Type` suffix from protocol names.
```diff
-public protocol BooleanType { ... }
+public protocol Boolean { ... }
-public protocol SequenceType { ... }
+public protocol Sequence { ... }
-public protocol CollectionType : ... { ... }
+public protocol Collection : ... { ... }
-public protocol MutableCollectionType : ... { ... }
+public protocol MutableCollection : ... { ... }
-public protocol RangeReplaceableCollectionType : ... { ... }
+public protocol RangeReplaceableCollection : ... { ... }
-public protocol AnyCollectionType : ... { ... }
+public protocol AnyCollectionProtocol : ... { ... }
-public protocol IntegerType : ... { ... }
+public protocol Integer : ... { ... }
-public protocol SignedIntegerType : ... { ... }
+public protocol SignedInteger : ... { ... }
-public protocol UnsignedIntegerType : ... { ... }
+public protocol UnsignedInteger : ... { ... }
-public protocol FloatingPointType : ... { ... }
+public protocol FloatingPoint : ... { ... }
-public protocol ForwardIndexType { ... }
+public protocol ForwardIndex { ... }
-public protocol BidirectionalIndexType : ... { ... }
+public protocol BidirectionalIndex : ... { ... }
-public protocol RandomAccessIndexType : ... { ... }
+public protocol RandomAccessIndex : ... { ... }
-public protocol IntegerArithmeticType : ... { ... }
+public protocol IntegerArithmetic : ... { ... }
-public protocol SignedNumberType : ... { ... }
+public protocol SignedNumber : ... { ... }
-public protocol IntervalType : ... { ... }
+public protocol Interval : ... { ... }
-public protocol LazyCollectionType : ... { ... }
+public protocol LazyCollectionProtocol : ... { ... }
-public protocol LazySequenceType : ... { ... }
+public protocol LazySequenceProtocol : ... { ... }
-public protocol OptionSetType : ... { ... }
+public protocol OptionSet : ... { ... }
-public protocol OutputStreamType : ... { ... }
+public protocol OutputStream : ... { ... }
-public protocol BitwiseOperationsType { ... }
+public protocol BitwiseOperations { ... }
-public protocol ReverseIndexType : ... { ... }
+public protocol ReverseIndexProtocol : ... { ... }
-public protocol SetAlgebraType : ... { ... }
+public protocol SetAlgebra : ... { ... }
-public protocol UnicodeCodecType { ... }
+public protocol UnicodeCodec { ... }
-public protocol CVarArgType { ... }
+public protocol CVarArg { ... }
-public protocol MirrorPathType { ... }
+public protocol MirrorPath { ... }
-public protocol ErrorType { ... }
+public protocol ErrorProtocol { ... }
```
* The concept of "generator" is renamed to "iterator" across all APIs.
```diff
-public protocol GeneratorType { ... }
+public protocol IteratorProtocol { ... }
public protocol Collection : ... {
- associatedtype Generator : GeneratorType = IndexingGenerator
+ associatedtype Iterator : IteratorProtocol = IndexingIterator
- func generate() -> Generator
+ func makeIterator() -> Iterator
}
-public struct IndexingGenerator : ... { ... }
+public struct IndexingIterator : ... { ... }
-public struct GeneratorOfOne : ... { ... }
+public struct IteratorOverOne : ... { ... }
-public struct EmptyGenerator : ... { ... }
+public struct EmptyIterator : ... { ... }
-public struct AnyGenerator : ... { ... }
+public struct AnyIterator : ... { ... }
-public struct LazyFilterGenerator : ... { ... }
+public struct LazyFilterIterator : ... { ... }
-public struct FlattenGenerator : ... { ... }
+public struct FlattenIterator : ... { ... }
-public struct JoinGenerator : ... { ... }
+public struct JoinedIterator : ... { ... }
-public struct LazyMapGenerator ... { ... }
+public struct LazyMapIterator ... { ... }
-public struct RangeGenerator : ... { ... }
+public struct RangeIterator : ... { ... }
-public struct GeneratorSequence : ... { ... }
+public struct IteratorSequence : ... { ... }
-public struct StrideToGenerator : ... { ... }
+public struct StrideToIterator : ... { ... }
-public struct StrideThroughGenerator : ... { ... }
+public struct StrideThroughIterator : ... { ... }
-public struct UnsafeBufferPointerGenerator : ... { ... }
+public struct UnsafeBufferPointerIterator : ... { ... }
```
* The type `Bit`, which was only used as the index for `CollectionOfOne`, was
removed. We recommend using `Int` instead.
```diff
-public enum Bit : ... { ... }
```
* `PermutationGenerator` was removed.
```diff
-public struct PermutationGenerator<
- C : CollectionType, Indices : SequenceType
- where C.Index == Indices.Generator.Element
-> : ... { ... }
```
* `MutableSliceable` was removed. Use `Collection where SubSequence :
MutableCollection` instead.
```diff
-public protocol MutableSliceable : CollectionType, MutableCollectionType {
- subscript(_: Range) -> SubSequence { get set }
-}
```
* The generic parameter name in unsafe pointer types was renamed from `Memory`
to `Pointee`.
* No-argument initializers were removed from unsafe pointer types. We
recommend using the `nil` literal instead.
```diff
// The same changes applied to `UnsafePointer`, `UnsafeMutablePointer` and
// `AutoreleasingUnsafeMutablePointer`.
public struct UnsafePointer<
- Memory
+ Pointee
> ... : {
- public var memory: Memory { get set }
+ public var pointee: Pointee { get set }
// Use `nil` instead.
- public init()
}
public struct OpaquePointer : ... {
// Use `nil` instead.
- public init()
}
```
* `sort()` => `sorted()`, `sortInPlace()` => `sort()`. We also added argument
labels to closures.
```diff
extension Sequence where Self.Iterator.Element : Comparable {
@warn_unused_result
- public func sort() -> [Generator.Element]
+ public func sorted() -> [Iterator.Element]
}
extension Sequence {
@warn_unused_result
- public func sort(
+ public func sorted(
- @noescape isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
+ @noescape isOrderedBefore isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
) -> [Iterator.Element]
}
extension MutableCollection where Self.Iterator.Element : Comparable {
@warn_unused_result(mutable_variant="sort")
- public func sort() -> [Generator.Element]
+ public func sorted() -> [Iterator.Element]
}
extension MutableCollection {
@warn_unused_result(mutable_variant="sort")
- public func sort(
+ public func sorted(
- @noescape isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
+ @noescape isOrderedBefore isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
) -> [Iterator.Element]
}
extension MutableCollection
where
Self.Index : RandomAccessIndex,
Self.Iterator.Element : Comparable {
- public mutating func sortInPlace()
+ public mutating func sort()
}
extension MutableCollection where Self.Index : RandomAccessIndex {
- public mutating func sortInPlace(
+ public mutating func sort(
- @noescape isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
+ @noescape isOrderedBefore isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
)
}
```
* `reverse()` => `reversed()`.
```diff
extension SequenceType {
- public func reverse() -> [Generator.Element]
+ public func reversed() -> [Iterator.Element]
}
extension CollectionType where Index : BidirectionalIndexType {
- public func reverse() -> ReverseCollection
+ public func reversed() -> ReverseCollection
}
extension CollectionType where Index : RandomAccessIndexType {
- public func reverse() -> ReverseRandomAccessCollection
+ public func reversed() -> ReverseRandomAccessCollection
}
extension LazyCollectionProtocol
where Index : BidirectionalIndexType, Elements.Index : BidirectionalIndexType {
- public func reverse()
+ public func reversed()
-> LazyCollection>
}
extension LazyCollectionProtocol
where Index : RandomAccessIndexType, Elements.Index : RandomAccessIndexType {
- public func reverse()
+ public func reversed()
-> LazyCollection>
}
```
* `enumerate()` => `enumerated()`.
```diff
extension Sequence {
- public func enumerate() -> EnumerateSequence
+ public func enumerated() -> EnumeratedSequence
}
-public struct EnumerateSequence : ... { ... }
+public struct EnumeratedSequence : ... { ... }
-public struct EnumerateGenerator : ... { ... }
+public struct EnumeratedIterator : ... { ... }
```
* `partition()` API was simplified: the range argument was removed. It
composes better with collection slicing now, and is more uniform with other
collection algorithms. We also added `@noescape` and an argument label to
the closure.
```diff
extension MutableCollection where Index : RandomAccessIndex {
public mutating func partition(
- range: Range,
- isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
+ @noescape isOrderedBefore isOrderedBefore: (Iterator.Element, Iterator.Element) -> Bool
) -> Index
}
extension MutableCollection
where Index : RandomAccessIndex, Iterator.Element : Comparable {
- public mutating func partition(range: Range) -> Index
+ public mutating func partition() -> Index
}
```
* `SequenceType.minElement()` => `.min()`, `.maxElement()` => `.max()`. We
also added argument labels to closures.
```diff
extension Sequence {
- public func minElement(
+ public func min(
- @noescape isOrderedBefore: (Iterator.Element, Iterator.Element) throws -> Bool
+ @noescape isOrderedBefore isOrderedBefore: (Iterator.Element, Iterator.Element) throws -> Bool
) rethrows -> Iterator.Element?
- public func maxElement(
+ public func max(
- @noescape isOrderedBefore: (Iterator.Element, Iterator.Element) throws -> Bool
+ @noescape isOrderedBefore isOrderedBefore: (Iterator.Element, Iterator.Element) throws -> Bool
) rethrows -> Iterator.Element?
}
extension Sequence where Iterator.Element : Comparable {
- public func minElement() -> Iterator.Element?
+ public func min() -> Iterator.Element?
- public func maxElement() -> Iterator.Element?
+ public func max() -> Iterator.Element?
}
```
* Some initializers for sequence, collection and iterator adapters were
removed. We suggest calling the corresponding algorithm function or
method instead.
```diff
extension Repeated {
- public init(count: Int, repeatedValue: Element)
}
+/// Return a collection containing `n` repetitions of `elementInstance`.
+public func repeatElement(element: T, count n: Int) -> Repeated
public struct LazyMapSequence : ... {
// Call `.lazy.map` on the sequence instead.
- public init(_ base: Base, transform: (Base.Generator.Element) -> Element)
}
public struct LazyMapCollection : ... {
// Call `.lazy.map` on the collection instead.
- public init(_ base: Base, transform: (Base.Generator.Element) -> Element)
}
public struct LazyFilterIterator : ... {
// Call `.lazy.filter` on the sequence instead.
- public init(
- _ base: Base,
- whereElementsSatisfy predicate: (Base.Element) -> Bool
- )
}
public struct RangeIterator : ... {
// Use the 'generate()' method on the collection instead.
- public init(_ bounds: Range)
// Use the '..<' operator.
- public init(start: Element, end: Element)
}
public struct ReverseCollection : ... {
// Use the 'reverse()' method on the collection.
- public init(_ base: Base)
}
public struct ReverseRandomAccessCollection : ... {
// Use the 'reverse()' method on the collection.
- public init(_ base: Base)
}
public struct Slice : ... {
// Use the slicing syntax.
- public init(base: Base, bounds: Range)
}
public struct MutableSlice : ... {
// Use the slicing syntax.
- public init(base: Base, bounds: Range)
}
public struct EnumeratedIterator : ... {
// Use the 'enumerated()' method.
- public init(_ base: Base)
}
public struct EnumeratedSequence : ... {
// Use the 'enumerated()' method.
- public init(_ base: Base)
}
public struct IndexingIterator : ... {
// Call 'iterator()' on the collection instead.
- public init(_elements: Elements)
}
public struct HalfOpenInterval : ... {
// Use the '..<' operator.
- public init(_ start: Bound, _ end: Bound)
}
public struct ClosedInterval : ... {
// Use the '...' operator.
- public init(_ start: Bound, _ end: Bound)
}
```
* Some functions were changed into properties and vice versa.
```diff
-public func unsafeUnwrap(nonEmpty: T?) -> T
extension Optional {
+ public var unsafelyUnwrapped: Wrapped { get }
}
public struct Mirror {
- public func superclassMirror() -> Mirror?
+ public var superclassMirror: Mirror? { get }
}
public protocol CustomReflectable {
- func customMirror() -> Mirror
+ var customMirror: Mirror { get }
}
public protocol Collection : ... {
- public func underestimateCount() -> Int
+ public var underestimatedCount: Int { get }
}
public protocol CustomPlaygroundQuickLookable {
- func customPlaygroundQuickLook() -> PlaygroundQuickLook
+ var customPlaygroundQuickLook: PlaygroundQuickLook { get }
}
extension String {
- public var lowercaseString: String { get }
+ public func lowercased()
- public var uppercaseString: String { get }
+ public func uppercased()
}
public enum UnicodeDecodingResult {
- public func isEmptyInput() -> Bool {
+ public var isEmptyInput: Bool
}
```
* Base names and argument labels were changed to follow guidelines about first
argument labels. (Some changes in this category are already specified
elsewhere in the diff and are not repeated.)
```diff
public protocol ForwardIndex {
- func advancedBy(n: Distance) -> Self
+ func advanced(by n: Distance) -> Self
- func advancedBy(n: Distance, limit: Self) -> Self
+ func advanced(by n: Distance, limit: Self) -> Self
- func distanceTo(end: Self) -> Distance
+ func distance(to end: Self) -> Distance
}
public struct Set : ... {
- public mutating func removeAtIndex(index: Index) -> Element
+ public mutating func remove(at index: Index) -> Element
}
public struct Dictionary : ... {
- public mutating func removeAtIndex(index: Index) -> Element
+ public mutating func remove(at index: Index) -> Element
- public func indexForKey(key: Key) -> Index?
+ public func index(forKey key: Key) -> Index?
- public mutating func removeValueForKey(key: Key) -> Value?
+ public mutating func removeValue(forKey key: Key) -> Value?
}
extension Sequence where Iterator.Element : Sequence {
// joinWithSeparator(_:) => join(separator:)
- public func joinWithSeparator<
+ public func joined<
Separator : Sequence
where
Separator.Iterator.Element == Iterator.Element.Iterator.Element
- >(separator: Separator) -> JoinSequence
+ >(separator separator: Separator) -> JoinedSequence
}
extension Sequence where Iterator.Element == String {
- public func joinWithSeparator(separator: String) -> String
+ public func joined(separator separator: String) -> String
}
public class ManagedBuffer : ... {
public final class func create(
- minimumCapacity: Int,
+ minimumCapacity minimumCapacity: Int,
initialValue: (ManagedProtoBuffer) -> Value
) -> ManagedBuffer
}
public protocol Streamable {
- func writeTo(inout target: Target)
+ func write(inout to target: Target)
}
public func dump(
value: T,
- inout _ target: TargetStream,
+ inout to target: TargetStream,
name: String? = nil,
indent: Int = 0,
maxDepth: Int = .max,
maxItems: Int = .max
) -> T
extension Sequence {
- public func startsWith<
+ public func starts<
PossiblePrefix : Sequence where PossiblePrefix.Iterator.Element == Iterator.Element
>(
- possiblePrefix: PossiblePrefix,
+ with possiblePrefix: PossiblePrefix,
@noescape isEquivalent: (Iterator.Element, Iterator.Element) throws -> Bool
) rethrows -> Bool
- public func startsWith<
+ public func starts<
PossiblePrefix : Sequence where PossiblePrefix.Iterator.Element == Iterator.Element
>(
- possiblePrefix: PossiblePrefix
+ with possiblePrefix: PossiblePrefix
) -> Bool
}
extension CollectionType where Iterator.Element : Equatable {
- public func indexOf(element: Iterator.Element) -> Index?
+ public func index(of element: Iterator.Element) -> Index?
}
extension CollectionType {
- public func indexOf(predicate: (Iterator.Element) throws -> Bool) rethrows -> Index?
+ public func index(where predicate: (Iterator.Element) throws -> Bool) rethrows -> Index?
}
extension String.Index {
- public func samePositionIn(utf8: String.UTF8View) -> String.UTF8View.Index
+ public func samePosition(in utf8: String.UTF8View) -> String.UTF8View.Index
- public func samePositionIn(utf16: String.UTF16View) -> String.UTF16View.Index
+ public func samePosition(in utf16: String.UTF16View) -> String.UTF16View.Index
- public func samePositionIn(unicodeScalars: String.UnicodeScalarView) -> String.UnicodeScalarView.Index
+ public func samePosition(in unicodeScalars: String.UnicodeScalarView) -> String.UnicodeScalarView.Index
}
extension String.UTF16View.Index {
- public func samePositionIn(characters: String) -> String.Index
+ public func samePosition(in characters: String) -> String.Index
- public func samePositionIn(utf8: String.UTF8View) -> String.UTF8View.Index
+ public func samePosition(in utf8: String.UTF8View) -> String.UTF8View.Index
- public func samePositionIn(unicodeScalars: String.UnicodeScalarView) -> String.UnicodeScalarView.Index
+ public func samePosition(in unicodeScalars: String.UnicodeScalarView) -> String.UnicodeScalarView.Index
}
extension String.UTF8View.Index {
- public func samePositionIn(characters: String) -> String.Index
+ public func samePosition(in characters: String) -> String.Index
- public func samePositionIn(utf16: String.UTF16View) -> String.UTF16View.Index
+ public func samePosition(in utf16: String.UTF16View) -> String.UTF16View.Index
- public func samePositionIn(unicodeScalars: String.UnicodeScalarView) -> String.UnicodeScalarView.Index
+ public func samePosition(in unicodeScalars: String.UnicodeScalarView) -> String.UnicodeScalarView.Index
}
extension String.UnicodeScalarView.Index {
- public func samePositionIn(characters: String) -> String.Index
+ public func samePosition(in characters: String) -> String.Index
- public func samePositionIn(utf16: String.UTF16View) -> String.UTF16View.Index
+ public func samePosition(in utf16: String.UTF16View) -> String.UTF16View.Index
- public func samePositionIn(utf16: String.UTF16View) -> String.UTF16View.Index
+ public func samePosition(in utf16: String.UTF16View) -> String.UTF16View.Index
}
```
* Lowercase enum cases and static properties.
```diff
public struct Float {
- public static var NaN: Float
+ public static var nan: Float
}
public struct Double {
- public static var NaN: Double
+ public static var nan: Double
public struct CGFloat {
- public static var NaN: CGFloat
+ public static var nan: CGFloat
}
public protocol FloatingPoint : ... {
- static var NaN: Self { get }
+ static var nan: Self { get }
}
public enum FloatingPointClassification {
- case SignalingNaN
+ case signalingNaN
- case QuietNaN
+ case quietNaN
- case NegativeInfinity
+ case negativeInfinity
- case NegativeNormal
+ case negativeNormal
- case NegativeSubnormal
+ case negativeSubnormal
- case NegativeZero
+ case negativeZero
- case PositiveZero
+ case positiveZero
- case PositiveSubnormal
+ case positiveSubnormal
- case PositiveNormal
+ case positiveNormal
- case PositiveInfinity
+ case positiveInfinity
}
public enum ImplicitlyUnwrappedOptional : ... {
- case None
+ case none
- case Some(Wrapped)
+ case some(Wrapped)
}
public enum Optional : ... {
- case None
+ case none
- case Some(Wrapped)
+ case some(Wrapped)
}
public struct Mirror {
public enum AncestorRepresentation {
- case Generated
+ case generated
- case Customized(() -> Mirror)
+ case customized(() -> Mirror)
- case Suppressed
+ case suppressed
}
public enum DisplayStyle {
- case struct, class, enum, tuple, optional, collection
+ case `struct`, `class`, `enum`, tuple, optional, collection
- case dictionary, `set`
+ case dictionary, `set`
}
}
public enum PlaygroundQuickLook {
- case Text(String)
+ case text(String)
- case Int(Int64)
+ case int(Int64)
- case UInt(UInt64)
+ case uInt(UInt64)
- case Float(Float32)
+ case float(Float32)
- case Double(Float64)
+ case double(Float64)
- case Image(Any)
+ case image(Any)
- case Sound(Any)
+ case sound(Any)
- case Color(Any)
+ case color(Any)
- case BezierPath(Any)
+ case bezierPath(Any)
- case AttributedString(Any)
+ case attributedString(Any)
- case Rectangle(Float64,Float64,Float64,Float64)
+ case rectangle(Float64,Float64,Float64,Float64)
- case Point(Float64,Float64)
+ case point(Float64,Float64)
- case Size(Float64,Float64)
+ case size(Float64,Float64)
- case Logical(Bool)
+ case bool(Bool)
- case Range(Int64, Int64)
+ case range(Int64, Int64)
- case View(Any)
+ case view(Any)
- case Sprite(Any)
+ case sprite(Any)
- case URL(String)
+ case url(String)
- case _Raw([UInt8], String)
+ case _raw([UInt8], String)
}
```
* `String` factory methods dealing with nul-terminated UTF-8 data (a.k.a.
C-strings) became initializers.
```diff
extension String {
- public static func fromCString(cs: UnsafePointer) -> String?
+ public init?(validatingUTF8 cString: UnsafePointer)
- public static func fromCStringRepairingIllFormedUTF8(cs: UnsafePointer) -> (String?, hadError: Bool)
+ public init(cString: UnsafePointer)
+ public static func decodeCString(
+ cString: UnsafePointer,
+ as encoding: Encoding.Type,
+ repairingInvalidCodeUnits isReparing: Bool = true)
+ -> (result: String, repairsMade: Bool)?
}
```
* `String` methods that mirror imported methods on NSString are renamed to reflect the new importing rules.
```diff
extension String {
- public static func localizedNameOfStringEncoding(
- encoding: NSStringEncoding
- ) -> String
+ public static func localizedName(
+ ofStringEncoding encoding: NSStringEncoding
+ ) -> String
- public static func pathWithComponents(components: [String]) -> String
+ public static func path(withComponents components: [String]) -> String
- public init?(UTF8String bytes: UnsafePointer)
+ public init?(utf8String bytes: UnsafePointer)
- public func canBeConvertedToEncoding(encoding: NSStringEncoding) -> Bool
+ public func canBeConverted(toEncoding encoding: NSStringEncoding) -> Bool
- public var capitalizedString: String
+ public var capitalized: String
- public var localizedCapitalizedString: String
+ public var localizedCapitalized: String
- public func capitalizedStringWithLocale(locale: NSLocale?) -> String
+ public func capitalized(with locale: NSLocale?) -> String
- public func commonPrefixWithString(
- aString: String, options: NSStringCompareOptions) -> String
+ public func commonPrefix(
+ with aString: String, options: NSStringCompareOptions = []) -> String
- public func completePathIntoString(
- outputName: UnsafeMutablePointer = nil,
- caseSensitive: Bool,
- matchesIntoArray: UnsafeMutablePointer<[String]> = nil,
- filterTypes: [String]? = nil
- ) -> Int
+ public func completePath(
+ into outputName: UnsafeMutablePointer = nil,
+ caseSensitive: Bool,
+ matchesInto matchesIntoArray: UnsafeMutablePointer<[String]> = nil,
+ filterTypes: [String]? = nil
+ ) -> Int
- public func componentsSeparatedByCharactersInSet(
- separator: NSCharacterSet
- ) -> [String]
+ public func componentsSeparatedByCharacters(
+ in separator: NSCharacterSet
+ ) -> [String]
- public func componentsSeparatedByString(separator: String) -> [String]
+ public func componentsSeparated(by separator: String) -> [String]
- public func cStringUsingEncoding(encoding: NSStringEncoding) -> [CChar]?
+ public func cString(usingEncoding encoding: NSStringEncoding) -> [CChar]?
- public func dataUsingEncoding(
- encoding: NSStringEncoding,
- allowLossyConversion: Bool = false
- ) -> NSData?
+ public func data(
+ usingEncoding encoding: NSStringEncoding,
+ allowLossyConversion: Bool = false
+ ) -> NSData?
- public func enumerateLinguisticTagsInRange(
- range: Range,
- scheme tagScheme: String,
- options opts: NSLinguisticTaggerOptions,
- orthography: NSOrthography?,
- _ body:
- (String, Range, Range, inout Bool) -> ()
- )
+ public func enumerateLinguisticTags(
+ in range: Range,
+ scheme tagScheme: String,
+ options opts: NSLinguisticTaggerOptions = [],
+ orthography: NSOrthography? = nil,
+ _ body:
+ (String, Range, Range, inout Bool) -> ()
+ )
- public func enumerateSubstringsInRange(
- range: Range,
- options opts:NSStringEnumerationOptions,
- _ body: (
- substring: String?, substringRange: Range,
- enclosingRange: Range, inout Bool
- ) -> ()
- )
+ public func enumerateSubstrings(
+ in range: Range,
+ options opts:NSStringEnumerationOptions = [],
+ _ body: (
+ substring: String?, substringRange: Range,
+ enclosingRange: Range, inout Bool
+ ) -> ()
+ )
- public func fileSystemRepresentation() -> [CChar]
+ public var fileSystemRepresentation: [CChar]
- public func getBytes(
- inout buffer: [UInt8],
- maxLength maxBufferCount: Int,
- usedLength usedBufferCount: UnsafeMutablePointer,
- encoding: NSStringEncoding,
- options: NSStringEncodingConversionOptions,
- range: Range,
- remainingRange leftover: UnsafeMutablePointer>
- ) -> Bool
+ public func getBytes(
+ inout buffer: [UInt8],
+ maxLength maxBufferCount: Int,
+ usedLength usedBufferCount: UnsafeMutablePointer,
+ encoding: NSStringEncoding,
+ options: NSStringEncodingConversionOptions = [],
+ range: Range,
+ remaining leftover: UnsafeMutablePointer>
+ ) -> Bool
- public func getLineStart(
- start: UnsafeMutablePointer,
- end: UnsafeMutablePointer,
- contentsEnd: UnsafeMutablePointer,
- forRange: Range
- )
+ public func getLineStart(
+ start: UnsafeMutablePointer,
+ end: UnsafeMutablePointer,
+ contentsEnd: UnsafeMutablePointer,
+ for range: Range
+ )
- public func getParagraphStart(
- start: UnsafeMutablePointer,
- end: UnsafeMutablePointer,
- contentsEnd: UnsafeMutablePointer,
- forRange: Range
- )
+ public func getParagraphStart(
+ start: UnsafeMutablePointer,
+ end: UnsafeMutablePointer,
+ contentsEnd: UnsafeMutablePointer,
+ for range: Range
+ )
public init(
- contentsOfURL url: NSURL,
+ contentsOf url: NSURL,
encoding enc: NSStringEncoding
) throws
public init(
- contentsOfURL url: NSURL,
+ contentsOf url: NSURL,
usedEncoding enc: UnsafeMutablePointer = nil
) throws
public init?(
- CString: UnsafePointer,
+ cString: UnsafePointer,
encoding enc: NSStringEncoding
)
- public init(format: String, _ arguments: CVarArgType...)
+ public init(format: String, _ arguments: CVarArg...)
- public init(format: String, arguments: [CVarArgType])
+ public init(format: String, arguments: [CVarArg])
- public init(format: String, locale: NSLocale?, _ args: CVarArgType...)
+ public init(format: String, locale: NSLocale?, _ args: CVarArg...)
- public init(format: String, locale: NSLocale?, arguments: [CVarArgType])
+ public init(format: String, locale: NSLocale?, arguments: [CVarArg])
- public func lengthOfBytesUsingEncoding(encoding: NSStringEncoding) -> Int
+ public func lengthOfBytes(usingEncoding encoding: NSStringEncoding) -> Int
- public func lineRangeForRange(aRange: Range) -> Range
+ public func lineRange(for aRange: Range) -> Range
- public func linguisticTagsInRange(
- range: Range,
- scheme tagScheme: String,
- options opts: NSLinguisticTaggerOptions = [],
- orthography: NSOrthography? = nil,
- tokenRanges: UnsafeMutablePointer<[Range]> = nil // FIXME:Can this be nil?
- ) -> [String]
+ public func linguisticTags(
+ in range: Range,
+ scheme tagScheme: String,
+ options opts: NSLinguisticTaggerOptions = [],
+ orthography: NSOrthography? = nil,
+ tokenRanges: UnsafeMutablePointer<[Range]> = nil // FIXME:Can this be nil?
+ ) -> [String]
- public var localizedLowercaseString: String
+ public var localizedLowercase: String
- public func lowercaseStringWithLocale(locale: NSLocale?) -> String
+ public func lowercaseString(with locale: NSLocale?) -> String
- func maximumLengthOfBytesUsingEncoding(encoding: NSStringEncoding) -> Int
+ func maximumLengthOfBytes(usingEncoding encoding: NSStringEncoding) -> Int
- public func paragraphRangeForRange(aRange: Range) -> Range
+ public func paragraphRange(for aRange: Range) -> Range
- public func rangeOfCharacterFromSet(
- aSet: NSCharacterSet,
- options mask:NSStringCompareOptions = [],
- range aRange: Range? = nil
- ) -> Range?
+ public func rangeOfCharacter(
+ from aSet: NSCharacterSet,
+ options mask:NSStringCompareOptions = [],
+ range aRange: Range? = nil
+ ) -> Range?
- func rangeOfComposedCharacterSequenceAtIndex(anIndex: Index) -> Range
+ func rangeOfComposedCharacterSequence(at anIndex: Index) -> Range
- public func rangeOfComposedCharacterSequencesForRange(
- range: Range
- ) -> Range
+ public func rangeOfComposedCharacterSequences(
+ for range: Range
+ ) -> Range
- public func rangeOfString(
- aString: String,
- options mask: NSStringCompareOptions = [],
- range searchRange: Range? = nil,
- locale: NSLocale? = nil
- ) -> Range?
+ public func range(
+ of aString: String,
+ options mask: NSStringCompareOptions = [],
+ range searchRange: Range? = nil,
+ locale: NSLocale? = nil
+ ) -> Range?
- public func localizedStandardContainsString(string: String) -> Bool
+ public func localizedStandardContains(string: String) -> Bool
- public func localizedStandardRangeOfString(string: String) -> Range?
+ public func localizedStandardRange(of string: String) -> Range?
- public var stringByAbbreviatingWithTildeInPath: String
+ public var abbreviatingWithTildeInPath: String
- public func stringByAddingPercentEncodingWithAllowedCharacters(
- allowedCharacters: NSCharacterSet
- ) -> String?
+ public func addingPercentEncoding(
+ withAllowedCharacters allowedCharacters: NSCharacterSet
+ ) -> String?
- public func stringByAddingPercentEscapesUsingEncoding(
- encoding: NSStringEncoding
- ) -> String?
+ public func addingPercentEscapes(
+ usingEncoding encoding: NSStringEncoding
+ ) -> String?
- public func stringByAppendingFormat(
- format: String, _ arguments: CVarArgType...
- ) -> String
+ public func appendingFormat(
+ format: String, _ arguments: CVarArg...
+ ) -> String
- public func stringByAppendingPathComponent(aString: String) -> String
+ public func appendingPathComponent(aString: String) -> String
- public func stringByAppendingPathExtension(ext: String) -> String?
+ public func appendingPathExtension(ext: String) -> String?
- public func stringByAppendingString(aString: String) -> String
+ public func appending(aString: String) -> String
- public var stringByDeletingLastPathComponent: String
+ public var deletingLastPathComponent: String
- public var stringByDeletingPathExtension: String
+ public var deletingPathExtension: String
- public var stringByExpandingTildeInPath: String
+ public var expandingTildeInPath: String
- public func stringByFoldingWithOptions(
- options: NSStringCompareOptions, locale: NSLocale?
- ) -> String
+ public func folding(
+ options: NSStringCompareOptions = [], locale: NSLocale?
+ ) -> String
- public func stringByPaddingToLength(
- newLength: Int, withString padString: String, startingAtIndex padIndex: Int
- ) -> String
+ public func padding(
+ toLength newLength: Int,
+ with padString: String,
+ startingAt padIndex: Int
+ ) -> String
- public var stringByRemovingPercentEncoding: String?
+ public var removingPercentEncoding: String?
- public func stringByReplacingCharactersInRange(
- range: Range, withString replacement: String
- ) -> String
+ public func replacingCharacters(
+ in range: Range, with replacement: String
+ ) -> String
- public func stringByReplacingOccurrencesOfString(
- target: String,
- withString replacement: String,
- options: NSStringCompareOptions = [],
- range searchRange: Range? = nil
- ) -> String
+ public func replacingOccurrences(
+ of target: String,
+ with replacement: String,
+ options: NSStringCompareOptions = [],
+ range searchRange: Range? = nil
+ ) -> String
- public func stringByReplacingPercentEscapesUsingEncoding(
- encoding: NSStringEncoding
- ) -> String?
+ public func replacingPercentEscapes(
+ usingEncoding encoding: NSStringEncoding
+ ) -> String?
- public var stringByResolvingSymlinksInPath: String
+ public var resolvingSymlinksInPath: String
- public var stringByStandardizingPath: String
+ public var standardizingPath: String
- public func stringByTrimmingCharactersInSet(set: NSCharacterSet) -> String
+ public func trimmingCharacters(in set: NSCharacterSet) -> String
- public func stringsByAppendingPaths(paths: [String]) -> [String]
+ public func strings(byAppendingPaths paths: [String]) -> [String]
- public func substringFromIndex(index: Index) -> String
+ public func substring(from index: Index) -> String
- public func substringToIndex(index: Index) -> String
+ public func substring(to index: Index) -> String
- public func substringWithRange(aRange: Range) -> String
+ public func substring(with aRange: Range) -> String
- public var localizedUppercaseString: String
+ public var localizedUppercase: String
- public func uppercaseStringWithLocale(locale: NSLocale?) -> String
+ public func uppercaseString(with locale: NSLocale?) -> String
- public func writeToFile(
- path: String, atomically useAuxiliaryFile:Bool,
- encoding enc: NSStringEncoding
- ) throws
+ public func write(
+ toFile path: String, atomically useAuxiliaryFile:Bool,
+ encoding enc: NSStringEncoding
+ ) throws
- public func writeToURL(
- url: NSURL, atomically useAuxiliaryFile: Bool,
- encoding enc: NSStringEncoding
- ) throws
+ public func write(
+ to url: NSURL, atomically useAuxiliaryFile: Bool,
+ encoding enc: NSStringEncoding
+ ) throws
- public func stringByApplyingTransform(
- transform: String, reverse: Bool
- ) -> String?
+ public func applyingTransform(
+ transform: String, reverse: Bool
+ ) -> String?
- public func containsString(other: String) -> Bool
+ public func contains(other: String) -> Bool
- public func localizedCaseInsensitiveContainsString(other: String) -> Bool
+ public func localizedCaseInsensitiveContains(other: String) -> Bool
}
```
* Miscellaneous changes.
```diff
public struct EnumeratedIterator : ... {
- public typealias Element = (index: Int, element: Base.Element)
+ public typealias Element = (offset: Int, element: Base.Element)
}
public struct Array : ... {
// Same changes were also applied to `ArraySlice` and `ContiguousArray`.
- public init(count: Int, repeatedValue: Element)
+ public init(repeating: Element, count: Int)
}
public protocol Sequence : ... {
public func split(
- maxSplit: Int = Int.max,
+ maxSplits maxSplits: Int = Int.max,
- allowEmptySlices: Bool = false,
+ omittingEmptySubsequences: Bool = true,
@noescape isSeparator: (Iterator.Element) throws -> Bool
) rethrows -> [SubSequence]
}
extension Sequence where Iterator.Element : Equatable {
public func split(
- separator: Iterator.Element,
+ separator separator: Iterator.Element,
- maxSplit: Int = Int.max,
+ maxSplits maxSplits: Int = Int.max,
- allowEmptySlices: Bool = false
+ omittingEmptySubsequences: Bool = true
) -> [AnySequence] {
}
public protocol Sequence : ... {
- public func lexicographicalCompare<
+ public func lexicographicallyPrecedes<
OtherSequence : Sequence where OtherSequence.Iterator.Element == Iterator.Element
>(
other: OtherSequence,
@noescape isOrderedBefore: (Iterator.Element, Iterator.Element) throws -> Bool
) rethrows -> Bool {
}
extension Sequence where Iterator.Element : Equatable {
- public func lexicographicalCompare<
+ public func lexicographicallyPrecedes<
OtherSequence : Sequence where OtherSequence.Iterator.Element == Iterator.Element
>(
other: OtherSequence
) -> Bool {
}
public protocol Collection : ... {
- func prefixUpTo(end: Index) -> SubSequence
+ func prefix(upTo end: Index) -> SubSequence
- func suffixFrom(start: Index) -> SubSequence
+ func suffix(from start: Index) -> SubSequence
- func prefixThrough(position: Index) -> SubSequence
+ func prefix(through position: Index) -> SubSequence
}
// Changes to this protocol affect `Array`, `ArraySlice`, `ContiguousArray` and
// other types.
public protocol RangeReplaceableCollection : ... {
+ public init(repeating repeatedValue: Iterator.Element, count: Int)
- mutating func replaceRange<
+ mutating func replaceSubrange<
C : CollectionType where C.Iterator.Element == Iterator.Element
>(
subRange: Range, with newElements: C
)
- mutating func insert(newElement: Iterator.Element, atIndex i: Int)
+ mutating func insert(newElement: Iterator.Element, at i: Int)
- mutating func insertContentsOf<
+ mutating func insert<
S : Collection where S.Iterator.Element == Iterator.Element
- >(newElements: S, at i: Index)
+ >(contentsOf newElements: S, at i: Index)
- mutating func removeAtIndex(index: Int) -> Element
+ mutating func remove(at index: Int) -> Element
- mutating func removeAll(keepCapacity keepCapacity: Bool = false)
+ mutating func removeAll(keepingCapacity keepingCapacity: Bool = false)
- mutating func removeRange(subRange: Range)
+ mutating func removeSubrange(subRange: Range)
- mutating func appendContentsOf(newElements: S)
+ mutating func append(contentsOf newElements: S)
}
+extension Set : SetAlgebra {}
public struct Dictionary : ... {
- public typealias Element = (Key, Value)
+ public typealias Element = (key: Key, value: Value)
}
public struct DictionaryLiteral : ... {
- public typealias Element = (Key, Value)
+ public typealias Element = (key: Key, value: Value)
}
extension String {
- public mutating func appendContentsOf(other: String) {
+ public mutating func append(other: String) {
- public mutating appendContentsOf(newElements: S)
+ public mutating append(contentsOf newElements: S)
- public mutating func replaceRange<
+ public mutating func replaceSubrange<
C: CollectionType where C.Iterator.Element == Character
>(
subRange: Range, with newElements: C
)
- public mutating func replaceRange(
+ public mutating func replaceSubrange(
subRange: Range, with newElements: String
)
- public mutating func insert(newElement: Character, atIndex i: Index)
+ public mutating func insert(newElement: Character, at i: Index)
- public mutating func insertContentsOf<
+ public mutating func insert<
S : Collection where S.Iterator.Element == Character
- >(newElements: S, at i: Index)
+ >(contentsOf newElements: S, at i: Index)
- public mutating func removeAtIndex(i: Index) -> Character
+ public mutating func remove(at i: Index) -> Character
- public mutating func removeRange(subRange: Range)
+ public mutating func removeSubrange(subRange: Range)
- mutating func removeAll(keepCapacity keepCapacity: Bool = false)
+ mutating func removeAll(keepingCapacity keepingCapacity: Bool = false)
- public init(count: Int, repeatedValue c: Character)
+ public init(repeating repeatedValue: Character, count: Int)
- public init(count: Int, repeatedValue c: UnicodeScalar)
+ public init(repeating repeatedValue: UnicodeScalar, count: Int)
- public var utf8: UTF8View { get }
+ public var utf8: UTF8View { get set }
- public var utf16: UTF16View { get }
+ public var utf16: UTF16View { get set }
- public var characters: CharacterView { get }
+ public var characters: CharacterView { get set }
}
public enum UnicodeDecodingResult {
- case Result(UnicodeScalar)
- case EmptyInput
- case Error
+ case scalarValue(UnicodeScalar)
+ case emptyInput
+ case error
}
public struct ManagedBufferPointer : ... {
- public var allocatedElementCount: Int { get }
+ public var capacity: Int { get }
}
public struct RangeIterator : ... {
- public var startIndex: Element { get set }
- public var endIndex: Element { get set }
}
public struct ObjectIdentifier : ... {
- public var uintValue: UInt { get }
}
extension UInt {
+ /// Create a `UInt` that captures the full value of `objectID`.
+ public init(_ objectID: ObjectIdentifier)
}
extension Int {
+ /// Create an `Int` that captures the full value of `objectID`.
+ public init(_ objectID: ObjectIdentifier)
}
-public struct Repeat : ... { ... }
+public struct Repeated : ... { ... }
public struct StaticString : ... {
- public var byteSize: Int { get }
+ public var utf8CodeUnitCount: Int { get }
// Use the 'String(_:)' initializer.
- public var stringValue: String { get }
}
extension Strideable {
- public func stride(to end: Self, by stride: Stride) -> StrideTo
}
+public func stride(from start: T, to end: T, by stride: T.Stride) -> StrideTo
extension Strideable {
- public func stride(through end: Self, by stride: Stride) -> StrideThrough
}
+public func stride(from start: T, through end: T, by stride: T.Stride) -> StrideThrough
public func transcode<
Input : IteratorProtocol,
InputEncoding : UnicodeCodec,
OutputEncoding : UnicodeCodec
where InputEncoding.CodeUnit == Input.Element>(
inputEncoding: InputEncoding.Type, _ outputEncoding: OutputEncoding.Type,
_ input: Input, _ output: (OutputEncoding.CodeUnit) -> Void,
- stopOnError: Bool
+ stoppingOnError: Bool
) -> Bool
extension UnsafeMutablePointer {
- public static func alloc(num: Int) -> UnsafeMutablePointer
+ public init(allocatingCapacity count: Int)
- public func dealloc(num: Int)
+ public func deallocateCapacity(count: Int)
- public func initialize(newvalue: Memory)
+ public func initializePointee(newValue: Pointee, count: Int = 1)
- public func move() -> Memory
+ public func take() -> Pointee
- public func destroy()
- public func destroy(count: Int)
+ public func deinitializePointee(count count: Int = 1)
}
-public struct COpaquePointer : ... { ... }
+public struct OpaquePointer : ... { ... }
-public func unsafeAddressOf(object: AnyObject) -> UnsafePointer
+public func unsafeAddress(of object: AnyObject) -> UnsafePointer
-public func unsafeBitCast(x: T, _: U.Type) -> U
+public func unsafeBitCast(x: T, to: U.Type) -> U
-public func unsafeDowncast(x: AnyObject) -> T
+public func unsafeDowncast(x: AnyObject, to: T.Type) -> T
-public func print(
+public func print(
items: Any...,
separator: String = " ",
terminator: String = "\n",
- inout toStream output: Target
+ inout to output: Target
)
-public func debugPrint(
+public func debugPrint(
items: Any...,
separator: String = " ",
terminator: String = "\n",
- inout toStream output: Target
+ inout to output: Target
)
public struct Unmanaged {
- public func toOpaque() -> COpaquePointer
}
extension OpaquePointer {
+ public init(bitPattern bits: Unmanaged)
}
public enum UnicodeDecodingResult
+ : Equatable {
- public var isEmptyInput: Bool
}
-public func readLine(stripNewline stripNewline: Bool = true) -> String?
+public func readLine(strippingNewline strippingNewline: Bool = true) -> String?
struct UnicodeScalar {
// Use 'UnicodeScalar("\0")' instead.
- init()
- public func escape(asASCII forceASCII: Bool) -> String
+ public func escaped(asASCII forceASCII: Bool) -> String
}
public func transcode<
Input : IteratorProtocol,
InputEncoding : UnicodeCodec,
OutputEncoding : UnicodeCodec
where InputEncoding.CodeUnit == Input.Element
>(
- inputEncoding: InputEncoding.Type, _ outputEncoding: OutputEncoding.Type,
- _ input: Input, _ output: (OutputEncoding.CodeUnit) -> Void,
- stoppingOnError stopOnError: Bool
+ input: Input,
+ from inputEncoding: InputEncoding.Type,
+ to outputEncoding: OutputEncoding.Type,
+ stoppingOnError stopOnError: Bool,
+ sendingOutputTo processCodeUnit: (OutputEncoding.CodeUnit) -> Void
) -> Bool
extension UTF16 {
- public static func measure<
+ public static func transcodedLength<
Encoding : UnicodeCodec, Input : IteratorProtocol
where Encoding.CodeUnit == Input.Element
>(
- _: Encoding.Type, input: Input, repairIllFormedSequences: Bool
+ of input: Input,
+ decodedAs sourceEncoding: Encoding.Type,
+ repairingIllFormedSequences: Bool
- ) -> (Int, Bool)?
+ ) -> (count: Int, isASCII: Bool)? {
}
-public struct RawByte {}
-final public class VaListBuilder {}
-public func withVaList(
- builder: VaListBuilder,
- @noescape _ f: CVaListPointer -> R)
--> R
```
## Impact on existing code
The proposed changes are massively source-breaking for Swift code, and will
require a migrator to translate Swift 2 code into Swift 3 code. The API diffs
from this proposal will be the primary source of the information about the
required transformations. In addition, to the extent the language allows, the
library will keep old names as unavailable symbols with a `renamed` annotation,
that allows the compiler to produce good error messages and emit Fix-Its.
[api-design-guidelines]: https://swift.org/documentation/api-design-guidelines "API Design Guidelines"
[swift-repo]: https://github.com/apple/swift "Swift repository"
[swift-3-api-guidelines-branch]: https://github.com/apple/swift/tree/swift-3-api-guidelines "Swift 3 API Design Guidelines preview"
================================================
FILE: proposals/0007-remove-c-style-for-loops.md
================================================
# Remove C-style for-loops with conditions and incrementers
* Proposal: [SE-0007](0007-remove-c-style-for-loops.md)
* Author: [Erica Sadun](https://github.com/erica)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0007-remove-c-style-for-loops-with-conditions-and-incrementers/512)
* Bugs: [SR-226](https://bugs.swift.org/browse/SR-226), [SR-227](https://bugs.swift.org/browse/SR-227)
## Introduction
The C-style `for-loop` appears to be a mechanical carry-over from C rather than a
genuinely Swift-specific construct. It is rarely used and not very Swift-like.
More Swift-typical construction is already available with `for-in`
statements and `stride`. Removing for loops would simplify the language and starve the
most common use-points for `--` and `++`, which are already due to be eliminated from the
language.
The value of this construct is limited and I believe its removal should be seriously considered.
This proposal was discussed on the Swift Evolution list in the [C-style For Loops](https://forums.swift.org/t/c-style-for-loops/31) thread and reviewed in the [\[Review\] Remove C-style for-loops with conditions and incrementers](https://forums.swift.org/t/review-remove-c-style-for-loops-with-conditions-and-incrementers/255) thread.
## Advantages of For Loops
Swift design supported a shallow learning curve using familiar constants and control
structures. The `for-loop` mimics C and limits the effort needed to master this control flow.
## Disadvantages of For Loops
1. Both `for-in` and `stride` provide equivalent behavior using Swift-coherent approaches
without being tied to legacy terminology.
1. There is a distinct expressive disadvantage in using `for-loops` compared to `for-in`
in succinctness
1. `for-loop` implementations do not lend themselves to use with collections and other core Swift types.
1. The `for-loop` encourages use of unary incrementors and decrementors, which will be
soon removed from the language.
1. The semi-colon delimited declaration offers a steep learning curve from users arriving
from non C-like languages
1. If the `for-loop` did not exist, I doubt it would be considered for inclusion in Swift 3.
## Proposed Approach
I suggest that the for-loop be deprecated in Swift 2.x and removed entirely in Swift 3, with coverage removed from the Swift Programming Language to match the revisions in the current 2.2 update.
## Alternatives considered
Not removing `for-loop` from Swift, losing the opportunity to streamline the language
and discard an unneeded control flow item.
## Impact on existing code
A search of the Apple Swift codebase suggests this feature is rarely used. Community members of the Swift-Evolution mail list confirm that it does not feature in many pro-level apps and can be worked around for those few times when `for-loop`s do pop up. For example:
```swift
char *blk_xor(char *dst, const char *src, size_t len)
{
const char *sp = src;
for (char *dp = dst; sp - src < len; sp++, dp++)
*dp ^= *sp;
return dst;
}
```
versus
```swift
func blk_xor(dst: UnsafeMutablePointer, src:
UnsafePointer, len: Int) -> UnsafeMutablePointer {
for i in 0.., Range>>>
(1...10)
.lazy
.flatMap { n in n % 2 == 0 ? n/2 : nil }
// [1, 2, 3, 4, 5]
```
Swift Evolution Discussions: [Lazy flatMap for Optionals](https://forums.swift.org/t/lazy-flatmap-for-optionals/127/3), [Review](https://forums.swift.org/t/review-add-a-lazy-flatmap-for-sequences-of-optionals/548)
## Motivation ##
Seeing as the already-existing `flatMap` has a lazy version for nested sequences, a missing lazy version for sequences of `Optional`s seems like a gap. The usefulness of lazy sequences is well documented, especially when refactoring imperative nested for-loops into chains of methods, which can unnecessarily allocate intermediate arrays if done eagerly.
## Proposed Approach ##
Making use of already-existing types in the standard library, `flatMap`'s functionality can be achieved with a `map`-`filter`-`map` chain:
```swift
extension LazySequenceType {
@warn_unused_result
public func flatMap(transform: Elements.Generator.Element -> T?)
-> LazyMapSequence>, T> {
return self
.map(transform)
.filter { opt in opt != nil }
.map { notNil in notNil! }
}
}
```
## Detailed Design ##
A version for `LazyCollectionType`s is almost identical:
```swift
extension LazyCollectionType {
@warn_unused_result
public func flatMap(transform: Elements.Generator.Element -> T?)
-> LazyMapCollection>, T> {
return self
.map(transform)
.filter { opt in opt != nil }
.map { notNil in notNil! }
}
}
```
However, a "bidirectional" version cannot be written in this way, since no `FilterBidirectionalCollection` exists.
The other form of `flatMap` uses a `flatten` method on nested sequences, which has both a `CollectionType` form and a form for `CollectionType`s with `BidirectionalIndexType`s.
However, Swift's current type system doesn't allow a similar method to be defined on sequences of `Optional`s. This means we have to rely on `filter`, which only has a `SequenceType` and `CollectionType` implementation.
## Impact on existing code ##
## Alternatives considered ##
### Custom struct ###
It would also be possible to add a new struct, and a method on `LazySequenceType`:
```swift
public struct FlatMapOptionalGenerator: GeneratorType {
private let transform: G.Element -> Element?
private var generator: G
public mutating func next() -> Element? {
while let next = generator.next() {
if let transformed = transform(next) {
return transformed
}
}
return nil
}
}
public struct FlatMapOptionalSequence: LazySequenceType {
private let transform: S.Generator.Element -> Element?
private let sequence: S
public func generate() -> FlatMapOptionalGenerator {
return FlatMapOptionalGenerator(transform: transform, generator: sequence.generate())
}
}
extension LazySequenceType {
public func flatMap(transform: Generator.Element -> T?) -> FlatMapOptionalSequence {
return FlatMapOptionalSequence(transform: transform, sequence: self)
}
}
```
However, this implementation does not have a `LazyCollectionType` version. To add one, and a bidirectional implementation, six new types (three `SequenceType`s, three `GeneratorType`s) would have to be added to the standard library.
### New Filter struct ###
This would involve adding a `FilterBidirectionalCollection` to the standard library. Arguably, this is a gap currently. It would allow both `flatMap` versions to mirror each other, with minimal new types.
### Make Optional Conform to SequenceType ###
This is a far-reaching, separate proposal, but it would solve the issue that this proposal seeks to solve. It's worth bearing in mind, though, that `Optional` *probably* wouldn't have a `BidirectionalIndexType`, so the bidirectional version of `flatMap` wouldn't exist on `Optional`s, anyway.
================================================
FILE: proposals/0009-require-self-for-accessing-instance-members.md
================================================
# Require self for accessing instance members
* Proposal: [SE-0009](0009-require-self-for-accessing-instance-members.md)
* Author: [David Hart](https://github.com/hartbit)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Rejected**
* Decision Notes: [Rationale](https://forums.swift.org/t/rejected-se-0009-require-self-for-accessing-instance-members/930)
## Introduction
The current version of Swift (2.1) requires using `self` when accessing instance members in closures. The proposal suggests extending this to all member accesses (as is intrinsically the case in Objective-C). It has the benefit of documenting instance properties vs local variables and instance functions vs local functions or closures.
[Swift Evolution Discussion Thread](https://forums.swift.org/t/proposal-re-instate-mandatory-self-for-accessing-instance-properties-and-functions/125)
## Motivation
This proposal makes it obvious which are instance properties vs local variables, as well as which are instance functions vs local functions/closures. This has several advantages:
* More readable at the point of use.
* More consistent than only requiring `self` in closure contexts.
* Less confusing from a learning point of view.
* Lets the compiler warn users (and avoids bugs) where the authors mean to use a local variable but instead are unknowingly using an instance property (and the other way round).
One example of a bug avoidable by the proposal ([provided by Rudolf Adamkovic](https://forums.swift.org/t/proposal-re-instate-mandatory-self-for-accessing-instance-properties-and-functions/125/4)):
```swift
class MyViewController : UIViewController {
@IBOutlet var button: UIButton!
var name: String = "David"
func updateButton() {
// var title = "Hello \(name)"
button.setTitle(title, forState: .Normal) // forgot to comment this line but the compiler does not complain and title is now referencing UIViewController’s title by mistake
button.setTitleColor(UIColor.blackColor(), forState: .Normal)
}
}
```
The API Design Guidelines are meant for writing APIs but I still think they represent fundamentals of Swift. The two first points are:
* Clarity at the point of use is your most important goal. Code is read far more than it is written.
* Clarity is more important than brevity. Although Swift code can be compact, it is a non-goal to enable the smallest possible code with the fewest characters. Brevity in Swift code, where it occurs, is a side-effect of the strong type system and features that naturally reduce boilerplate.
And I believe that the proposition is directly in line with those objectives.
## Counter-argument
The counter-argument brought up by two members of the community is that the current behaviour "makes the capturing semantics of self stand out more in closures". While this is true, the author finds its usefulness lacking.
In the following lines of code, we know without a shadow of a doubt that `foobar` is a throwing function and that `barfoo` does not throw.
```swift
try foobar()
barfoo()
```
But with an example of `self` in a closure:
```swift
foobar({
print(self.description)
})
```
The `self` keyword in the previous lines of code gives a hint but does not bring any certitudes:
* `self` might have been forced by the compiler to hint at possible memory issues,
* `self` might have been a programmer choice if the closure is non-escaping.
And in the reverse example:
```swift
barfoo({
print(description)
})
```
* the closure might be non-escaping,
* the `description` might be referring to a local variable (which we missed the declaration of) shadowing the instance property in an escaping closure.
In both of these examples, the `self` keyword does not tell us with any certainty that we should or not be careful about reference cycle issues without checking the signature of the called function, only that self is captured. With the proposition, `self` gets some meaning back: it indicates which are local and which are instance properties.
## Proposed Solution
I suggest that not using `self` for accessing instance properties and functions is applied in two stages. In Swift 2.x, it could start as a warning and Xcode could provide a Fix-It. Then, it could become a compiler error in Swift 3 and the migrator would help transition code over.
The following code which used to compile would generate an error at the documented lines:
```swift
class Person {
var name: String = "David"
func foo() {
print("Hello \(name)") // would not compile
}
func bar() {
foo() // would not compile
}
}
```
The code would have to be modified as so to compile correctly:
```swift
class Person {
var name: String = "David"
func foo() {
print("Hello \(self.name)")
}
func bar() {
self.foo()
}
}
```
## Impact on existing code
A lot of code written since the original change would be impacted by this proposal, but it seems like it can be easily fixed by both the migrator tool and an Xcode Fix-It.
## Alternatives considered
The alternative is to keep the current behaviour, but it has the aforementioned disadvantages.
An alternative would be to demote from a compiler error to a warning.
## Community Responses
* "I actually encountered at least two bugs in my app introduced by this implicit "self" behavior. It can be dangerous and hard to track down." -- Rudolf Adamkovic, salutis@me.com
* "Given this, some teams use underscores for their iVars which is very unfortunate. Myself, I use self whenever possible to be explicit. I'd like the language to force us to be clear." -- Dan, robear18@gmail.com
* "I'm not sure how many Swift users this effects, but I'm colorblind and I really struggle with the local vs properties syntax coloring." -- Tyler Cloutier, cloutiertyler@aol.com
* "+1 I've had a lot of weird things happen that I've traced to mistakes in properties having the same name as function arguments. I've hardly ever had this issue in modern Obj-C." -- Colin Cornaby, colin.cornaby@mac.com
* "Teaching wise, its much less confusing for self to be required so students don't mix up instance properties and local vars. Especially when self is required in closures, it confuses students. If self is mandatory for all instance properties, it would be so much clearer and much easier to read." -- Yichen Cao, ycao@me.com
* "this avoids confusion, maintains a consistent language approach, and thus helps reducing bugs. Sure, it might lead to less poetic haiku code, but that is not necessarily a bad thing in medium to large scale software products with more than one person working on it and possible/eventual change of people on the project over time." -- Panajev
* "I'm +1 on this, for the reasons already stated by others, but not as strongly as I was a year ago. I was very worried about this with Swift 1 was first released, but since then, I haven't actually made this mistake, possibly because I'm so paranoid about it." -- Michael Buckley, michael@buckleyisms.com
================================================
FILE: proposals/0010-add-staticstring-unicodescalarview.md
================================================
# Add StaticString.UnicodeScalarView
* Proposal: [SE-0010](0010-add-staticstring-unicodescalarview.md)
* Author: [Lily Ballard](https://github.com/lilyball)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Rejected**
* Decision Notes: [Rationale](https://forums.swift.org/t/rejected-se-0010-add-staticstring-unicodescalarview/1530)
## Introduction
There is no way to create a substring of a `StaticString` that is still typed
as `StaticString`. There should be.
[Swift Evolution Discussion Thread](https://forums.swift.org/t/proposal-add-staticstring-unicodescalarview/199), [Review](https://forums.swift.org/t/review-se-0010-add-staticstring-unicodescalarview/942)
## Motivation
It is occasionally useful to be able to produce a substring of a `StaticString`
that can be passed to APIs expecting a `StaticString`. For example, extracting
the filename from `__FILE__`. But there is no way to do this today, as
`StaticString` does not provide any means by which to create a new instance
beyond the trivial nullary `init()` initializer (which creates an empty
string).
## Proposed solution
We add a new type `StaticString.UnicodeScalarView` that conforms to
`CollectionType` and a new property `unicodeScalars` on `StaticString`. We also
add 2 initializers to `StaticString`
```swift
init(_ unicodeScalars: UnicodeScalarView)
init(_ unicodeScalars: Slice)
```
Together, this allows the user to manipulate the unicode scalar view to produce
the desired slice, and then to create a `StaticString` from the results. This
has the added benefit of providing a convenient way to work with
`StaticString`s as a sequence of `UnicodeScalar`s instead of as a UTF8 buffer.
## Detailed design
The API looks like this:
```swift
extension StaticString {
/// The value of `self` as a collection of [Unicode scalar values](http://www.unicode.org/glossary/#unicode_scalar_value).
public var unicodeScalars: UnicodeScalarView { get }
/// Construct the `StaticString` corresponding to the given
/// `UnicodeScalarView`.
public init(_: UnicodeScalarView)
/// Construct the `StaticString` corresponding to the given
/// `UnicodeScalarView` slice.
public init(_: Slice)
/// A collection of [Unicode scalar values](http://www.unicode.org/glossary/#unicode_scalar_value) that
/// encode a `StaticString`.
public struct UnicodeScalarView : CollectionType {
init(_: StaticString)
/// A position in a `StaticString.UnicodeScalarView`.
public struct Index : BidirectionalIndexType, Comparable {
/// Returns the next consecutive value after `self`.
///
/// - Requires: The next value is representable.
@warn_unused_result
public func successor() -> Index
/// Returns the previous consecutive value before `self`.
///
/// - Requires: The previous value is representable.
@warn_unused_result
public func predecessor() -> Index
}
/// The position of the first `UnicodeScalar` if the `StaticString` is
/// non-empty; identical to `endIndex` otherwise.
public var startIndex: Index { get }
/// The "past the end" position.
///
/// `endIndex` is not a valid argument to `subscript`, and is always
/// reachable from `startIndex` by zero or more applications of
/// `successor()`.
public var endIndex: Index { get }
/// Returns `true` iff `self` is empty.
public var isEmpty: Bool { get }
public subscript(position: Index) -> UnicodeScalar { get }
}
}
```
## Impact on existing code
None.
## Alternatives considered
We could add a `subscript(bounds: Range)` to `StaticString` directly,
but there's no good way to define `Index` (for the same reasons `String`
doesn't conform to `CollectionType`).
We could expose an unsafe initializer from a pointer, so the user can
manipulate `utf8Start` to produce the desired pointer, but this would be very
unsafe and allow users to try and trick code taking `StaticString` into
accepting a dynamic string instead.
================================================
FILE: proposals/0011-replace-typealias-associated.md
================================================
# Replace `typealias` keyword with `associatedtype` for associated type declarations
* Proposal: [SE-0011](0011-replace-typealias-associated.md)
* Author: [Loïc Lecrenier](https://github.com/loiclec)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Implemented (Swift 2.2)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0011-replace-typealias-keyword-with-associatedtype-for-associated-type-declarations/990)
* Bug: [SR-511](https://bugs.swift.org/browse/SR-511)
## Introduction
The `typealias` keyword is currently used to declare two kinds of types:
1. Type Aliases (alternative name for an existing type)
2. Associated Types (placeholder name to type used as part of a protocol)
These two kinds of declarations are different and should use distinct keywords.
This would emphasize the difference between them and reduce some of the
confusion surrounding the use of associated types.
The proposed new keyword is `associatedtype`.
[Review Thread](https://forums.swift.org/t/review-replace-typealias-keyword-with-associatedtype-for-associated-type-declarations/880)
## Motivation
Re-using `typealias` for associated type declarations is confusing in many ways.
1. It is not obvious that `typealias` in protocols means something else than in
other places.
2. It hides the existence of associated types to beginners, which allows them
to write code they misunderstand.
3. It is not clear that concrete type aliases are forbidden inside protocols.
In particular, **2 + 3** leads to programmers writing
```swift
protocol Prot {
typealias Container : SequenceType
typealias Element = Container.Generator.Element
}
```
without realizing that `Element` is a new associated type with a default value
of `Container.Generator.Element` instead of a type alias to
`Container.Generator.Element`.
However, this code
```swift
protocol Prot {
typealias Container : SequenceType
}
extension Prot {
typealias Element = Container.Generator.Element
}
```
declares `Element` as a type alias to `Container.Generator.Element`.
These subtleties of the language currently require careful consideration to
understand.
## Proposed solution
For declaring associated types, replace the `typealias` keyword with `associatedtype`.
This solves the issues mentioned above:
1. `typealias` can now only be used for type aliases declaration.
2. Beginners are now forced to learn about associated types when creating protocols.
3. An error message can now be displayed when someone tries to create a type alias
inside a protocol.
This eliminates the confusion showed in the previous code snippets.
```swift
protocol Prot {
associatedtype Container : SequenceType
typealias Element = Container.Generator.Element // error: cannot declare type alias inside protocol, use protocol extension instead
}
```
```swift
protocol Prot {
associatedtype Container : SequenceType
}
extension Prot {
typealias Element = Container.Generator.Element
}
```
Alternative keywords considered: `type`, `associated`, `requiredtype`, `placeholdertype`, …
## Proposed Approach
For declaring associated types, I suggest adding `associatedtype` and deprecating
`typealias` in Swift 2.2, and removing `typealias` entirely in Swift 3.
## Impact on existing code
As it simply replaces one keyword for another, the transition to `associatedtype`
could be easily automated without any risk of breaking existing code.
## Mailing List
- [Original](https://forums.swift.org/t/introduce-associated-type-keyword/201)
- [Alternative Keywords](https://forums.swift.org/t/se-0011-re-considering-the-replacement-keyword-for-typealias/669)
================================================
FILE: proposals/0012-add-noescape-to-public-library-api.md
================================================
# Add `@noescape` to public library API
* Proposal: [SE-0012](0012-add-noescape-to-public-library-api.md)
* Author: [Jacob Bandes-Storch](https://github.com/jtbandes)
* Review Manager: [Philippe Hausler](https://github.com/phausler)
* Status: **Rejected**
* Decision Notes: [Rationale](https://forums.swift.org/t/rejected-se-0097-normalizing-naming-for-negative-attributes/2854/9)
##### Revision history
* **v1** Initial version
* **v1.2** Updates after component owners review and discussion
## Summary
* Swift provides the `@noescape` declaration attribute which indicates that a closure's execution is guaranteed not to escape the function call.
* clang also provides support for this via a “noescape” attribute, which is automatically imported into Swift as @noescape
* We propose exposing this attribute in CF and Foundation as `CF_NOESCAPE` and `NS_NOESCAPE`
* We also propose applying this declaration to a number of closure-taking APIs in CF and Foundation
[Swift Evolution Discussion Thread: \[Pitch\] make @noescape the default](https://forums.swift.org/t/pitch-make-noescape-the-default/664)
## Introduction
### `@noescape`
Swift provides a `@noescape` declaration [attribute](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID546) which can be applied to closure parameters, indicating that the closure's execution is guaranteed not to escape the function call.
```swift
func withLock(@noescape perform closure: () -> Void) {
myLock.lock()
closure()
myLock.unlock()
}
```
Thus, a closure argument is guaranteed to be executed (if executed at all) *before* the function returns. This enables the compiler to perform various optimizations, such as omitting unnecessary capturing/retaining/releasing of `self`.
For example, just as "`self.`" may be omitted in the context of a method, since a `@noescape` closure is known not to capture `self`, properties and methods can be accessed without the `self.` prefix:
```swift
class MyClass {
var counter = 0
func incrementCounter() {
counter += 1 // "self." elided in an instance method
withLock {
// Without @noescape, the following line would produce the error
// "reference to property 'counter' in closure requires
// explicit 'self.' to make capture semantics explicit".
counter += 1
}
}
}
```
### In C and Objective-C
Clang understands the `noescape` attribute, spelled `__attribute__((noescape))` or `__attribute__((__noescape__))`. When function definitions whose block or function-pointer parameters have this attribute are imported to Swift, they are visible with a Swift `@noescape` attribute.
```c
void performWithLock(__attribute__((noescape)) void (^block)()) { // exposed as @noescape to Swift
lock(myLock);
block();
unlock(myLock);
}
```
```objective-c
- (void)performWithLock:(__attribute__((noescape)) void (^)())block { // exposed as @noescape to Swift
[myLock lock];
block();
[myLock unlock];
}
```
## Motivation
Many standard methods and functions — particularly in Foundation and libdispatch — have non-escaping closure semantics, but **do not have `__attribute__((noescape))`**. This thwarts the compiler optimizations and syntax shortcuts granted by `@noescape`, when they should otherwise be applied.
In pure Swift, there is no workaround, but by writing some custom C/Objective-C wrapper functions, users can work around these limitations:
```objective-c
// MyProject-Bridging-Header.h
NS_INLINE void MyDispatchSyncWrapper(dispatch_queue_t queue, __attribute__((noescape)) dispatch_block_t block)
{
dispatch_sync(queue, block);
}
```
However, it's clear that library functions with non-escaping semantics should be marked with the `noescape` attribute at the source, so that users don't have to wrap every function they'd like to use.
## Proposed solution
1. Audit system C/Objective-C libraries (libdispatch, Foundation, ...) for functions and methods with closure parameters that are guaranteed not to escape the lifetime of the call.
- *See the end of this document for a proposed list of candidate functions/methods.*
2. Annotate such functions and methods' block/function-pointer parameters with `__attribute__((noescape))` via a macro where appropriate.
3. Add a new macro in a common area (CoreFoundation/Foundation) to provide a compiler support braced use of this attribute. This macro will allow higher level frameworks and applications to adopt this annotation where appropriate.
4. For libraries with Swift-specific forks (like [swift-corelibs-libdispatch](https://github.com/apple/swift-corelibs-libdispatch)), the change should be made in the Apple-internal upstream version as well.
###### Example patch
An example patch to libdispatch can be seen at https://github.com/apple/swift-corelibs-libdispatch/pull/6/files.
## Impact on existing code
Users who previously used functions which are newly `@noescape` may have unnecessary instances of `self.` in their code. However, there should be no breaking syntax changes and no functional difference.
## Alternatives considered
The Swift compiler's support for supplementary "API notes" (`.apinotes` files) could be extended and used to annotate closure parameters as non-escaping.
However, I believe it's better to put annotations in headers for the following reasons:
- The presence of `__attribute__((noescape))` in library headers clarifies API contracts, and encourages users to use this attribute in their own code where applicable.
- With apinotes, the benefits to Swift would be limited to specific libraries and functions, leaving annotation in the hands of the Swift compiler project. Given a version of a library with annotated headers, however, no extra compiler configuration is required to take advantage of the annotation.
- As Clang itself improves, the benefits of `__attribute__((noescape))` can be granted to Objective-C callers as well as Swift (for example, by suppressing `-Wimplicit-retain-self` <rdar://19914650>).
## CoreFoundation
CoreFoundation will now provide a macro for annotating noescape methods and the following public functions will be annotated accordingly:
```c
#if __has_attribute(noescape)
#define CF_NOESCAPE __attribute__((noescape))
#else
#define CF_NOESCAPE
#endif
```
### CFArray
```c
void CFArrayApplyFunction(CFArrayRef theArray, CFRange range, CFArrayApplierFunction CF_NOESCAPE applier, void *context);
```
### CFBag
```c
void CFBagApplyFunction(CFBagRef theBag, CFBagApplierFunction CF_NOESCAPE applier, void *context);
```
### CFDictionary
```c
void CFDictionaryApplyFunction(CFDictionaryRef theDict, CFDictionaryApplierFunction CF_NOESCAPE applier, void *context);
```
### CFSet
```c
void CFSetApplyFunction(CFSetRef theSet, CFSetApplierFunction CF_NOESCAPE applier, void *context);
```
### CFTree
```c
void CFTreeApplyFunctionToChildren(CFTreeRef tree, CFTreeApplierFunction CF_NOESCAPE applier, void *context);
```
## Foundation
Foundation will provide the following macro and methods annotated accordingly:
```objc
#define NS_NOESCAPE CF_NOESCAPE
```
### NSArray
```objc
- (NSArray *)sortedArrayUsingFunction:(NSInteger (NS_NOESCAPE *)(ObjectType, ObjectType, void * _Nullable))comparator context:(nullable void *)context;
- (NSArray *)sortedArrayUsingFunction:(NSInteger (NS_NOESCAPE *)(ObjectType, ObjectType, void * _Nullable))comparator context:(nullable void *)context hint:(nullable NSData *)hint;
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (NSUInteger)indexOfObjectPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSUInteger)indexOfObjectWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSUInteger)indexOfObjectAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSIndexSet *)indexesOfObjectsWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSIndexSet *)indexesOfObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSArray *)sortedArrayUsingComparator:(NSComparator NS_NOESCAPE)cmptr NS_AVAILABLE(10_6, 4_0);
- (NSArray *)sortedArrayWithOptions:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr NS_AVAILABLE(10_6, 4_0);
- (NSUInteger)indexOfObject:(ObjectType)obj inSortedRange:(NSRange)r options:(NSBinarySearchingOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmp NS_AVAILABLE(10_6, 4_0); // binary search
```
### NSMutableArray
```objc
- (void)sortUsingFunction:(NSInteger (NS_NOESCAPE *)(ObjectType, ObjectType, void * _Nullable))compare context:(nullable void *)context;
- (void)sortUsingComparator:(NSComparator NS_NOESCAPE)cmptr NS_AVAILABLE(10_6, 4_0);
- (void)sortWithOptions:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr NS_AVAILABLE(10_6, 4_0);
```
### NSAttributedString
```objc
- (void)enumerateAttributesInRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSDictionary *attrs, NSRange range, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateAttribute:(NSString *)attrName inRange:(NSRange)enumerationRange options:(NSAttributedStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(id _Nullable value, NSRange range, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
```
### NSCalendar
```objc
- (void)enumerateDatesStartingAfterDate:(NSDate *)start matchingComponents:(NSDateComponents *)comps options:(NSCalendarOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSDate * _Nullable date, BOOL exactMatch, BOOL *stop))block NS_AVAILABLE(10_9, 8_0);
```
### NSData
```objc
- (void) enumerateByteRangesUsingBlock:(void (NS_NOESCAPE ^)(const void *bytes, NSRange byteRange, BOOL *stop))block NS_AVAILABLE(10_9, 7_0);
```
### NSDictionary
```objc
- (void)enumerateKeysAndObjectsUsingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (NSArray *)keysSortedByValueUsingComparator:(NSComparator NS_NOESCAPE)cmptr NS_AVAILABLE(10_6, 4_0);
- (NSArray *)keysSortedByValueWithOptions:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr NS_AVAILABLE(10_6, 4_0);
- (NSSet *)keysOfEntriesPassingTest:(BOOL (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSSet *)keysOfEntriesWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(KeyType key, ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
```
### NSIndexSet
```objc
- (void)enumerateIndexesUsingBlock:(void (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateIndexesWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateIndexesInRange:(NSRange)range options:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (NSUInteger)indexPassingTest:(BOOL (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSUInteger)indexWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSUInteger)indexInRange:(NSRange)range options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSIndexSet *)indexesPassingTest:(BOOL (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSIndexSet *)indexesWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSIndexSet *)indexesInRange:(NSRange)range options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(NSUInteger idx, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (void)enumerateRangesUsingBlock:(void (NS_NOESCAPE ^)(NSRange range, BOOL *stop))block NS_AVAILABLE(10_7, 5_0);
- (void)enumerateRangesWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSRange range, BOOL *stop))block NS_AVAILABLE(10_7, 5_0);
- (void)enumerateRangesInRange:(NSRange)range options:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSRange range, BOOL *stop))block NS_AVAILABLE(10_7, 5_0);
```
### NSLinguisticTagger
```objc
- (void)enumerateTagsInRange:(NSRange)range scheme:(NSString *)tagScheme options:(NSLinguisticTaggerOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop))block NS_AVAILABLE(10_7, 5_0);
- (void)enumerateLinguisticTagsInRange:(NSRange)range scheme:(NSString *)tagScheme options:(NSLinguisticTaggerOptions)opts orthography:(nullable NSOrthography *)orthography usingBlock:(void (NS_NOESCAPE ^)(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop))block NS_AVAILABLE(10_7, 5_0);
```
### NSMetadataQuery
```objc
- (void)enumerateResultsUsingBlock:(void (NS_NOESCAPE ^)(id result, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_9, 7_0);
- (void)enumerateResultsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(id result, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_9, 7_0);
```
### NSOrderedSet
```objc
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
- (void)enumerateObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))block;
- (NSUInteger)indexOfObjectPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate;
- (NSUInteger)indexOfObjectWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate;
- (NSUInteger)indexOfObjectAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate;
- (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate;
- (NSIndexSet *)indexesOfObjectsWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate;
- (NSIndexSet *)indexesOfObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, NSUInteger idx, BOOL *stop))predicate;
- (NSUInteger)indexOfObject:(ObjectType)object inSortedRange:(NSRange)range options:(NSBinarySearchingOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmp; // binary search
- (NSArray *)sortedArrayUsingComparator:(NSComparator NS_NOESCAPE)cmptr;
- (NSArray *)sortedArrayWithOptions:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr;
```
### NSMutableOrderedSet
```objc
- (void)sortUsingComparator:(NSComparator NS_NOESCAPE)cmptr;
- (void)sortWithOptions:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr;
- (void)sortRange:(NSRange)range options:(NSSortOptions)opts usingComparator:(NSComparator NS_NOESCAPE)cmptr;
```
### NSRegularExpression
```objc
- (void)enumerateMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range usingBlock:(void (NS_NOESCAPE ^)(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL *stop))block;
```
### NSSet
```objc
- (void)enumerateObjectsUsingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (NSSet *)objectsPassingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
- (NSSet *)objectsWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (NS_NOESCAPE ^)(ObjectType obj, BOOL *stop))predicate NS_AVAILABLE(10_6, 4_0);
```
### NSString
```objc
- (void)enumerateSubstringsInRange:(NSRange)range options:(NSStringEnumerationOptions)opts usingBlock:(void (NS_NOESCAPE ^)(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
- (void)enumerateLinesUsingBlock:(void (NS_NOESCAPE ^)(NSString *line, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
```
================================================
FILE: proposals/0013-remove-partial-application-super.md
================================================
# Remove Partial Application of Non-Final Super Methods (Swift 2.2)
* Proposal: [SE-0013](0013-remove-partial-application-super.md)
* Author: [Ashley Garland](https://github.com/bitjammer)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Rejected**
* Decision Notes: [Rationale](https://forums.swift.org/t/rejected-se-0013-remove-partial-application-of-non-final-super-methods/1157)
## Introduction
Prior to Swift 2.2, calls to superclass methods like `super.foo()` in
Native Swift classes were dispatched statically by recording a reference
to the function and calling it directly by its mangled name. In Swift
2.2, class methods invoked via `super` will use dynamic dispatch. That
is, the method will be looked up in the superclass's vtable at runtime.
However, if the method is marked with `final`, it will use the old
static dispatch, since no class will be able to override it.
The mechanisms that support currying require thunks to be emitted so
that the function can be called at various uncurrying levels. Currying
will be removed in Swift 3.0 so, rather than invest more engineering in
those mechanisms, I propose that we disallow partial application of
non-final methods through `super`, except where the `self` parameter is
implicitly captured.
[Swift Evolution Discussion Thread](https://forums.swift.org/t/swift-2-2-removing-partial-application-of-super-method-calls/264)
## Motivation
The motivation of this change is partially motivated by implementation
concerns. The machinery for curry thunk mechanism has a lot of
assumptions about what the ultimate function call will be: an apply of a
static `function_ref` or a dynamic dispatch through a `class_method`,
which originate in something like `doFoo(self.foo)` (note `self` instead
of `super`). Rather than risk regressions stemming from significant
replumbing, it would a good tradeoff to pull in this limited portion of
the currying removals in Swift 3.0.
## Detailed design
In terms of design and implementation, this is a trivial change. In
semantic analysis, perform the following check on call expressions: if
the call expression is based in super, the referenced function isn't
final, and the application does not fulfill all of the parameters, emit
an error diagnostic.
### Example Code
#### Illegal: Partial application of non-final method
```swift
func doFoo(f: () -> ()) {
f()
}
class Base {
func foo()() {}
}
class Derived : Base {
override func foo()() {
doFoo(super.foo()) // Illegal - doesn't apply the second time.
}
}
```
#### OK: Partial application of final method
This is safe because the new dynamic super dispatch mechanisms don't
kick in for final methods - these fall back to the original static
function reference because no class can ever override the original
implementation.
```swift
func doFoo(f: () -> ()) {
f()
}
class Base {
final func foo()() {}
}
class Derived : Base {
func bar() {
doFoo(super.foo()) // OK - method is final.
}
}
```
The implementation for this change is available on [apple/swift/remove-partial-super].
#### OK: Partial application with implicit self
Partial application of the implicit self parameter is still allowed with
this change. When you pass `super.foo` around, you have in fact
partially applied the method - you've captured the `self` argument
present in all Swift method calls. This is safe because no explicit
thunks need to be generated at SILGen - the `partial_apply` instruction
will create a closure without additional SIL code.
```swift
func doFoo(f: () -> ()) {
f()
}
class Base {
func foo() {}
}
class Derived : Base {
func bar() {
doFoo(super.foo) // OK - only partially applies self
}
}
```
## Impact on existing code
Given that we've decided to remove currying outright, this would be a
small percentage of that usage. Generally, calls on `super` are for
delegation, where all arguments are often present.
## Alternatives considered
The only alternative is to make super method dispatch a citizen in the
thunk emission process, which requires deep changes to SILGen, symbol
mangling, and IRGen. Although this more comprehensive change would allow
us to adopt dynamic super dispatch with no source changes for those
writing in Swift, I believe the proposal is a reasonable tradeoff.
[apple/swift/remove-partial-super]: https://github.com/apple/swift/tree/remove-partial-super
================================================
FILE: proposals/0014-constrained-AnySequence.md
================================================
# Constraining `AnySequence.init`
* Proposal: [SE-0014](0014-constrained-AnySequence.md)
* Author: [Max Moiseev](https://github.com/moiseev)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Implemented (Swift 2.2)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0014-constraining-anysequence-init/924)
* Bug: [SR-474](https://bugs.swift.org/browse/SR-474)
## Introduction
In order to allow `AnySequence` delegate calls to the underlying sequence,
its initializer should have extra constraints.
[Swift Evolution Discussion](https://forums.swift.org/t/restricting-anysequence-init/254)
## Motivation
At the moment `AnySequence` does not delegate calls to `SequenceType` protocol
methods to the underlying base sequence, which results in dynamic downcasts in
places where this behavior is needed (see default implementations of
`SequenceType.dropFirst` or `SequenceType.prefix`). Besides, and this is even
more important, customized implementations of `SequenceType` methods would be
ignored without delegation.
## Proposed solution
See the implementation in [this PR](https://github.com/apple/swift/pull/220).
In order for this kind of delegation to become possible, `_SequenceBox` needs to
be able to 'wrap' not only the base sequence but also its associated
`SubSequence`. So instead of being declared like this:
~~~~Swift
internal class _SequenceBox
: _AnySequenceBox { ... }
~~~~
it would become this:
~~~~Swift
internal class _SequenceBox<
S : SequenceType
where
S.SubSequence : SequenceType,
S.SubSequence.Generator.Element == S.Generator.Element,
S.SubSequence.SubSequence == S.SubSequence
> : _AnySequenceBox { ... }
~~~~
Which, in its turn, will lead to `AnySequence.init` getting a new set of
constraints as follows.
Before the change:
~~~~Swift
public struct AnySequence : SequenceType {
public init<
S: SequenceType
where
S.Generator.Element == Element
>(_ base: S) { ... }
}
~~~~
After the change:
~~~~Swift
public struct AnySequence : SequenceType {
public init<
S: SequenceType
where
S.Generator.Element == Element,
S.SubSequence : SequenceType,
S.SubSequence.Generator.Element == Element,
S.SubSequence.SubSequence == S.SubSequence
>(_ base: S) { ... }
}
~~~~
These constraints, in fact, should be applied to `SequenceType` protocol itself
(although, that is not currently possible), as we expect every `SequenceType`
implementation to satisfy them already. Worth mentioning that technically
`S.SubSequence.SubSequence == S.SubSequence` does not have to be this strict,
as any sequence with the same element type would do, but that is currently not
representable.
## Impact on existing code
New constraints do not affect any built-in types that conform to
`SequenceType` protocol as they are essentially constructed like this
(`SubSequence.SubSequence == SubSequence`). 3rd party collections, if they use
the default `SubSequence` (i.e. `Slice`), should also be fine. Those having
custom `SubSequence`s may stop conforming to the protocol.
================================================
FILE: proposals/0015-tuple-comparison-operators.md
================================================
# Tuple comparison operators
* Proposal: [SE-0015](0015-tuple-comparison-operators.md)
* Author: [Lily Ballard](https://github.com/lilyball)
* Review Manager: [Dave Abrahams](https://github.com/dabrahams)
* Status: **Implemented (Swift 2.2)**
* Decision Notes: [Rationale](https://forums.swift.org/t/review-add-a-lazy-flatmap-for-sequences-of-optionals/695/4)
* Implementation: [apple/swift#408](https://github.com/apple/swift/pull/408)
## Introduction
Implement comparison operators on tuples up to some arity.
[Swift Evolution Discussion](https://forums.swift.org/t/proposal-implement-and-for-tuples-where-possible-up-to-some-high-arity/251), [Review](https://forums.swift.org/t/review-add-a-lazy-flatmap-for-sequences-of-optionals/695)
Note: The review was initially started on the wrong thread with the wrong title and subsequently corrected.
## Motivation
It's annoying to try and compare tuples of comparable values and discover that
tuples don't support any of the common comparison operators. There's an
extremely obvious definition of `==` and `!=` for tuples of equatable values,
and a reasonably obvious definition of the ordered comparison operators as well
(lexicographical compare).
Beyond just comparing tuples, being able to compare tuples also makes it easier
to implement comparison operators for tuple-like structs, as the relevant
operator can just compare tuples containing the struct properties.
## Proposed solution
The Swift standard library should provide generic implementations of the
comparison operators for all tuples up to some specific arity. The arity should
be chosen so as to balance convenience (all tuples support this) and code size
(every definition adds to the size of the standard library).
When Swift gains support for conditional conformation to protocols, and if Swift
ever gains support for extending tuples, then the tuples up to the chosen arity
should also be conditionally declared as conforming to `Equatable` and
`Comparable`.
If Swift ever gains support for variadic type parameters, then we should
investigate redefining the operators (and protocol conformance) in terms of
variadic types, assuming there's no serious codesize issues.
## Detailed design
The actual definitions will be generated by gyb. The proposed arity here is 6,
which is large enough for most reasonable tuples (but not as large as I'd
prefer), without having massive code increase. After implementing this proposal
for arity 6, a Ninja-ReleaseAssert build increases codesize for
`libswiftCore.dylib` (for both macosx and iphoneos) by 43.6KiB, which is a
1.4% increase.
The generated definitions look like the following (for arity 3):
```swift
@warn_unused_result
public func == (lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2
}
@warn_unused_result
public func != (lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
return lhs.0 != rhs.0 || lhs.1 != rhs.1 || lhs.2 != rhs.2
}
@warn_unused_result
public func < (lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
if lhs.0 != rhs.0 { return lhs.0 < rhs.0 }
if lhs.1 != rhs.1 { return lhs.1 < rhs.1 }
return lhs.2 < rhs.2
}
@warn_unused_result
public func <= (lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
if lhs.0 != rhs.0 { return lhs.0 < rhs.0 }
if lhs.1 != rhs.1 { return lhs.1 < rhs.1 }
return lhs.2 <= rhs.2
}
@warn_unused_result
public func > (lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
if lhs.0 != rhs.0 { return lhs.0 > rhs.0 }
if lhs.1 != rhs.1 { return lhs.1 > rhs.1 }
return lhs.2 > rhs.2
}
@warn_unused_result
public func >= (lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
if lhs.0 != rhs.0 { return lhs.0 > rhs.0 }
if lhs.1 != rhs.1 { return lhs.1 > rhs.1 }
return lhs.2 >= rhs.2
}
```
## Impact on existing code
No existing code should be affected.
## Alternatives considered
I tested building a Ninja-ReleaseAssert build for tuples up to arity 12, but
that had a 171KiB codesize increase (5.5%). I have not tried any other arities.
================================================
FILE: proposals/0016-initializers-for-converting-unsafe-pointers-to-ints.md
================================================
# Add initializers to Int and UInt to convert from UnsafePointer and UnsafeMutablePointer
* Proposal: [SE-0016](0016-initializers-for-converting-unsafe-pointers-to-ints.md)
* Author: [Michael Buckley](https://github.com/MichaelBuckley)
* Review Manager: [Chris Lattner](https://github.com/lattner)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0016-adding-initializers-to-int-and-uint-to-convert-from-unsafepointer-and-unsafemutablepointer/2005)
* Bug: [SR-1115](https://bugs.swift.org/browse/SR-1115)
* Previous Revision: [1](https://github.com/swiftlang/swift-evolution/blob/ae2d7c24fff7cbdff754d9a4339e4fb02df5c690/proposals/0016-initializers-for-converting-unsafe-pointers-to-ints.md)
## Introduction
Just as users can create `Unsafe[Mutable]Pointer`s from `Int`s and `UInt`s, they
should be able to create Ints and UInts from `Unsafe[Mutable]Pointer`s. This will
allow users to call C functions with `intptr_t` and `uintptr_t` parameters, and will
allow users to perform more advanced pointer arithmetic than is allowed by
`UnsafePointer`s.
[Swift Evolution Discussion](https://forums.swift.org/t/proposal-add-initializers-for-converting-unsafepointers-to-int-and-unit/331), [Review](https://forums.swift.org/t/review-se-0016-adding-initializers-to-int-and-uint-to-convert-from-unsafepointer-and-unsafemutablepointer/1899)
## Motivation
Swift currently lacks the ability to perform many complex operations on
pointers, such as checking pointer alignment, tagging pointers, or XORing
pointers (for working with XOR linked lists, for example). As a systems
programming language, Swift ought to be able to solve these problems natively
and concisely.
Additionally, since some C functions take `intptr_t` and `uintptr_t` parameters,
Swift currently has no ability to call these functions directly. Users must wrap
calls to these functions in C code.
## Proposed solution
Initializers will be added to `Int` and `UInt` to convert from `UnsafePointer`,
`UnsafeMutablePointer`, and `OpaquePointer`.
Currently, the only workaround which can solve these problems is to write any
code that requires pointer arithmetic in C. Writing this code in Swift will be
no safer than it is in C, as this is a fundamentally unsafe operation. However,
it will be cleaner in that users will not be forced to write C code.
## Detailed design
The initializers will be implemented using the built-in `ptrtoint_Word` function.
```swift
extension UInt {
init(bitPattern: UnsafePointer) {
self = UInt(Builtin.ptrtoint_Word(bitPattern._rawValue))
}
init(bitPattern: UnsafeMutablePointer) {
self = UInt(Builtin.ptrtoint_Word(bitPattern._rawValue))
}
init(bitPattern: OpaquePointer) {
self = UInt(Builtin.ptrtoint_Word(bitPattern._rawValue))
}
}
extension Int {
init(bitPattern: UnsafePointer) {
self = Int(Builtin.ptrtoint_Word(bitPattern._rawValue))
}
init(bitPattern: UnsafeMutablePointer) {
self = Int(Builtin.ptrtoint_Word(bitPattern._rawValue))
}
init(bitPattern: OpaquePointer) {
self = Int(Builtin.ptrtoint_Word(bitPattern._rawValue))
}
}
```
As an example, these initializers will allow the user to get the next address of
an XOR linked list in Swift.
```swift
struct XORLinkedList {
let address: UnsafePointer
...
func successor(_ predecessor: XORLinkedList) -> XORLinkedList {
let next = UInt(bitPattern: address) ^ UInt(bitPattern: predecessor.address)
return XorLinkedList(UnsafePointer(bitPattern: next))
}
}
```
## Impact on existing code
There is no impact on existing code.
## Alternatives considered
Three alternatives were considered.
The first alternative was to add an `intValue` function to `Unsafe[Mutable]Pointer`.
This alternative was rejected because it is preferred that type conversions be
implemented as initializers where possible.
The next alternative was to add functions to `Unsafe[Mutable]Pointer` which
covered the identified pointer arithmetic cases. This alternative was rejected
because it either would have required us to imagine every use-case of pointer
arithmetic and write functions for them, which is an impossible task, or it
would have required adding a full suite of arithmetic and bitwise operators to
`Unsafe[Mutable]Pointer`. Because some of these operations are defined only on
signed integers, and others on unsigned, it would have required splitting
`Unsafe[Mutable]Pointer` into signed and unsigned variants, which would have
complicated things for users who did not need to do pointer arithmetic.
Additionally, the implementations of these operations would have probably
converted the pointers to integers, perform a single operation, and then convert
them back. When chaining operations, this would create a lot of unnecessary
conversions.
The last alternative was to forgo these initializers and force users to write
all their complicated pointer code in C. This alternative was rejected because
it makes Swift less useful as a systems programming language.
## Changes from revision 1
- The proposal was amended post-acceptance to include `OpaquePointer`.
Originally it only included `UnsafePointer` and `UnsafeMutablePointer`.
================================================
FILE: proposals/0017-convert-unmanaged-to-use-unsafepointer.md
================================================
# Change `Unmanaged` to use `UnsafePointer`
* Proposal: [SE-0017](0017-convert-unmanaged-to-use-unsafepointer.md)
* Author: [Jacob Bandes-Storch](https://github.com/jtbandes)
* Review Manager: [Chris Lattner](https://github.com/lattner)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0017-change-unmanaged-to-use-unsafepointer/2461)
* Bug: [SR-1485](https://bugs.swift.org/browse/SR-1485)
## Introduction
The standard library [`Unmanaged` struct](https://github.com/apple/swift/blob/master/stdlib/public/core/Unmanaged.swift) provides a type-safe object wrapper that does not participate in ARC; it allows the user to make manual retain/release calls.
[Swift Evolution Discussion](https://forums.swift.org/t/unmanaged-and-copaquepointer-vs-unsafe-mutable-pointer/295), [Proposed Rewrite Discussion](https://forums.swift.org/t/rfc-proposed-rewrite-of-unmanaged-t/612), [Review](https://forums.swift.org/t/review-se-0017-change-unmanaged-to-use-unsafepointer/2380)
## Motivation
The following methods are provided for converting to/from Unmanaged:
```swift
static func fromOpaque(value: COpaquePointer) -> Unmanaged
func toOpaque() -> COpaquePointer
```
However, C APIs that accept `void *` or `const void *` are exposed to Swift as `UnsafePointer` or `UnsafeMutablePointer`, rather than `COpaquePointer`. In practice, users must convert `UnsafePointer` → `COpaquePointer` → `Unmanaged`, which leads to bloated code such as
```swift
someFunction(context: UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque()))
info.retain = { Unmanaged.fromOpaque(COpaquePointer($0)).retain() }
info.copyDescription = {
Unmanaged.passRetained(CFCopyDescription(Unmanaged.fromOpaque(COpaquePointer($0)).takeUnretainedValue()))
}
```
## Proposed solution
In the `Unmanaged` API, replace the usage of `COpaquePointer` with `UnsafePointer` and `UnsafeMutablePointer`.
The affected functions are `fromOpaque()` and `toOpaque()`. Only very minor modification is required from the [current implementation](https://github.com/apple/swift/blob/0287ac7fd94af0fb860b5444e1bd26faded88e39/stdlib/public/core/Unmanaged.swift#L32-L54):
```swift
@_transparent
@warn_unused_result
public static func fromOpaque(value: UnsafePointer) -> Unmanaged {
// Null pointer check is a debug check, because it guards only against one
// specific bad pointer value.
_debugPrecondition(
value != nil,
"attempt to create an Unmanaged instance from a null pointer")
return Unmanaged(_private: unsafeBitCast(value, Instance.self))
}
@_transparent
@warn_unused_result
public func toOpaque() -> UnsafeMutablePointer {
return unsafeBitCast(_value, UnsafeMutablePointer.self)
}
```
Note that values of type `UnsafeMutablePointer` can be passed to functions accepting either `UnsafePointer` or `UnsafeMutablePointer`, so for simplicity and ease of use, we choose `UnsafePointer` as the input type to `fromOpaque()`, and `UnsafeMutablePointer` as the return type of `toOpaque()`.
The example usage above no longer requires conversions:
```swift
someFunction(context: Unmanaged.passUnretained(self).toOpaque())
info.retain = { Unmanaged.fromOpaque($0).retain() }
info.copyDescription = {
Unmanaged.passRetained(CFCopyDescription(Unmanaged.fromOpaque($0).takeUnretainedValue()))
}
```
## Impact on existing code
Code previously calling `Unmanaged` API with `COpaquePointer` will need to change to use `UnsafePointer`. The `COpaquePointer` variants can be kept with availability attributes to aid the transition, such as:
@available(*, unavailable, message="use fromOpaque(value: UnsafeMutablePointer) instead")
@available(*, unavailable, message="use toOpaque() -> UnsafePointer instead")
[Code that uses `COpaquePointer`](https://github.com/search?q=COpaquePointer&type=Code) does not seem to depend on it heavily, and would not be significantly harmed by this change.
## Alternatives considered
- Make no change. However, it has been [said on swift-evolution](https://forums.swift.org/t/unmanaged-and-copaquepointer-vs-unsafe-mutable-pointer/295/3) that `COpaquePointer` is vestigial, and better bridging of C APIs is desired, so we do want to move in this direction.
================================================
FILE: proposals/0018-flexible-memberwise-initialization.md
================================================
# Flexible Memberwise Initialization
* Proposal: [SE-0018](0018-flexible-memberwise-initialization.md)
* Author: [Matthew Johnson](https://github.com/anandabits)
* Review Manager: [Chris Lattner](https://github.com/lattner)
* Status: **Returned for revision**
* Review: ([pitch](https://forums.swift.org/t/proposal-draft-flexible-memberwise-initialization/698)) ([review](https://forums.swift.org/t/review-se-0018-flexible-memberwise-initialization/939)) ([deferral](https://forums.swift.org/t/review-se-0018-flexible-memberwise-initialization/939/22)) ([return for revision](https://forums.swift.org/t/returning-or-rejecting-all-the-deferred-evolution-proposals/60724))
## Introduction
The Swift compiler is currently able to generate a memberwise initializer for use in some circumstances, however there are currently many limitations to this. This proposal builds on the idea of a compiler generated memberwise initializer, making the capability available to any initializer that opts in.
## Motivation
When designing initializers for a type we are currently faced with the unfortunate fact that the more flexibility we wish to offer users the more boilerplate we are required to write and maintain. We usually end up with more boilerplate and less flexibility than desired. There have been various strategies employed to mitigate this problem, including:
1. Sometimes properties that should be immutable are made mutable and a potentially unsafe ad-hoc two-phase initialization pattern is employed where an instance is initialized and then configured immediately afterwards. This allows the developer to avoid including boilerplate in every initializer that would otherwise be required to initialize immutable properties.
2. Sometimes mutable properties that have a sensible default value are simply default-initialized and the same post-initialization configuration strategy is employed when the default value is not correct for the intended use. This results in an instance which may pass through several states that are incorrect *for the intended use* before it is correctly initialized for its intended use.
Underlying this problem is the fact that initialization scales with M x N complexity (M members, N initializers). We need as much help from the compiler as we can get!
Flexible and concise initialization for both type authors and consumers will encourages using immutability where possible and removes the need for boilerplate from the concerns one must consider when designing the initializers for a type.
Quoting [Chris Lattner](https://forums.swift.org/t/proposal-helpers-for-initializing-properties-of-same-name-as-parameters/129/8):
The default memberwise initializer behavior of Swift has at least these deficiencies (IMO):
1) Defining a custom init in a struct disables the memberwise initializer, and there is no easy way to get it back.
2) Access control + the memberwise init often requires you to implement it yourself.
3) We don’t get memberwise inits for classes.
4) var properties with default initializers should have their parameter to the synthesized initializer defaulted.
5) lazy properties with memberwise initializers have problems (the memberwise init eagerly touches it).
Add to the list “all or nothing”. The compiler generates the entire initializer and does not help to eliminate boilerplate for any other initializers where it may be desirable to use memberwise initialization for a subset of members and initialize others manually.
It is common to have a type with a number of public members that are intended to be configured by clients, but also with some private state comprising implementation details of the type. This is especially prevalent in UI code which may expose many properties for configuring visual appearance, etc. Flexible memberwise initialization can provide great benefit in these use cases, but it immediately becomes useless if it is "all or nothing".
We need a flexible solution that can synthesize memberwise initialization for some members while allowing the type author full control over initialization of implementation details.
## Proposed solution
I propose adding a `memberwise` declaration modifier for initializers which allows them to *opt-in* to synthesis of memberwise initialization.
This proposal adopts a model for property eligibility where stored properties automatically receive memberwise initialization parameters unless they are deemed ineligible for one of several reasons. An *opt-in* model using a `memberwise` declaration modifier allowing properties to *opt-in* to memberwise initialization synthesis is also possible.
The two approaches are not mutually exclusive: it is possible to use the *automatic* model when no properties have the `memberwise` declaration modifier and the *opt-in* model when one or more properties do have the `memberwise` declaration modifier. A future enhancement to this proposal may introduce the *opt-in* model, allowing programmers to choose which model is preferred for a specific type they are authoring.
The *automatic* model of the current proposal determines the set of properties that receive memberwise initialization parameters by considering *only* the initializer declaration and the declarations for all properties that are *at least* as visible as the initializer (including any behaviors attached to the properties). The rules are as follows:
1. The access level of the property is *at least* as visible as the memberwise initializer. The visibility of the **setter** is used for `var` properties.
2. They do not have a behavior which prohibits memberwise initialization (e.g. the 'lazy' behavior).
3. If the property is a `let` property it *may not* have an initial value.
The parameters are synthesized in the parameter list in the location of the `...` placeholder. It is a compile-time error for a memberwise initializer to omit the `...` placeholder. The parameter list is ordered as follows:
1. All parameters **without** default values precede parameters **with** default values.
2. Within each group, parameters follow property declaration order.
Under the current proposal only `var` properties could specify a default value, which would be the initial value for that property. It may be possible for `let` properties to specify a default value in the future using the `@default` enhancement or some other mechanism allowing the default value to be specified.
## Examples
This section of the document contains several examples of the solution in action. It *does not* cover every possible scenario. If there are concrete examples you are wondering about please post them to the list. I will be happy to discuss them and will add any examples we consider important to this section as the discussion progresses.
Specific details on how synthesis is performed are contained in the detailed design.
### Replacing the current memberwise initializer
```swift
struct S {
let s: String
let i: Int
// user declares:
memberwise init(...) {}
// compiler synthesizes:
init(s: String, i: Int) {
/* synthesized */ self.s = s
/* synthesized */ self.i = i
}
}
```
### Var properties with initial values
NOTE: this example is only possible for `var` properties due to the initialization rules for `let` properties. If the initializer expression contains side effects, then the side effect is not evaluated if passed in explicitly by a caller of the memberwise initializer.
```swift
struct S {
var s: String = "hello"
var i: Int = 42
// user declares:
memberwise init(...) {}
// compiler synthesizes:
init(s: String = "hello", i: Int = 42) {
/* synthesized */ self.s = s
/* synthesized */ self.i = i
}
}
```
### Access control
```swift
struct S {
let s: String
private let i: Int
// user declares:
memberwise init(...) {
// compiler error, i memberwise initialization cannot be synthesized
// for i because it is less visible than the initializer itself
}
}
```
```swift
struct S {
let s: String
private let i: Int
// user declares:
memberwise init(...) {
i = 42
}
// compiler synthesizes (suppressing memberwise initialization for properties with lower visibility):
init(s: String) {
/* synthesized */ self.s = s
// body of the user's initializer remains
i = 42
}
}
```
### Manually declared parameters
```swift
struct S {
let s: String
private let i: Int
// user declares:
memberwise init(anInt: Int, anotherInt: Int, ...) {
i = anInt > anotherInt ? anInt : anotherInt
}
// compiler synthesizes (suppressing memberwise initialization for properties with lower visibility):
init(anInt: Int, anotherInt: Int, s: String) {
/* synthesized */ self.s = s
// body of the user's initializer remains
i = anInt > anotherInt ? anInt : anotherInt
}
}
```
### Lazy properties and incompatible behaviors
```swift
struct S {
let s: String
lazy var i: Int = InitialValueForI()
// user declares:
memberwise init(...) {
}
// compiler synthesizes:
init(s: String) {
/* synthesized */ self.s = s
// compiler does not synthesize initialization for i
// because it contains a behavior that is incompatible with
// memberwise initialization.
}
}
```
## Detailed design
### Syntax changes
This proposal introduces two new syntactic elements: the `memberwise` declaration modifier and the `...` memberwise parameter placeholder.
Designated initializers opt-in to synthesized memberwise initialization with the `memberwise` declaration modifier. This modifier will cause the compiler to follow the procedure outlined later in the design to synthesize memberwise parameters as well as memberwise initialization code at the beginning of the initializer body.
### Overview
Throughout this design the term **memberwise initialization parameter** is used to refer to initializer parameters synthesized by the compiler as part of **memberwise initialization synthesis**.
#### Algorithm
1. Determine the set of properties eligible for memberwise initialization synthesis. Properties are eligible for memberwise initialization synthesis if:
1. The access level of the property is *at least* as visible as the memberwise initializer. The visibility of the **setter** is used for `var` properties.
2. They do not have a behavior which prohibits memberwise initialization.
3. If the property is a `let` property it *may not* have an initial value.
2. Determine the default value, if one exists, for each *memberwise initialization parameter*. Under the current proposal only `var` properties could specify a default value, which would be the initial value for that property.
3. If the initializer declares any parameters with external labels matching the name of any of the properties eligible for memberwise initialization report a compiler error.
4. Synthesize *memberwise initialization parameters* in the location where the `...` placeholder was specified. The synthesized parameters should have external labels matching the property name. Place the synthesized parameters in the following order:
1. All parameters **without** default values precede parameters **with** default values.
2. Within each group, follow property declaration order.
5. Synthesize initialization of all *memberwise initialization parameters* at the beginning of the initializer body.
6. If the initializer body assigns to a `var` property that received memberwise initialization synthesis report a warning. It is unlikely that overwriting the value provided by the caller is the desired behavior.
## Impact on existing code
This proposal will also support generating an *implicit* memberwise initializer for classes and structs when the following conditions are true:
1. The type declares no initializers explicitly.
2. The type is:
1. a struct
2. a root class
3. a class whose superclass has a designated initializer requiring no arguments
The implicitly generated memberwise initializer will have the highest access level possible while still allowing all stored properties to be eligible for memberwise parameter synthesis, but will have at most `internal` visibility. Currently this means its visibility will be `internal` when all stored properties of the type have setters with *at least* `internal` visibility, and `private` otherwise (when one or more stored properties are `private` or `private(set)`).
The *implicitly* synthesized initializer will be identical to an initializer declared *explicitly* as follows: `memberwise init(...) {}` or `private memberwise init(...) {}`.
NOTE: Because the `memberwise` declaration modifier only applies to designated initializers, it may not be used with class initializers defined in an extension. It may be used with struct initializers defined in an extension as long as all of the struct's stored properties are visible to the extension.
The changes described in this proposal are *almost* entirely additive. The only existing code that will break will be in the case of structs with stored `private` properties or `var` properties that have `private` setters which had been receiving an `internal` implicitly synthesized memberwise initializer. Options for addressing this impact are:
1. If the implicitly synthesized memberwise initializer was only used *within* the same source file no change is necessary. An implicit `private` memberwise initializer will still be synthesized by the compiler.
2. A mechanical migration could generate the explicit code necessary to declare the previously implicit initializer. This would be an `internal` memberwise initializer with *explicit* parameters used to manually initialize the stored properties with `private` setters.
3. If the "Access control for init" enhancement were accepted the `private` members could have their access control modified to `private internal(init)` which would allow the implicit memberwise initializer to continue to have `internal` visibility as all stored properties would be eligible for parameter synthesis by an `internal` memberwise initializer.
The only other impact on existing code is that memberwise parameters corresponding to `var` properties with initial values will now have default values. This will be a change in the behavior of the implicit memberwise initializer but will not break any code. The change will simply allow new code to use that initializer without providing an argument for such parameters.
## Future enhancements
In the spirit of incremental change, the current proposal is focused on core functionality. It is possible to enhance that core functionality with additional features. These enhancements may be turned into proposals after the current proposal is accepted.
### @default
It is not possible under the current proposal to specify a default value for memberwise initialization parameters of `let` properties. This is an unfortunate limitation and a solution to this is a highly desired enhancement to the current proposal.
One possible solution would be to introduce the `@default` attribute allowing `let` properties to specify a default value for the parameter the compiler synthesizes in memberwise initializers.
There are two possible syntactic approaches that could be taken by `@default`:
1. Make `@default` a modifier. The same syntax is used as for initial values, but when the `@default` attribute is specified for a property the specified value is a default rather than an initial value.
2. Allow the default value to be specified using an attribute argument.
Each syntax has advantages and disadvantages:
1. The first syntax is arguably cleaner and more readable.
2. The first syntax makes it impossible to specify both an initial value **and** a default value for the same property. This is advantageous because a `let` property should never have both and initial values for `var` properties are effectively just a default value anyway.
3. The second syntax may have less potential for confusion and thus more clear as it uses significantly different syntax for specifying initial and default values.
#### Example using the first syntax option
```swift
struct S {
@default let s: String = "hello"
@default let i: Int = 42
// user declares:
memberwise init(...) {}
// compiler synthesizes:
init(s: String = "hello", i: Int = 42) {
/* synthesized */ self.s = s
/* synthesized */ self.i = i
}
}
```
#### Example using the second syntax option
```swift
struct S {
@default("hello") let s: String
@default(42) let i: Int
// user declares:
memberwise init(...) {}
// compiler synthesizes:
init(s: String = "hello", i: Int = 42) {
/* synthesized */ self.s = s
/* synthesized */ self.i = i
}
}
```
### `memberwise` properties
The rules of the current proposal are designed to synthesize memberwise parameters for the correct set of properties as best as possible. Of course there will be times when the rules don't match what is desired.
Introducing a `memberwise` declaration modifier for properties would allow programmers to specify exactly which properties should participate in memberwise initialization synthesis. It allows full control and has the clarity afforded by being explicit.
Specific use cases this feature would support include allowing `private` properties to receive synthesized memberwise parameters in a `public` initializer, or allow `public` properties to be omitted from parameter synthesis.
An example of this
```swift
struct S {
// both properties receive memberwise initialization parameters
// regardless of access control.
memberwise public let s: String
memberwise private let i: Int
// neither property receives a memberwise initialization parameter
// regardless of access control.
public var s2 = ""
private var i2 = 42
// user declares:
memberwise init(...) {}
// compiler synthesizes:
init(s: String, i: Int) {
/* synthesized */ self.s = s
/* synthesized */ self.i = i
}
}
```
### Access control for init
In some cases it may be desirable to be able to specify distinct access control for memberwise initialization when using the *automatic* model, for example if that model *almost* has the desired behavior, but the initialization visibility of one property must be adjusted to produce the necessary result.
The syntax used would be identical to that used for specifying distinct access control for a setter. This feature would likely have its greatest utility in allowing more-private members to participate in more-public memberwise initializers. It may also be used to inhibit memberwise initialization for some members, although that use would usually be discouraged if the `@nomemberwise` proposal were also accepted.
```swift
struct S {
private internal(init) let s: String
private i: Int
// user declares:
memberwise init(...) {
i = getTheValueForI()
}
// compiler synthesizes (including a parameter for private member s despite the fact that this is an internal memberwis initializer):
init(s: String) {
/* synthesized */ self.s = s
// body of the user's initializer remains
i = getTheValueForI()
}
}
```
If this enhancement were submitted the first property eligibility rule would be updates as follows:
1. Their **init** access level is *at least* as visible as the memberwise initializer. If the property does not have an **init** access level, the access level of its **setter** must be *at least* as visible as the memberwise initializer.
### @nomemberwise
There may be cases where the author of a type would like to prevent a specific property from participating in memberwise initialization either for all initializers or for a specific initializer. The `@nomemberwise` attribute for properties and initializers supports this use case.
Memberwise initializers can explicitly prevent memberwise initialization for specific properties by including them in a list of property names provided to the `@nomemberwise` attribute like this: `@nomemberwise(prop1, prop2)`.
Under the *automatic* model, properties would be able to explicitly opt-out of memberwise initialization with the `@nomemberwise` attribute. When they do so they would not be eligible for memberwise initialization synthesis. Because of this they must be initialized directly with an initial value or initialized directly by every initializer for the type.
The `@nomemberwise` attribute would introduce two additional eligibility rules when deterimining which properties can participtate in memberwise initialization.
1. The property **is not** annotated with the `@nomemberwise` attribute.
2. The property **is not** included in the `@nomemberwise` attribute list attached of the initializer. If `super` is included in the `@nomemberwise` attribute list **no** superclass properties will participate in memberwise initialization.
#### Examples
NOTE: This example doesn't really save a lot. Imagine ten properties with only one excluded from memberwise initialization.
```swift
struct S {
let s: String
let i: Int
// user declares:
@nomemberwise(i)
memberwise init(...) {
i = getTheValueForI()
}
// compiler synthesizes (suppressing memberwise initialization for properties mentioned in the @nomemberwise attribute):
init(s: String) {
/* synthesized */ self.s = s
// body of the user's initializer remains
i = getTheValueForI()
}
}
```
```swift
struct S {
let s: String
@nomemberwise let i: Int
// user declares:
memberwise init() {
i = 42
}
// compiler synthesizes:
init(s: String) {
/* synthesized */ self.s = s
// body of the user's initializer remains
i = 42
}
}
```
### Memberwise initializer chaining / parameter forwarding
Ideally it would be possible to define convenience and delegating initializers without requiring them to manually declare parameters and pass arguments to the designated initializer for memberwise initialized properties. It would also be ideal if designated initializers also did not have to the same for memberwise initialization parameters of super.
A general solution for parameter forwarding would solve this problem. A future parameter forwarding proposal to support this use case and others is likely to be pursued.
### Objective-C Class Import
Objective-C frameworks are extremely important to (most) Swift developers. In order to provide the call-site advantages of flexible memberwise initialization to Swift code using Cocoa frameworks a future proposal could recommend introducing a `MEMBERWISE` attribute that can be applied to Objective-C properties and initializers.
Mutable Objective-C properties could be marked with the `MEMBERWISE` attribute. Readonly Objective-C properties **could not** be marked with the `MEMBERWISE` attribute. The `MEMBERWISE` attribute should only be used for properties that are initialized with a default value (not a value provided directly by the caller or computed in some way) in **all** of the class's initializers.
Objective-C initializers could also be marked with the `MEMBERWISE` attribute. When Swift imports an Objective-C initializer marked with this attribute it could allow callers to provide memberwise values for the properties declared in the class that are marked with the `MEMBERWISE` attribute. At call sites for these initializers the compiler could perform a transformation that results in the memberwise properties being set with the provided value immediately after initialization of the instance completes.
It may also be desirable to allow specific initializers to hide the memberwise parameter for specific properties if necessary. `NOMEMBERWISE(prop1, prop2)`
It is important to observe that the mechanism for performing memberwise initialization of Objective-C classes (post-initialization setter calls) must be implemented in a different way than native Swift memberwise initialization. As long as developers are careful in how they annotate Objective-C types this implementation difference should not result in any observable differences to callers.
The difference in implementation is necessary if we wish to use call-site memberwise initialization syntax in Swift when initializing instances of Cocoa classes. There have been several threads with ideas for better syntax for initializing members of Cocoa class instances. I believe memberwise initialization is the *best* way to do this as it allows full configuration of the instance in the initializer call.
Obviously supporting memberwise initialization with Cocoa classes would require Apple to add the `MEMBERWISE` attribute where appropriate. A proposal for the Objective-C class import provision is of significantly less value if this did not happen. My recommendation is that an Objective-C import proposal should be drafted and submitted if this proposal is submitted, but not until the core team is confident that Apple will add the necessary annotations to their frameworks.
## Alternatives considered
### Require stored properties to opt-in to memberwise initialization
This is a reasonable option and and I expect a healthy debate about which default is better. The decision to adopt the *automatic* model by default was made for several reasons:
1. The memberwise initializer for structs does not currently require an annotation for properties to opt-in. Requiring an annotation for a mechanism designed to supersede that mechanism may be viewed as boilerplate.
2. Stored properties with public visibility are often initialized directly with a value provided by the caller.
3. Stored properties with **less visibility** than a memberwise initializer are not eligible for memberwise initialization. No annotation is required to indicate that and it is usually not desired.
4. The *automatic* model cannot exist unless it is the default. The *opt-in* model can exist alongside the *automatic* model and itself be opted-into simply by specifying the `memberwise` declaration modifier on one or more properties.
I do think a strong argument can be made that it may be **more clear** to require a `memberwise` declaration modifier on stored properties in order to *opt-in* to memberwise initialization.
### Allow all initializers to participate in memberwise initialization
This option was not seriously considered. It would impact existing code and it would provide no indication in the declaration of the initializer that the compiler will synthesize additional parameters and perform additional initialization of stored properties in the body of the initializer.
### Require initializers to opt-out of memberwise initialization
This option was also not seriously considered. It has the same problems as allowing all initializers to participate in memberwise initialization.
### Allow parameters to be synthesized for properties with a lower access level than the initializer
I considered allowing parameters to be synthesized for properties that are not directly visible to callers of the initializer. There is no direct conflict with the access modifier and it is possible to write such code manually. I decided against this approach because as it is unlikely to be the right approach most of the time. In cases where it is the right approach I think it is a good thing to require developers to write this code manually.
Reasons to limit memberwise parameter synthesis to members which are *at least* as visible as the initializer include:
1. Makes logical sense at first blush. Memberwise inits publishing private state would be odd/surprising.
2. Safer default, in that you don’t accidentally publish stuff you don’t want through a memberwise init.
3. It is likely the more common desire of the author of an initializer. If the caller can’t see a member it probably doesn’t make sense to allow them to initialize it.
4. If we expose more private-members by default then memberwise initialization is useless under the current proposal in many cases. There would be no way to prevent synthesis of parameters for more-private members. We have to choose between allowing callers to initialize our internal state or forgoing the benefit of memberwise initialization.
5. If a proposal for `@nomemberwise` is put forward and adopted that would allow us to prevent synthesis of parameters for members as desired. Unfortunately `@nomemberwise` would need to be used much more heavily than it otherwise would (i.e. to prevent synthesis of memberwise parameters for more-private members). It would be better if `@nomemberwise` was not necessary most of the time.
6. If callers must be able to provide memberwise arguments for more-private members directly it is still possible to allow that while taking advantage of memberwise initialization for same-or-less-private members. You just need to declare a `memberwise init` with explicitly declared parameters for the more-private members and initialize them manually in the body. If the "Access control for init" enhancement is accepted another option would be upgrading the visibility of `init` for the more-private member while retaining its access level for the getter and setter. Requiring the programmer to explicitly expose a more-private member either via `init` access control or by writing code that it directly is arguably a very good thing.
Reasons we might want to allow memberwise parameter synthesis for members with lower visibility than the initializer:
1. Not doing so puts tension between access control for stored properties and memberwise inits. You have to choose between narrower access control or getting the benefit of a memberwise init. Another way to say it: this design means that narrow access control leads to boilerplate.
NOTE: The tension mentioned here is lessened by #6 above: memberwise initialization can still be used for same-or-less-private members and the requirement to explicitly expose more-private members to more-public initializers one way or another is arguably a good thing.
### Require initializers to explicitly specify memberwise initialization parameters
The thread "[helpers for initializing properties of the same name as parameters](https://forums.swift.org/t/proposal-helpers-for-initializing-properties-of-same-name-as-parameters/129/3)" discussed an idea for synthesizing property initialization in the body of the initializer while requiring the parameters to be declared explicitly.
```swift
struct Foo {
let bar: String
let bas: Int
let baz: Double
init(self.bar: String, self.bas: Int, bax: Int) {
// self.bar = bar synthesized by the compiler
// self.bas = bas synthesized by the compiler
self.baz = Double(bax)
}
}
```
The downside of this approach is that it does not address the M x N scaling issue mentioned in the motivation section. The manual initialization statements are elided, but the boilerplate parameter declarations still grow at the rate MxN (properties x initializers). It also does not address forwarding of memberwise initialization parameters which makes it useless for convenience and delegating initializers.
Proponents of this approach believe it provides additional clarity and control over the current proposal.
Under the current proposal full control is still available. It requires initializers to opt-in to memberwise initialization. When full control is necessary an initializer will simply not opt-in to memberwise initialization synthesis. The boilerplate saved in the examples on the list is relatively minimal and is tolerable in situations where full control of initialization is required.
I believe the `memberwise` declaration modifier on the initializer and the placeholder in the parameter list make it clear that the compiler will synthesize additional parameters. Furthermore, IDEs and generated documentation will contain the full, synthesized signature of the initializer.
Finally, this idea is not mutually exclusive with the current proposal. It could even work in the declaration of a memberwise initializer, so long the corresponding property was made ineligible for memberwise initialization synthesis.
### Adopt "type parameter list" syntax like Kotlin and Scala
Several commenters in the mailing list thread have suggested using syntax like Kotlin and Scala that looks like this:
```swift
struct Rect(var origin: Point = Point(), var size: Size = Size()) {}
```
Which would expand to:
```swift
struct Rect {}
// Whether the initial value is included here or not is unclear.
// Mailing list suggestions have not included it.
var origin: Point // = Point()
var size: Size // = Size()
init(origin: Point = Point(), size: Size = Size()) {
self.origin = origin
self.size = size
}
```
This approach was not chosen because it is not compatible with the goal of this proposal to provide a flexible and scalable solution for memberwise initialization. Specific reasons include:
1. This proposal supports partial memberwise initialization.
Initializers can receive non-memberwise parameters and can initialize private state manually while still exposing public properties for direct initialization by callers via memberwise initialization.
2. This proposal supports multiple memberwise initializers.
It may be necessary to support more than one way to initialize private state while still desiring direct initialization of public properties via memberwise initialization.
3. This proposal supports more flexibility for organizing property declarations.
The Scala / Kotlin syntax may be acceptable in really simple cases. Unfortunately it requires placing property declarations in a single list at the beginning of the type declaration. This is extremely limiting.
It is especially unfortunatey for types which contain generic parameters and inheritance clauses. Property declarations would be sandwiched in between those two clauses cluttering up type-level information with member-level information
This proposal is not mutually exclusive with supporting the "type parameter list" syntax. They are aimed at solving different problems and could live side-by-side. A future proposal could introduce similar syntax. One option for such a proposal would be to provide a simple expansion into property declarations, allowing the current proposal to drive synthesis of the initializer (assuming the default parameter values for `let` properties problem is solved by that time).
In fairness I would like to repeat the advantages of the Scala / Kotlin syntax that have been mentioned:
1. It might support default values for parameters corresponding to `let` properties.
2. It could allow parameter labels to be specified.
3. It is more concise than the current proposal in some cases.
Responses to these points follow:
1. If the expansion of this syntax does not supply initial values to the synthesized properties and only uses the default value for parameters of the synthesized initializer this is true. The downside of doing this is that `var` properties no longer have an initial value which may be desirable if you write additional initializers for the type.
I believe we should continue the discussion about default values for `let` properties. Ideally we can find an acceptable solution that will work with the current proposal, as well as any additional syntactic sugar we add in the future.
2. I don't believe allowing parameter labels for memberwise initialization parameters is a good idea. Callers are directly initializing a property and are best served by a label that matches the name of the property. If you really need to provide a different name you can still do so by writing your initializer manually. With future enhancements to the current proposal you may be able to use memberwise initialization for properties that do not require a custom label while manually initializing properties that do need one.
3. The Scala / Kotlin syntax is indeed more concise in some cases, but not in all cases. Under this proposal the example given above is actually more concise than it is with that syntax:
```swift
struct Rect { var origin: Point = Point(), size: Size = Size() }
```
vs
```swift
struct Rect(var origin: Point = Point(), var size: Size = Size()) {}
```
================================================
FILE: proposals/0019-package-manager-testing.md
================================================
# Swift Testing
* Proposal: [SE-0019](0019-package-manager-testing.md)
* Authors: [Max Howell](https://github.com/mxcl), [Daniel Dunbar](https://github.com/ddunbar), [Mattt Thompson](https://github.com/mattt)
* Review Manager: [Rick Ballard](https://github.com/rballard)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0019-swift-testing-package-manager/1155)
* Bug: [SR-592](https://bugs.swift.org/browse/SR-592)
## Introduction
Testing is an essential part of modern software development.
Tight integration of testing into the Swift Package Manager
will help ensure a stable and reliable packaging ecosystem.
[SE Review Link](https://forums.swift.org/t/review-se-0019-swift-testing-package-manager/909), [Second Review](https://forums.swift.org/t/review-se-0019-swift-testing-package-manager/1084)
## Proposed Solution
We propose to extend our conventional package directory layout
to accommodate test modules.
Any subdirectory of the package root directory named "Tests"
or any subdirectory of an existing module directory named "Tests"
will comprise a test module.
For example:
Package
├── Sources
│ └── Foo
│ └──Foo.swift
└── Tests
└── Foo
└── Test.swift
Or:
Package
└── Sources
├── Foo.swift
└── Tests
└── Test.swift
Or, for projects with a single module:
Package
├── Sources
│ └── Foo.swift
└── Tests
└── TestFoo.swift
The filename: `TestFoo.swift` is arbitrary.
In the examples above
a test case is created for the module `Foo`
based on the sources in the relevant subdirectories.
A test-module is created per subdirectory of Tests, so:
Package
├── Sources
│ └── Foo
│ └──Foo.swift
└── Tests
└── Foo
└── Test.swift
└── Bar
└── Test.swift
Would create two test-modules. The modules in this example may
test different aspects of the module Foo, it is entirely up
to the package author.
Additionally, we propose that building a module
also builds that module's corresponding tests.
Although this would result in slightly increased build times,
we believe that tests are important enough to justify this
(one might even consider slow building tests to be a code smell).
We would prefer to go even further by executing the tests
each time a module is built as well,
but we understand that this would impede debug cycles.
As an exception, when packages are built in release mode we will
not build tests because for release builds we should not enable
testability. However, considering the need for release-mode testing
this will be a future direction.
This feature is controversial; many are worried always building
tests will slow debug cycles. We understand these concerns but
think knowing quickly tests have been broken by code changes is
important. However we will provide an command line option to not
build tests and will be open to reversing this decision in future
should it be proven unwise.
### Command-Line Interface
We propose the following syntax to execute all tests (though not the tests
of any dependent packages):
$ swift test
The command line should accept the names of specific test cases to run:
swift test TestModule.FooTestCase
Or specific tests:
swift test TestModule.FooTestCase.test1
In the future we would like to support running specific kinds of tests:
swift test --kind=performance
`swift test` would forward any other arguments to the underlying testing framework and it
would decide how to interpret them.
---
Sometimes test sources cannot compile and fixing them is not the most
pressing priority. Thus it will be possible to skip building tests
with an additional flag:
swift build --without-tests
---
It is desirable to sometimes specify to only build specific tests, the
command line for this will fall out of future work that allows specification
of targets that `swift build` should specifically build in isolation.
---
Users should be able to run the tests of all their dependencies.
This is not the default behavior, but a flag will be provided.
### Command Output
Executing a test from the terminal will produce user-readable output.
This should incorporate colorization and other formatting
similar to other testing tools
to indicate the success and failure of different tests.
For example:
$ swift test --output module
Running tests for PackageX (x/100)
.........x.....x...................
Completed
Elapsed time: 0.2s
98 Success
2 Failure
1 Warning
FAILURE: Tests/TestsA.swift:24 testFoo()
XCTAssertTrue expected true, got false
FAILURE: Tests/TestsB.swift:10 testBar()
XCTAssertEqual
WARNING: Tests/TestsC.swift:1
"Some Warning"
An additional option may be passed to the testing command
to output JUnit-style XML or other formats that can be integrated
with continuous integration (CI) and other systems.
Running `swift test` will firstly trigger a build. We feel this
is the most expected result considering tests must be built before
they can be run and almost all other tools build before running
tests. However we will provide a flag to not build first.
### Test-only Dependencies
There is already a mechanism to specify test-only dependencies.
It is very basic, but a new proposal should be made for more
advanced `Package.swift` functionality.
This proposal also does not cover the need for utility code, ie.
a module that is built for tests to consume that is provided as
part of a package and is not desired to be an external package.
This is something we would like to add as part of a future proposal.
### Test-target configuration
This proposal does not allow a test-module to have module dependencies
from its own package, and thus there is no provided mechanism to
specify or configure tests in the `Package.swift` file.
This will be added, but as part of a broader proposal for the future
of the `Package.swift` file.
### Automatic Dependency Determination
Testing is important and it is important to make the barrier to testing
as minimal as possible. Thus, by analyzing the names of test targets,
we will automatically determine the most likely dependency of that test
and accommodate accordingly.
For example,
a test for "Foo" will depend on compilation of the library target `Foo`.
Any additional dependencies or dependencies that could not be automatically determined
would need to be specified in a package manifest separately.
### Debug / Release Configuration
Although tests built in debug configuration
are generally run against modules also build in debug configuration,
it is sometimes necessary to specify the build configuration for tests separately.
It is also sometimes necessary to explicitly specify this information for every build,
such as when building in a release configuration to execute performance tests.
We would like to eventually support these use cases,
however this will not be present in the initial implementation of this feature.
### Testability
Swift can build modules with "testability",
which allows tests to access entities with `internal` access control.
Because it would be tedious for users to specify this requirement for tests,
we intend to build debug builds with testability by default.
It is desirable that modules that are built for testing can identify this
fact in their sources. Thus at a future time we will provide a define.
### Test Frameworks
Initially,
the Swift Package Manager will use `XCTest` as its underlying test framework.
However, testing is an evolving art form,
so we'd like to support other approaches
that might allow frameworks other than XCTest
to be supported by the package manager.
We expect that such an implementation would take the form of
a Swift protocol that the package manager defines,
which other testing frameworks can adopt.
## Impact On Existing Code
Current releases of the package manager already exclude directories named
"Tests" from target-determination. Directories named `FooTests` are not
excluded, but as it stands this is a cause of compile failure, so in fact
these changes will positively impact existing code.
## Alternatives Considered
We considered supporting the following layout:
Package
└── Sources
│ └── Foo.swift
└── FooTests
└── Test.swift
This was considered because of the vast number of existing
Xcode projects out there that are laid out in the fashion.
However it was decided that the rules for these layouts are
inconsistent with our existing simple set. When users experience
unexpected consequences of layouts with our convention approach
it can be confusing and tricky to diagnose, so we should instead
submit another proposal in the future that allows easy
configuration of targets in `Package.swift`.
---
We considered decoupling testing from SwiftPM altogether.
However, since tests must be built and dependencies of tests
must be managed complete decoupling is not possible. The coupling
will be minimal, with a separate library and executable for tests,
this is about as far as we think it is prudent to go.
---
We considered not baking in support for XCTest and only having
a protocol for testing.
We would like to get testing up to speed as soon as possible.
Using XCTest allows this to occur. We also think there is value
in packages being able to depend on a testing framework being
provided by the Swift system.
However nothing stops us eventually making the support for XCTest
work via our protocol system.
================================================
FILE: proposals/0020-if-swift-version.md
================================================
# Swift Language Version Build Configuration
* Proposal: [SE-0020](0020-if-swift-version.md)
* Author: [Ashley Garland](https://github.com/bitjammer)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Implemented (Swift 2.2)**
* Implementation: [apple/swift@c32fb8e](https://github.com/apple/swift/commit/c32fb8e7b9a67907e8b6580a46717c6a345ec7c6)
## Introduction
This proposal aims to add a new build configuration option to Swift
2.2: `#if swift`.
Swift-evolution threads:
- [Swift 2.2: #if swift language version](https://forums.swift.org/t/proposal-swift-2-2-if-swift-language-version/640)
- [Review](https://forums.swift.org/t/review-se-0020-swift-language-version-build-configuration/1034)
## Motivation
Over time, Swift syntax may change but library and package authors will
want their code to work with multiple versions of the language. Up until
now, the only recourse developers have is to maintain separate release
branches that follow the language. This gives developers another tool to
track syntax changes without having to maintain separate source trees.
We also want to ease the transition between language revisions for
package authors that distribute their source code, so clients can build
their package with older or newer Swift.
## Proposed solution
The solution is best illustrated with a simple example:
```swift
#if swift(>=2.2)
print("Active!")
#else
this! code! will! not! parse! or! produce! diagnostics!
#endif
```
## Detailed design
This will use existing version mechanics already present in the
compiler. The version of the language is baked into the compiler when
it's built, so we know how to determine whether a block of code is
active. If the version is at least as recent as specified in the
condition, the active branch is parsed and compiled into your code.
Like other build configurations, `#if swift` isn't line-based - it
encloses whole statements or declarations. However, unlike the others,
the compiler won't parse inactive branches guarded by `#if swift` or
emit lex diagnostics, so syntactic differences for other Swift versions
can be in the same file.
For now, we'll only expect up to two version components, since it will
be unlikely that a syntax change will make it in a +0.0.1 revision.
The argument to the configuration function is a unary prefix expression,
with one expected operator, `>=`, for simplicity. If the need arises,
this can be expanded to include other comparison operators.
## Impact on existing code
This mechanism is opt-in, so existing code won't be affected by this
change.
## Alternatives considered
We considered two other formats for the version argument:
- String literals (`#if swift("2.2")`): this allows us to embed an
arbitrary number of version components, but syntax changes are
unlikely in micro-revisions. If we need another version component, the
parser change won't be severe.
- Just plain `#if swift(2.2)`: Although `>=` is a sensible default, it
isn't clear what the comparison is here, and might be assumed to be
`==`.
- Argument lists (`#if swift(2, 2)`: This parses flexibly but can
indicate that the second `2` might be an argument with a different
meaning, instead of a component of the whole version.
================================================
FILE: proposals/0021-generalized-naming.md
================================================
# Naming Functions with Argument Labels
* Proposal: [SE-0021](0021-generalized-naming.md)
* Author: [Doug Gregor](https://github.com/DougGregor)
* Review Manager: [Joe Groff](https://github.com/jckarter)
* Status: **Implemented (Swift 2.2)**
* Decision Notes: [Rationale](https://forums.swift.org/t/review-naming-functions-with-argument-labels/1046/11)
* Implementation: [apple/swift@ecfde0e](https://github.com/apple/swift/commit/ecfde0e71c61184989fde0f93f8d6b7f5375b99a)
## Introduction
Swift includes support for first-class functions, such that any
function (or method) can be placed into a value of function
type. However, when specifying the name of a function, one can only provide the base name, (e.g., `insertSubview`) without the argument labels. For overloaded functions, this means that one must disambiguate based on type information, which is awkward and verbose. This proposal allows one to provide argument labels when referencing a function, eliminating the need to provide type context in most cases.
Swift-evolution thread: The first draft of this proposal was discussed [here](https://forums.swift.org/t/proposal-draft-generalized-naming-for-any-function/787). It included support for naming getters/setters (separately brought up by Michael Henson
[here](https://forums.swift.org/t/proposal-expose-getter-setters-in-the-same-way-as-regular-methods/501),
continued
[here](https://forums.swift.org/t/proposal-expose-getter-setters-in-the-same-way-as-regular-methods/501/5)). Joe Groff [convinced](https://forums.swift.org/t/proposal-draft-generalized-naming-for-any-function/787/4) me that lenses are a better approach for working with getters/setters, so I've dropped them from this version of the proposal.
## Motivation
It's fairly common in Swift for multiple functions or methods to have
the same "base name", but be distinguished by parameter labels. For
example, `UIView` has three methods with the same base name `insertSubview`:
```swift
extension UIView {
func insertSubview(view: UIView, at index: Int)
func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
}
```
When calling these methods, the argument labels distinguish the
different methods, e.g.,
```swift
someView.insertSubview(view, at: 3)
someView.insertSubview(view, aboveSubview: otherView)
someView.insertSubview(view, belowSubview: otherView)
```
However, when referencing the function to create a function value, one
cannot provide the labels:
```swift
let fn = someView.insertSubview // ambiguous: could be any of the three methods
```
In some cases, it is possible to use type annotations to disambiguate:
```swift
let fn: (UIView, Int) = someView.insertSubview // ok: uses insertSubview(_:at:)
let fn: (UIView, UIView) = someView.insertSubview // error: still ambiguous!
```
To resolve the latter case, one must fall back to creating a closure:
```swift
let fn: (UIView, UIView) = { view, otherView in
button.insertSubview(view, aboveSubview: otherView)
}
```
which is painfully tedious.
One additional bit of motivation: Swift should probably get some way
to ask for the Objective-C selector for a given method (rather than
writing a string literal). The argument to such an operation would
likely be a reference to a method, which would benefit from being able
to name any method, including getters and setters.
## Proposed solution
I propose to extend function naming to allow compound Swift names
(e.g., `insertSubview(_:aboveSubview:)`) anywhere a name can
occur. Specifically,
```swift
let fn = someView.insertSubview(_:at:)
let fn1 = someView.insertSubview(_:aboveSubview:)
```
The same syntax can also refer to initializers, e.g.,
```swift
let buttonFactory = UIButton.init(type:)
```
The "produce the Objective-C selector for the given method" operation
will be the subject of a separate proposal. However, here is one
possibility that illustrations how it uses the proposed syntax here:
```swift
let getter = Selector(NSDictionary.insertSubview(_:aboveSubview:)) // produces insertSubview:aboveSubview:.
```
## Detailed Design
Grammatically, the *primary-expression* grammar will change from:
primary-expression -> identifier generic-argument-clause[opt]
to:
primary-expression -> unqualified-name generic-argument-clause[opt]
unqualified-name -> identifier
| identifier '(' ((identifier | '_') ':')+ ')'
Within the parentheses, the use of "+" is important, because it disambiguates:
```swift
f()
```
as a call to `f` rather than a reference to an `f` with no
arguments. Zero-argument function references will still require
disambiguation via contextual type information.
Note that the reference to the name must include all of the arguments
present in the declaration; arguments for defaulted or variadic
parameters cannot be skipped. For example:
```swift
func foo(x x: Int, y: Int = 7, strings: String...) { ... }
let fn1 = foo(x:y:strings:) // okay
let fn2 = foo(x:) // error: no function named 'foo(x:)'
```
## Impact on existing code
This is a purely additive feature that has no impact on existing
code.
## Alternatives considered
* Joe Groff
[notes](https://forums.swift.org/t/proposal-expose-getter-setters-in-the-same-way-as-regular-methods/501/3)
that *lenses* are a better solution than manually
retrieving getter/setter functions when the intent is to actually
operate on the properties.
* Bartlomiej Cichosz [suggests](https://forums.swift.org/t/proposal-draft-generalized-naming-for-any-function/787/6) a general partial application syntax using `_` as a placeholder, e.g.,
```swift
aGameView.insertSubview(_, aboveSubview: playingSurfaceView)
```
When all arguments are `_`, this provides the ability to name any method:
```swift
aGameView.insertSubview(_, aboveSubview: _)
```
I decided not to go with this because I don't believe we need such a
general partial application syntax in Swift. Closures using the $
names are nearly as concise, and eliminate any questions about how
the `_` placeholder maps to an argument of the partially-applied
function:
```swift
{ aGameView.insertSubview($0, aboveSubview: playingSurfaceView) }
```
* We could elide the underscores in the names, e.g.,
```swift
let fn1 = someView.insertSubview(:aboveSubview:)
```
However, this makes it much harder to visually distinguish methods
with no first argument label from methods with a first argument
label, e.g., `f(x:)` vs. `f(:x:)`. Additionally, empty argument
labels in function names are written using the underscores
everywhere else in the system (e.g., the Clang `swift_name`
attribute), and we should maintain consistency.
================================================
FILE: proposals/0022-objc-selectors.md
================================================
# Referencing the Objective-C selector of a method
* Proposal: [SE-0022](0022-objc-selectors.md)
* Author: [Doug Gregor](https://github.com/DougGregor)
* Review Manager: [Joe Groff](https://github.com/jckarter)
* Status: **Implemented (Swift 2.2)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0022-referencing-the-objective-c-selector-of-a-method/1194)
* Implementation: [apple/swift#1170](https://github.com/apple/swift/pull/1170)
## Introduction
In Swift 2, Objective-C selectors are written as string literals
(e.g., `"insertSubview:aboveSubview:"`) in the type context of a
`Selector`. This proposal seeks to replace this error-prone approach
with `Selector` initialization syntax that refers to a specific method
via its Swift name.
Swift-evolution thread: [here](https://forums.swift.org/t/proposal-draft-referencing-the-objective-c-selector-of-a-method/1022), [Review](https://forums.swift.org/t/review-se-0022-referencing-the-objective-c-selector-of-a-method/1118), [Amendments after acceptance](https://forums.swift.org/t/amendment-se-0022-referencing-the-objective-c-selector-of-a-method/2737)
## Motivation
The use of string literals for selector names is extremely
error-prone: there is no checking that the string is even a
well-formed selector, much less that it refers to any known method, or
a method of the intended class. Moreover, with the effort to perform
[automatic renaming of Objective-C
APIs](0005-objective-c-name-translation.md),
the link between Swift name and Objective-C selector is
non-obvious. By providing explicit "create a selector" syntax based on
the Swift name of a method, we eliminate the need for developers to
reason about the actual Objective-C selectors being used.
## Proposed solution
Introduce a new expression `#selector` that allows one to build a selector from a reference to a method, e.g.,
```swift
control.sendAction(#selector(MyApplication.doSomething), to: target, forEvent: event)
```
where “doSomething” is a method of MyApplication, which might even have a completely-unrelated name in Objective-C:
```swift
extension MyApplication {
@objc(jumpUpAndDown:)
func doSomething(sender: AnyObject?) { … }
}
```
By naming the Swift method and having the `#selector` expression do
the work to form the Objective-C selector, we free the developer from
having to do the naming translation manually and get static checking
that the method exists and is exposed to Objective-C.
This proposal composes with the [Naming Functions with Argument Labels
proposal](https://forums.swift.org/t/proposal-draft-2-naming-functions-with-argument-labels/1018), which lets us name methods along with their argument labels, e.g.:
let sel = #selector(UIView.insertSubview(_:atIndex:)) // produces the Selector "insertSubview:atIndex:"
With the introduction of the `#selector` syntax, we should deprecate
the use of string literals to form selectors. Ideally, we could
perform the deprecation in Swift 2.2 and remove the syntax entirely
from Swift 3.
Additionally, we should introduce specific migrator support to
translate string-literals-as-selectors into method references. Doing
this well is non-trivial, requiring the compiler/migrator to find all
of the declarations with a particular Objective-C selector and
determine which one to reference. However, it should be feasible, and
we can migrate other references to a specific, string-based
initialization syntax (e.g., `Selector("insertSubview:atIndex:")`).
## Detailed design
The subexpression of the `#selector` expression must be a reference to an `objc` method. Specifically, the input expression must be a direct reference to an Objective-C method, possibly parenthesized and possibly with an "as" cast (which can be used to disambiguate same-named Swift methods). For example, here is a "highly general" example:
```swift
let sel = #selector(((UIView.insertSubview(_:at:)) as (UIView) -> (UIView, Int) -> Void))
```
The expression inside `#selector` is limited to be a series of instance
or class members separated by `.` where the last component may be
disambiguated using `as`. In particular, this prohibits performing
method calls inside `#selector`, clarifying that the subexpression of
`#selector` will not be evaluated and no side effects occur because of it.
The complete grammar of `#selector` is:
selector → #selector(selector-path)
selector-path → type-identifier . selector-member-path as-disambiguationopt
selector-path → selector-member-path as-disambiguationopt
selector-member-path → identifier
selector-member-path → unqualified-name
selector-member-path → identifier . selector-member-path
as-disambiguation → as type-identifier
## Impact on existing code
The introduction of the `#selector` expression has no
impact on existing code. However, deprecating and removing the
string-literal-as-selector syntax is a source-breaking
change. We can migrate the uses to either the new `#selector`
expression or to explicit initialization of a `Selector`
from a string.
## Alternatives considered
The primary alternative is [type-safe
selectors](https://forums.swift.org/t/type-safe-selectors/108),
which would introduce a new "selector" calling convention to capture
the type of an `@objc` method, including its selector. One major
benefit of type-safe selectors is that they can carry type
information, improving type safety. From that discussion, referencing
`MyClass.observeNotification` would produce a value of type:
```swift
@convention(selector) (MyClass) -> (NSNotification) -> Void
```
Objective-C APIs that accept selectors could provide type information
(e.g., via Objective-C attributes or new syntax for a typed `SEL`),
improving type safety for selector-based APIs. Personally, I feel that
type-safe selectors are a well-designed feature that isn't worth
doing: one would probably not use them outside of interoperability
with existing Objective-C APIs, because closures are generally
preferable (in both Swift and Objective-C). The cost of adding this
feature to both Swift and Clang is significant, and we would also need
adoption across a significant number of Objective-C APIs to make it
worthwhile. On iOS, we are talking about a relatively small number of
APIs (100-ish), and many of those have blocks/closure-based variants
that are preferred anyway. Therefore, we should implement the simpler
feature in this proposal rather than the far more complicated (but
admittedly more type-safe) alternative approach.
Syntactically, `@selector(method reference)` would match Objective-C
more closely, but it doesn't make sense in Swift where `@` always
refers to attributes.
The original version of this proposal suggested using a magic
`Selector` initializer, e.g.:
```swift
let sel = Selector(((UIView.insertSubview(_:at:)) as (UIView) -> (UIView, Int) -
```
However, concerns over this being magic syntax that looks like
instance construction (but is not actually representable in Swift as
an initializer), along with existing uses of `#` to denote special
expressions (e.g., `#available`), caused the change to the `#selector`
syntax at the completion of the public review.
## Revision history
- 2016-05-20: The proposal was amended post-acceptance to limit the
syntax inside the subexpression of `#selector`, in particular disallowing
methods calls. Originally any valid Swift expression was supported.
================================================
FILE: proposals/0023-api-guidelines.md
================================================
# API Design Guidelines
* Proposal: [SE-0023](0023-api-guidelines.md)
* Authors: [Dave Abrahams](https://github.com/dabrahams), [Doug Gregor](https://github.com/DougGregor), [Dmitri Gribenko](https://github.com/gribozavr), [Ted Kremenek](https://github.com/tkremenek), [Chris Lattner](https://github.com/lattner), Alex Migicovsky, [Max Moiseev](https://github.com/moiseev), Ali Ozer, [Tony Parker](https://github.com/parkera)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-with-modifications-se-0023-api-design-guidelines/1666)
## Reviewer notes
This review is part of a group of three related reviews, running
concurrently:
* [SE-0023 API Design Guidelines](0023-api-guidelines.md)
([Review](https://forums.swift.org/t/review-se-0023-api-design-guidelines/1162))
* [SE-0006 Apply API Guidelines to the Standard Library](0006-apply-api-guidelines-to-the-standard-library.md)
([Review](https://forums.swift.org/t/review-se-0006-apply-api-guidelines-to-the-standard-library/1163))
* [SE-0005 Better Translation of Objective-C APIs Into Swift](0005-objective-c-name-translation.md)
([Review](https://forums.swift.org/t/review-se-0005-better-translation-of-objective-c-apis-into-swift/1164))
These reviews are running concurrently because they interact strongly
(e.g., an API change in the standard library will correspond to a
particular guideline, or an importer rule implements a particular
guideline, etc.). Because of these interactions, and to keep
discussion manageable, we ask that you:
* **Please get a basic understanding of all three documents** before
posting review commentary
* **Please post your review of each individual document in response to
its review announcement**. It's okay (and encouraged) to make
cross-references between the documents in your review where it helps
you make a point.
## Introduction
The design of commonly-used libraries has a large impact on the
overall feel of a programming language. Great libraries feel like an
extension of the language itself, and consistency across libraries
elevates the overall development experience. To aid in the
construction of great Swift libraries, one of the major goals for
Swift 3 is to define a set of API design guidelines and to apply those
design guidelines consistently.
## Proposed solution
The proposed API Design Guidelines are available at
[https://swift.org/documentation/api-design-guidelines/](https://swift.org/documentation/api-design-guidelines/).
The sources for these guidelines are available at
https://github.com/apple/swift-internals. Pull requests for trivial
copyediting changes are most welcome. More substantive changes should
be handled as part of the review process.
## Impact on existing code
The existence of API Design Guidelines has no specific impact on
existing code. However, two companion proposals that apply these
guidelines to the [Standard
Library](0006-apply-api-guidelines-to-the-standard-library.md) and via
the [Clang importer](0005-objective-c-name-translation.md) will have a
massive impact on existing code, changing a significant number of
APIs.
================================================
FILE: proposals/0024-optional-value-setter.md
================================================
# Optional Value Setter `??=`
* Proposal: [SE-0024](0024-optional-value-setter.md)
* Author: [James Campbell](https://github.com/jcampbell05)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Rejected**
* Decision Notes: [Rationale](https://forums.swift.org/t/rejected-se-0024-optional-value-setter/1528)
## Introduction
Introduce a new operator an "Optional Value Setter". If the optional is set via this operator then the new value is
only set if there isn't an already existing value.
Swift-evolution thread: [link to the discussion thread for that proposal](https://forums.swift.org/t/optional-setting/553)
## Motivation
In certain cases the `??` operation doesn't help with lengthy variable names, i.e., `really.long.lvalue[expression] = really.long.lvalue[expression] ?? ""`. In addtition to this other languages such as Ruby contain a pipe operator `really.long.lvalue[expression] ||= ""` which works the same way and which is very popular. This lowers the barrier of entry for programmers from that language.
In the interest in conciseness and clarity I feel this would be a great addition to swift and would bring the length of that previous statement from
```swift
really.long.lvalue[expression] = really.long.lvalue[expression] ?? ""
```
to
```swift
really.long.lvalue[expression] ??= ""
```
## Proposed solution
In this solution an optonals value wouldn't be set if it already contains a value (i.e .Some), ideally willSet and didSet are only called if this operation occurs.
```swift
var itemsA:[Item]? = nil
var itemsB:[Item]? = [Item()]
itemsA ??= [] // itemsA is set since its value is .None
itemsB ??= [] // itemsB's value isn't changed since its value is .Some
```
## Impact on existing code
Since this is a strictly additive and optional feature, it won't affect existing code and should make code more concise going forward.
## Alternatives considered
Other syntaxes included `?=` but we felt it didn't match the convention of the `??` in `a = a ?? ""`.
================================================
FILE: proposals/0025-scoped-access-level.md
================================================
# Scoped Access Level
* Proposal: [SE-0025](0025-scoped-access-level.md)
* Author: Ilya Belenkiy
* Status: **Implemented (Swift 3.0)**
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Decision Notes: [Rationale](https://forums.swift.org/t/se-0025-scoped-access-level-next-steps/1797/131)
* Bug: [SR-1275](https://bugs.swift.org/browse/SR-1275)
* Previous revision: [1](https://github.com/swiftlang/swift-evolution/blob/e4328889a9643100177aef19f6f428855c5d0cf2/proposals/0025-scoped-access-level.md)
## Introduction
Scoped access level allows hiding implementation details of a class or a class extension at the class/extension level, instead of a file. It is a concise expression of the intent that a particular part of a class or extension definition is there only to implement a public API for other classes or extensions and must not be used directly anywhere outside of the scope of the class or the extension.
[Swift Evolution Discussion](https://forums.swift.org/t/review-se-0025-scoped-access-level/1588), [Next Steps Discussion](https://forums.swift.org/t/se-0025-scoped-access-level-next-steps/1797)
## Motivation
Currently, the only reliable way to hide implementation details of a class is to put the code in a separate file and mark it as private. This is not ideal for the following reasons:
- It is not clear whether the implementation details are meant to be completely hidden or can be shared with some related code without the danger of misusing the APIs marked as private. If a file already has multiple classes, it is not clear if a particular API is meant to be hidden completely or can be shared with the other classes.
- It forces a one class per file structure, which is very limiting. Putting related APIs and/or related implementations in the same file helps ensure consistency and reduces the time to find a particular API or implementation. This does not mean that the classes in the same file need to share otherwise hidden APIs, but there is no way to express such sharability with the current access levels.
Another, less reliable, way is to prefix APIs that are meant to be hidden with a `_` or do something similar. That works, but it’s not enforced by the compiler, and those APIs show up in tools like code completion, so the programmer has to filter out the noise — although these tools could quite easily support hiding methods with the `_` prefix standard. Also, there is a greater danger of using private APIs if they do something similar to public APIs but are somehow more optimized (because they make additional assumptions about the internal state).
The existing solutions are in some ways similar to those for untyped collections. It is usually possible to give a collection a name that would imply the type of elements it holds (similar to using _ to indicate private), but it is not the same as specifying it explicitly. Just as with generics, the intent not to share the implementation details with any other class is much clearer with support from the language as opposed to relying on where the code is in the project. Also, with untyped collections, it is possible to add an element of a different type (deliberately or not). Generics make that impossible, and it’s enforced by the compiler. Similarly, a dedicated access level modifier could enforce hiding implementation details at the compiler level and make it impossible to accidentally misuse or (deliberately use) implementation details in a context that the class meant not to share.
## Proposed solution
Add another access level modifier that is meant to express that the API is visible only within the scope in which it is defined. Properties, functions, and nested types marked this way would be completely hidden outside the class or class extension definition.
After the first review, the core team decided that it would be best to use `private` for this access level and rename other access level modifiers for consistency. The most popular set of names is:
- public: symbol visible outside the current module
- internal: symbol visible within the current module
- fileprivate: symbol visible within the current file
- private: symbol visible within the current declaration
(names proposed by Chris Lattner as an adjustment from names proposed by James Berry)
## Detailed design
When a function, variable, constant, subscript, or initializer is defined with `private` access modifier, it is visible only within that lexical scope. For example:
```swift
class A {
private var counter = 0
// public API that hides the internal state
func incrementCount() { ++counter }
// hidden API, not visible outside of this lexical scope
private func advanceCount(dx: Int) { counter += dx }
// incrementTwice() is not visible here
}
extension A {
// counter is not visible here
// advanceCount() is not visible here
// may be useful only to implement some other methods of the extension
// hidden from anywhere else, so incrementTwice() doesn’t show up in
// code completion outside of this extension
private func incrementTwice() {
incrementCount()
incrementCount()
}
}
```
### Complications with private types
When a type is defined with the `private` access modifier, things become a little more complicated. Of course the type itself is visible only within the lexical scope it is defined in, but what about members of the type?
```swift
class Outer {
private class Inner {
var value = 0
}
func test() {
// Can Outer.test reference Inner's initializer?
let inner = Inner()
// Can Outer.test reference Inner's 'value' property?
print(inner.value)
}
}
```
If the members of a private type are themselves considered `private`, it is very clear that they cannot be used outside of the type itself. However, it is also not currently permitted for a member to have an access level greater than its enclosing type. This restriction produces a conundrum: the type can be referenced within its enclosing lexical scope, but none of its members can.
Ignoring formal concerns, the most likely expected behavior is that members not explicitly marked `private` are permitted to be accessed within the enclosing scope of the private type. To achieve this goal, we relax a few of the existing rules:
- The default level of access control anywhere is `internal`.
- The compiler should not warn when a broader level of access control is used within a type with more restrictive access, such as `internal` within a `private` type. This allows the designer of the type to select the access they would use were they to make the type more widely accessible. (The members still cannot be accessed outside the enclosing lexical scope because the type itself is still restricted, i.e. outside code will never encounter a value of that type.)
- The type of a member can reference only declarations that are accessible wherever the member is accessible. (This relaxes an existing rule that states that the type of a declaration may not reference any declarations that have broader access.) The change permits the following code:
```swift
struct Outer {
private typealias Value = Int
private struct Inner {
var value: Value
}
}
```
and continues to treat this code as illegal:
```swift
struct Outer {
private struct Inner {
private typealias Value = Int
var value: Value
}
}
```
- A member that satisfies a protocol requirement may never be `private`. Similarly, a `required` initializer may never be `private`.
- As before, an extension with an explicit access modifier overrides the default `internal` access by specifying a default *scope*. Therefore, within an extension marked `private`, the default access level is `fileprivate` (since extensions are always declared at file scope). This matches the behavior of types declared `private` at file scope.
- As before, an explicit access modifier on an extension sets the maximum allowed access within that extension, and the compiler will warn on overly broad access within an extension that has an explicit access modifier.
## Impact on existing code
Existing code will need to rename `private` to `fileprivate` to achieve the same semantics, although in many cases the new meaning of `private` is likely to still compile and to run exactly as before.
## Alternatives considered
1. Do nothing and use `_` and `/` or split the code into more files and use the `private` modifier. The proposed solution makes the intent much clearer and enforced by the compiler, and the language does not dictate how the code must be organized.
2. Introduce a scoped namespace that would make it possible to hide APIs in part of the file. This introduces an extra level of grouping and nesting and forces APIs to be grouped by access level instead of a logical way that may make more sense.
3. Introduce a different access modifier and keep the current names unchanged. The proposal originally followed this approach to be completely compatible with the existing code, but the core team decided that it was better to use `private` for this modifier because it’s much closer to what the term means in other languages.
### Alternatives considered for "the private type issue"
1. Use `fileprivate` rather than `internal` as the default access level within `private` and `fileprivate` types. This is a more narrow change from the original model, but didn't have any benefits once we determined that the warning for unnecessarily broad access wasn't useful.
2. Introduce a new "parent" access level that declares an entity to be accessible within the *parent* lexical scope, rather than the immediately enclosing scope. This idea seems effective for `private` but is overly specific within types with any broader access and not worth the added complexity. We would also have to determine its name within the language, or decide that this level of access could not be spelled explicitly and was available only as the default access within private types.
3. Introduce a new "default" access level that names the default access within a scope. Within a `private` type, this would have the "parent" semantics from (2); elsewhere it would follow the rules laid down in previous versions of Swift. This idea likewise added complexity to the model for only a small gain in expressivity, and we would likewise have to determine a name for it within the language.
## Changes from revision 1
- The proposal was amended post-acceptance by [Robert Widmann][] and [Jordan Rose][] to account for "[the private type issue](#complications-with-private-types)". Only that section was added; there were no semantic changes to the rest of the proposal. This amendment requires a small amount of work to implement compared to the [alternatives considered](#alternatives-considered-for-the-private-type-issue), and was determined by the Core Team to be a small enough set of changes in the spirit of the original proposal that a full review was not necessary.
[Robert Widmann]: https://github.com/CodaFi
[Jordan Rose]: https://github.com/jrose-apple
================================================
FILE: proposals/0026-abstract-classes-and-methods.md
================================================
# Abstract classes and methods
* Proposal: [SE-0026](0026-abstract-classes-and-methods.md)
* Author: David Scrève
* Review Manager: [Joe Groff](https://github.com/jckarter/)
* Status: **Rejected**
* Review: ([pitch](https://forums.swift.org/t/proposal-draff-abstract-classes-and-methods/965)) ([review](https://forums.swift.org/t/review-se-0026-abstract-classes-and-methods/1580)) ([deferral](https://forums.swift.org/t/deferred-se-0026-abstract-classes-and-methods/1705)) ([rejection](https://forums.swift.org/t/returning-or-rejecting-all-the-deferred-evolution-proposals/60724))
## Introduction
When developing framework and reusable code, we need to develop classes that are partially
abstract with partial implementation. Protocol and protocol extensions provide this, but
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.
## Motivation
like pure virtual methods in C++ and abstract classes in Java and C#, frameworks development
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some
specific implementation methods which are not known in abstract class. This behavior
requires attributes that are used by internal abstract class method.
Example :
Considere a generic RESTClient that is included in a framework :
```swift
class RESTClient {
var timeout = 3000
var url : String {
assert(false,"Must be overridden")
return ""
}
func performNetworkCall() {
let restURL = self.url
print("Performing URL call to \(restURL) with timeout \(self.timeout)")
}
}
```
And an implementation :
```swift
class MyRestServiceClient : RESTClient {
override var url : String {
return "http://www.foo.com/client"
}
}
```
As you can see, url properties must be implemented by inherited class and should not be
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not
at compile time and might create crash for end-user.
Another workaround would be to use the delegate/datasource pattern, but the delegate will
not be able to use inheritance provided by classes.
## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can
be implemented.
We propose the keyword abstract that must be added to class and property/method :
```swift
abstract class RESTClient {
var timeout = 3000
abstract var url : String { get }
func performNetworkCall() {
let restURL = self.url
print("Performing URL call to \(restURL) with timeout \(self.timeout)")
}
}
```
And an implementation :
```swift
class MyRestServiceClient : RESTClient {
override var url : String {
return "http://www.foo.com/client"
}
}
```
## Detailed design
An abstract class cannot be instantiated.
Abstract method/property cannot have implementation.
If a class contains one or more abstract methods/properties, it must be declared abstract.
A class that inherits from abstract must be declared abstract if it does not implements
all inherited methods/properties.
If you try to implement an abstract class or a inherited class that implements partially
abstract methods/properties, you will get a compiler error.
As for override keyword, abstract properties apply on setter, getter and observers.
When declaring an abstract property, you must specify which methods must be implemented :
get, set, didSet, willSet.
If you do not specify anything, only setter and getter are made
abstract as below :
```swift
abstract var url : String
```
Observers provides default empty implementation.
Type is mandatory for abstract properties since it cannot be inferred.
## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being
stabilizing in Swift 3.0.
## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It
actually does not because abstract classes can have attributes and properties that
protocols do not support.
An alternative solution would be to add attributes to protocols and protocol extensions,
but this might break compatibility with Objective-C runtime.
================================================
FILE: proposals/0027-string-from-code-units.md
================================================
# Expose code unit initializers on String
* Proposal: [SE-0027](0027-string-from-code-units.md)
* Author: [Zachary Waldowski](https://github.com/zwaldowski)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Rejected**
* Decision Notes: [Rationale](https://forums.swift.org/t/rejected-se-0027-expose-code-unit-initializers-on-string/1529)
## Introduction
Going back and forth from Strings to their byte representations is an important part of solving many problems, including object serialization, binary and text file formats, wire/network interfaces, and cryptography. Swift has such utilities, but currently only exposed through `String.Type.fromCString(_:)` and `String.Type.fromCStringRepairingIllFormedUTF8(_:)`.
See swift-evolution [thread](https://forums.swift.org/t/faster-lower-level-external-string-initialization/974) and [draft proposal](https://forums.swift.org/t/faster-lower-level-external-string-initialization/974/4).
## Motivation
In developing a parser, a coworker did the yeoman's work of benchmarking Swift's Unicode types. He swore up and down that `String.Type.fromCString(_:)` ([use](https://gist.github.com/zwaldowski/5f1a1011ea368e1c833e#file-fromcstring-swift)) was the fastest way he found. I, stubborn and noobish as I am, was skeptical that a better way couldn't be wrought from Swift's `UnicodeCodecType`s.
After reading through stdlib source and doing my own testing, this is no wives' tale. `fromCString` is essentially the only public-facing user of `String.Type._fromCodeUnitSequence(_:input:)`, which serves the exact role of both efficient and safe initialization-by-buffer-copy. After many attempts, I've concluded that the currently available `String` APIs are deficient, as they provide much worse performance without guaranteeing more Unicode safety.
Of course, `fromCString(_:)` isn't a silver bullet; it forces a UTF-8 encoding with a null sentinel, requiring either a copy of the origin buffer or regressing to the much slower character-by-character append path if a terminator needs to be added. This is the case with formats that specify the length up front, or unstructured payloads that use another terminator). It also prevents the string itself from containing the null character. Finally, the `fromCString(_:)` constructor requires a call to `strlen`, even if that's already been calculated in users' code.
## Proposed solution
I'd like to expose an equivalent to `String.Type._fromCodeUnitSequence(_:input:)` as public API:
```swift
static func decode(_: Input, as: Encoding.Type, repairingInvalidCodeUnits: Bool = default) -> (result: String, repairsMade: Bool)?
```
For convenience, the `Bool` flag here is also separated out to a more common-case pair of `String` initializers:
```
init<...>(codeUnits: Input, as: Encoding.Type)
init?<...>(validatingCodeUnits: Input, as: Encoding.Type)
```
Finally, for more direct compatibility with `String.Type.fromCString(_:)` and `String.Type.fromCStringRepairingIllFormedUTF8(_:)`, these constructors are overloaded for pointer-based strings of unknown length:
```swift
init(cString: UnsafePointer)
init?(validatingCString: UnsafePointer)
```
## Detailed design
See [full implementation](https://github.com/apple/swift/compare/master...zwaldowski:string-from-code-units).
We start by backporting the [Swift 3.0](https://github.com/apple/swift/commit/f4aaece75e97379db6ba0a1fdb1da42c231a1c3b) versions of the `CString` constructors, then making them generic over their input and codec.
This is a fairly straightforward renaming of the internal APIs. The initializer, its labels, and their order were chosen to match other non-cast initializers in the stdlib. "Sequence" was removed, as it was a misnomer. "input" was kept as a generic name in order to allow for future refinements.
These new constructors swap the expectations for the default: `fromCString` could fail on invalid code unit sequences, but `init(cString:)` will unconditionally succeed. This, as developed against Swift 3, should "most probably [be] the right thing".
The backported constructors follow the Swift 3.0 naming guidelines, and presumably won't require any more changes after implementing this proposal.
The new API has overloads that continue to work the old `strlen` way, while allowing users to specify arbitrary code unit sequences through `UnsafeBufferPointer`. Low-level performance benefits like these are extremely important to performance-sensitive code. In the case of reading from buffers of unknown length, keeping copies low is vital.
The use of `String.Type._fromWellFormedCodeUnitSequence(_:input:)` was replaced with the new public API.
## Impact on existing code
`String.Type.fromCString(_:)` and `String.Type.fromCStringRepairingIllFormedUTF8(_:)` are replaced with `String.init(validatingCString:)` and `String.init(cString:)`, respectively. Do note that this is a reversal of the default expectations, as discussed above.
The old methods refer to the new signatures using deprecation attributes, presumably for removal in Swift 3.0.
## Alternatives considered
* Do nothing.
This seems suboptimal. For many use cases, `String` lacking this constructor is a limiting factor on performance for many kinds of pure-Swift implementations.
* A `String.UTF8View` and `String.UTF16View` solution
(See also "Make `String.append(_:)` faster")
Make `String.UTF8View` and `String.UTF16View` mutable (a la `String.UnicodeScalarView`) with amortized O(1) `append(_:)`/`appendContentsOf(_:)`. At least on the `String.UTF16View` side, this would be a simple change lifting the `append(_:)` from `String.UnicodeScalarView`. This would serve advanced use cases well, including supplanting `String.Type._fromWellFormedCodeUnitSequence(_:input:)`.
This might be the better long-term solution from the perspective of API maintenance, but in the meantime this proposal has a fairly low impact.
* A protocol-oriented API.
Some kind of `func decode(_:)` on `SequenceType`. It's not really clear this method would be related to string processing, and would require some kind of bounding (like `where Generator.Element: UnsignedIntegerType`), but that would be introducing a type bound that doesn't exist already.
* Make the `NSString` [bridge faster](https://gist.github.com/zwaldowski/5f1a1011ea368e1c833e#file-nsstring-swift).
After reading the bridge code, I don't really know why it's slower. Maybe it's a bug.
* Make `String.append(_:)` [faster](https://gist.github.com/zwaldowski/5f1a1011ea368e1c833e#file-unicodescalar-swift).
I don't completely understand the growth strategy of `_StringCore`, but it doesn't seem to exhibit the documented amortized `O(1)`, even when `reserveCapacity(_:)` is used. In the pre-proposal discussion, a user noted that it seems like `reserveCapacity` acts like a no-op.
================================================
FILE: proposals/0028-modernizing-debug-identifiers.md
================================================
# Modernizing Swift's Debugging Identifiers
* Proposal: [SE-0028](0028-modernizing-debug-identifiers.md)
* Author: [Erica Sadun](https://github.com/erica)
* Review Manager: [Chris Lattner](https://github.com/lattner)
* Status: **Implemented (Swift 2.2)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0028-modernizing-swifts-debugging-identifiers-line-etc/1303)
* Bug: [SR-669](https://bugs.swift.org/browse/SR-669)
## Introduction
This proposal aims to eliminate Swift's use of "[screaming snake case](https://en.wikipedia.org/wiki/Snake_case)" like `__FILE__` and `__FUNCTION__` and replacing identifier instances with common [octothorpe-prefixed](https://en.wiktionary.org/wiki/octothorpe) lowercase `#identifier` representations.
*The Swift-Evolution discussion of this topic took place in the "[Review] SE-0022: Referencing the Objective-C selector of a method" thread and then in its own "[\[Proposal\] Eliminating Swift's Screaming Snake Case Identifiers](https://forums.swift.org/t/proposal-eliminating-swifts-screaming-snake-case-identifiers/1165)" thread*
## Motivation
Swift offers built-in `__FILE__`, `__LINE__`, `__COLUMN__`, `__FUNCTION__`, and `__DSO_HANDLE__` identifiers. The first four expand to string and integer literals corresponding to a current location in source code. The last provides an `UnsafePointer` to the current dynamic shared object (.dylib or .so file). These features provide high utility for logging, both tracing execution and enabling developers to [capture error context](http://ericasadun.com/2015/08/27/capturing-context-swiftlang/).
The current identifiers owe their syntax to C's `__FILE__` and `__LINE__` macros. These are built into C's preprocessor and expanded before running the C-language parser. Swift's implementation differs from C's but offers similar functionality and, unfortunately, similar symbols. This proposal aims to break free of the historic chains of their unsightly screaming snake case, which look like boa constrictors [trying to digest](https://s-media-cache-ak0.pinimg.com/originals/59/ea/ee/59eaee788c31463b70e6e3d4fca5508f.jpg) fully swallowed keywords.
## Proposed solution
Using octothorpe-prefixed keywords offers several advantages:
* They match the existing `#available` keyword (D. Gregor)
* They match SE-0022's already-accepted `#selector(...)` approach that reference a method's Objective-C selector (D. Gregor)
* They support targeted code completion (D. Gregor)
* They add a compiler-supported expression type that doesn't steal keywords, introducing a convention where `#` means "invoke compiler substitution logic here" (J. Rose)
* They'd provide short-term solutions for a yet-as-undesigned macro system (D. Gregor)
## Detailed design
This proposal renames the following identifiers:
* `__FILE__` -> `#file`
* `__LINE__` -> `#line`
* `__COLUMN__` -> `#column`
* `__FUNCTION__` -> `#function` (*Added during review*)
* `__DSO_HANDLE__` -> `#dsohandle`
These identifiers retain the magic behavior of the existing `__LINE__` features: in a normal expression context, they expand to the location at that point. In a default argument context, they expand to the location of the caller.
Additional points to be considered by the Swift team for inclusion:
* Adding `#filename` to avoid using `lastPathComponent` on `#file` references.
* Retaining `__FUNCTION__` to be renamed as `#function`. (*Accepted during review*)
* Adopting a lower-case naming standard including `#dsohandle` and a potential future `#sourcelocation`.
* Introducing `#symbol`, (e.g. Swift.Dictionary.Init(x:Int,y:String)), which summarizes context including module, type, and function. A fully qualified symbol enables users to access exactly the information they desire. It should contain parameter type information to properly identify member overloads.
## Possible Future Extensions
[SR-198](https://bugs.swift.org/browse/SR-198) requested the coalescing of existing identifiers. A structured `#sourcelocation` identifier could be added as a follow-on if and when the Swift team decides to tackle a standardized source location type, which would provide individual field or keyword access.
In support of summaries, Remy Demerest writes, "[I] love the idea that source location would be one object that you can print to get the full story while still retaining the possibility to use each individual components as needed, which is probably the rarer case. I never find myself wanting only some of properties and usually don't include them simply because it takes longer to write the format properly, if I can get them all in one go it's certainly a win."
Should such a type be adopted, I'd recommend support for common output summary representations suitably differentiated for debug and release logging. Alternatively `#context`, `#releasecontext`, and `#debugcontext` summaries could be added independently of the adoption of `#sourcelocation`.
## Implementation notes
The octothorpe-delineated `#line` identifier already exists in Swift for resetting line numbers. Constraining the current `#line` directive to be the first token after a newline would disambiguate use. Alternatively, the context `#line` identifier could be renamed `#linenumber`.
## Review Acceptance and Modifications
The review of SE-0028 "Modernizing Swift's Debugging Identifiers" ran from January 29… February 2, 2016. The proposal has been *accepted*, with modifications:
* The core team agrees that we should rename all of the existing `__FILE__`, `__LINE__`, `__COLUMN__`, `__FUNCTION__`, and `__DSO_HANDLE__` symbols to lowercase equivalents in the `#` namespace: `#file`, `#line`, `#column`, `#function`, `#dsohandle`. This includes keeping `__FUNCTION__`, and making `#line` have the dual behavior of being a directive when it is the first token on a line, but an expression otherwise. Renaming these symbols improves uniformity within the Swift language, and keeping all of them provides a smooth transition path from the old syntax to the new syntax.
* The core team isn’t thrilled with the magic “first token on a line” whitespace behavior that `#line` will be getting, and would like to start a discussion about renaming the old `#line` directive to something more specific and tailored to its purpose. Once that name and syntax is settled, we can rename the directive and remove the whitespace rule.
* The core team requests that `#symbol` be split out into a separate proposal, because it needs more detailed design work, and is an additive feature. For example, it might be appealing to provide a `#mangledname` expression that provides the current symbol as a mangled name: when fed into a demangler, a more structured form of the current symbol would be available.
================================================
FILE: proposals/0029-remove-implicit-tuple-splat.md
================================================
# Remove implicit tuple splat behavior from function applications
* Proposal: [SE-0029](0029-remove-implicit-tuple-splat.md)
* Author: [Chris Lattner](https://github.com/lattner)
* Review Manager: [Joe Groff](https://github.com/jckarter)
* Status: **Implemented (Swift 3.0)**
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0029-remove-implicit-tuple-splat-behavior-from-function-applications/1380)
* Implementation: [apple/swift@8e12008](https://github.com/apple/swift/commit/8e12008d2b34a605f8766310f53d5668f3d50955)
## Introduction
Function call expressions (which include several syntactic forms that apply an argument list to something of function type) currently have a dual nature in Swift. Given something like:
```swift
func foo(a : Int, b : Int) {}
```
You can call it either with the typical syntactic form that passes arguments to each of its parameters:
```swift
foo(42, b : 17)
```
or you can take advantage of a little-known feature to pass an entire argument list as a single value (of tuple type):
```swift
let x = (1, b: 2)
foo(x)
```
This proposal recommends removing the later form, which I affectionately refer to as the "tuple splat" form. This feature is purely a sugar feature, it does not provide any expressive ability beyond passing the parameters manually.
Swift-evolution thread: [Proposal: Remove implicit tuple splat behavior from function applications](https://forums.swift.org/t/proposal-remove-implicit-tuple-splat-behavior-from-function-applications/1201)
## Motivation
This behavior is cute, precedented in other functional languages, and has some advantages, but it also has several major disadvantages, which are all related to its syntactic form.
* A call to `foo(x)` looks like a call to an overloaded version of `foo`, both to the compiler and to the human who maintains the code. This is extremely confusing if you don't know the feature exists.
* There are real ambiguities in the syntax, e.g. involving Any arguments and situations where you want to pass a tuple value as a single parameter.
* The current implementation has a ton of implementation bugs - it doesn't work reliably.
* The current implementation adds complexity to the type checker, slowing it down and adding maintenance burden.
* The current implementation doesn't work the way we would want a tuple splat operation to work. For example, arguably, you should be able to call foo with:
```swift
func bar() -> (Int, Int) { ... }
foo(bar())
```
... but this is not allowed, since tuple labels are required to line up. You have to write:
```swift
func bar() -> (Int, b: Int) { … }
foo(bar())
```
This makes this feature very difficult to use in practice, because you have to `_`'ize a lot of parameters (violating naming conventions), perform manual shuffling (defeating the sugar benefits of the feature), or add parameter labels to the result of functions (which leads to odd tying between callers and callees).
The root problem here is that we use exactly the same syntax for both forms of function application. If the two forms were differentiated (an option considered in “alternatives considered” below) then some of these problems would be defined away.
From a historical perspective, the tuple splat form of function application dates back to very early Swift design (probably introduced in 2010, but possibly 2011) where all function application was of a single value to a function type. For a large number of reasons (including inout, default arguments, variadic arguments, labels, etc) we completely abandoned this model, but never came back to reevaluating the tuple splat behavior.
If we didn’t already have this feature, we would not add it to Swift 3 (at least in its current form).
## Proposed solution
The proposed solution is simple, we should just remove this feature from the Swift 3 compiler. Ideally we would deprecate it in the Swift 2.2 compiler and remove it in Swift 3. However, if there isn’t time to get the deprecation into Swift 2.2, the author believes it would be perfectly fine to just remove it in Swift 3 (with a fixit + migration help of course).
One interesting aspect of this feature is that some people we’ve spoken to are very fond of it. However, when pressed, they admit that they are not actually using it widely in their code, or if they are using it, they are abusing naming conventions (distorting their code) in order to use it. This doesn’t seem like a positive contribution - this seems like a "clever" feature, not a practical one.
*Note:* a common point of confusion about this proposal is that it does not propose removing the ability to pass tuples as values to functions. For example, this will still be perfectly valid:
```swift
func f1(a : (Int, Int)) { ... }
let x = (1, 2)
f1(x)
```
as are cases using generics:
```swift
func f2(a : T) -> T { ... }
let x = (1, 2)
f2(x)
```
The only affected case is when a single tuple argument is being expanded by the compiler out into multiple different declared parameters.
## Detailed design
The design is straight-forward. In the Swift 3 time frame, we continue to parse and type check these expressions as we have so far, but produce an error + fixit hint when it is the tuple splat form. The migrator would auto-apply the fixit hint as it does for other cases.
## Impact on existing code
Any code that uses this feature will have to move to the traditional form. In the case of the example above, this means rewriting the code from:
```swift
foo(x)
```
into a form like this:
```swift
foo(x.0, x.b)
```
In the case where "x" is a complex expression, a temporary variable will need to be introduced. We believe that compiler fixits can handle the simple cases directly and that this extension is not widely used.
## Alternatives considered
The major problem with this feature is that it was not well considered and implemented properly (owing to its very old age, which has just been kept limping along). As such, the alternative is to actually design a proper feature to support this. Since the implicitness and syntactic ambiguity with normal function application is the problem, the solution is to introduce an explicit syntactic form to represent this. For example, something like this could address the problems we have:
```swift
foo(*x) // NOT a serious syntax proposal
```
However, actually designing this feature would be a non-trivial effort not core to the Swift 3 mission:
* It is a pure-sugar feature, and therefore low priority.
* We don't have an obvious sigil to use. "prefix-star" should be left unused for now in case we want to use it to refer to memory-related operations in the future.
* Making the tuple splat operation great requires more than just fixing the syntactic ambiguities we have, it would require re-evaluating the semantics of the operation (e.g. in light of parameter labels, varargs and other features).
If there is serious interest in pursuing this as a concept, we should do it as a follow-on proposal to this one. If a good design emerges, we can evaluate that design based on its merits.
The final alternative is that we could leave the feature in the compiler. However, that means living with its complexity “forever” or breaking code in the Swift 4 timeframe. It would be preferable to tackle this breakage in the Swift 3 timeframe, since we know that migration will already be needed then.
================================================
FILE: proposals/0030-property-behavior-decls.md
================================================
# Property Behaviors
* Proposal: [SE-0030](0030-property-behavior-decls.md)
* Author: [Joe Groff](https://github.com/jckarter)
* Review Manager: [Doug Gregor](https://github.com/DougGregor)
* Status: **Withdrawn**
* Superseded by: [SE-0258](0258-property-wrappers.md)
* Decision Notes: [Rationale](https://forums.swift.org/t/rejected-se-0030-property-behaviors/1546)
## Introduction
There are property implementation patterns that come up repeatedly.
Rather than hardcode a fixed set of patterns into the compiler,
we should provide a general "property behavior" mechanism to allow
these patterns to be defined as libraries.
[Swift Evolution Discussion](https://forums.swift.org/t/proposal-property-behaviors/594)
[Review](https://forums.swift.org/t/review-se-0030-property-behaviors/1385)
## Motivation
We've tried to accommodate several important patterns for properties with
targeted language support, but this support has been narrow in scope and
utility. For instance, Swift 1 and 2 provide `lazy` properties as a primitive
language feature, since lazy initialization is common and is often necessary to
avoid having properties be exposed as `Optional`. Without this language
support, it takes a lot of boilerplate to get the same effect:
```swift
class Foo {
// lazy var foo = 1738
private var _foo: Int?
var foo: Int {
get {
if let value = _foo { return value }
let initialValue = 1738
_foo = initialValue
return initialValue
}
set {
_foo = newValue
}
}
}
```
Building `lazy` into the language has several disadvantages. It makes the
language and compiler more complex and less orthogonal. It's also inflexible;
there are many variations on lazy initialization that make sense, but we
wouldn't want to hardcode language support for all of them. For instance, some
applications may want the lazy initialization to be synchronized, but `lazy`
only provides single-threaded initialization. The standard implementation of
`lazy` is also problematic for value types. A `lazy` getter must be `mutating`,
which means it can't be accessed from an immutable value. Inline storage is
also suboptimal for many memoization tasks, since the cache cannot be reused
across copies of the value. A value-oriented memoized property implementation
might look very different, using a class instance to store the cached value
out-of-line in order to avoid mutation of the value itself.
There are important property patterns outside of lazy initialization. It often
makes sense to have "delayed", once-assignable-then-immutable properties to
support multi-phase initialization:
```swift
class Foo {
let immediatelyInitialized = "foo"
var _initializedLater: String?
// We want initializedLater to present like a non-optional 'let' to user code;
// it can only be assigned once, and can't be accessed before being assigned.
var initializedLater: String {
get { return _initializedLater! }
set {
assert(_initializedLater == nil)
_initializedLater = newValue
}
}
}
```
Implicitly-unwrapped optionals allow this in a pinch, but give up a lot of
safety compared to a non-optional 'let'. Using IUO for multi-phase
initialization gives up both immutability and nil-safety.
We also have other application-specific property features like
`didSet`/`willSet` that add language complexity for
limited functionality. Beyond what we've baked into the language already,
there's a seemingly endless set of common property behaviors, including
synchronized access, copying, and various kinds of proxying, all begging for
language attention to eliminate their boilerplate.
## Proposed solution
I suggest we allow for **property behaviors** to be implemented within the
language. A `var` declaration can specify its **behaviors** in square
brackets after the keyword:
```swift
var [lazy] foo = 1738
```
which implements the property `foo` in a way described by the **property
behavior declaration** for `lazy`:
```swift
var behavior lazy: Value {
var value: Value? = nil
initialValue
mutating get {
if let value = value {
return value
}
let initial = initialValue
value = initial
return initial
}
set {
value = newValue
}
}
```
Property behaviors can control the storage,
initialization, and access of affected properties, obviating the need for
special language support for `lazy`, observers, and other
special-case property features.
## Examples
Before describing the detailed design, I'll run through some examples of
potential applications for behaviors.
### Lazy
The current `lazy` property feature can be reimplemented as a property behavior.
```swift
// Property behaviors are declared using the `var behavior` keyword cluster.
public var behavior lazy: Value {
// Behaviors can declare storage that backs the property.
private var value: Value?
// Behaviors can bind the property's initializer expression with an
// `initialValue` property declaration.
initialValue
// Behaviors can declare initialization logic for the storage.
// (Stored properties can also be initialized in-line.)
init() {
value = nil
}
// Inline initializers are also supported, so `var value: Value? = nil`
// would work equivalently.
// Behaviors can declare accessors that implement the property.
mutating get {
if let value = value {
return value
}
let initial = initialValue
value = initial
return initial
}
set {
value = newValue
}
}
```
Properties declared with the `lazy` behavior are backed by the `Optional`-typed
storage and accessors from the behavior:
```swift
var [lazy] x = 1738 // Allocates an Int? behind the scenes, inited to nil
print(x) // Invokes the `lazy` getter, initializing the property
x = 679 // Invokes the `lazy` setter
```
### Delayed Initialization
A property behavior can model "delayed" initialization behavior, where the DI
rules for properties are enforced dynamically rather than at compile time.
This can avoid the need for implicitly-unwrapped optionals in multi-phase
initialization. We can implement both a mutable variant, which
allows for reassignment like a `var`:
```swift
public var behavior delayedMutable: Value {
private var value: Value? = nil
get {
guard let value = value else {
fatalError("property accessed before being initialized")
}
return value
}
set {
value = newValue
}
}
```
and an immutable variant, which only allows a single initialization like
a `let`:
```swift
public var behavior delayedImmutable: Value {
private var value: Value? = nil
get {
guard let value = value else {
fatalError("property accessed before being initialized")
}
return value
}
// Perform an initialization, trapping if the
// value is already initialized.
set {
if let _ = value {
fatalError("property initialized twice")
}
value = initialValue
}
}
```
This enables multi-phase initialization, like this:
```swift
class Foo {
var [delayedImmutable] x: Int
init() {
// We don't know "x" yet, and we don't have to set it
}
func initializeX(x: Int) {
self.x = x // Will crash if 'self.x' is already initialized
}
func getX() -> Int {
return x // Will crash if 'self.x' wasn't initialized
}
}
```
### Property Observers
A property behavior can also approximate the built-in behavior of
`didSet`/`willSet` observers, by declaring support for custom accessors:
```swift
public var behavior observed: Value {
initialValue
var value = initialValue
// A behavior can declare accessor requirements, the implementations of
// which must be provided by property declarations using the behavior.
// The behavior may provide a default implementation of the accessors, in
// order to make them optional.
// The willSet accessor, invoked before the property is updated. The
// default does nothing.
mutating accessor willSet(newValue: Value) { }
// The didSet accessor, invoked before the property is updated. The
// default does nothing.
mutating accessor didSet(oldValue: Value) { }
get {
return value
}
set {
willSet(newValue)
let oldValue = value
value = newValue
didSet(oldValue)
}
}
```
A common complaint with `didSet`/`willSet` is that the observers fire on
*every* write, not only ones that cause a real change. A behavior
that supports a `didChange` accessor, which only gets invoked if the property
value really changed to a value not equal to the old value, can be implemented
as a new behavior:
```swift
public var behavior changeObserved: Value {
initialValue
var value = initialValue
mutating accessor didChange(oldValue: Value) { }
get {
return value
}
set {
let oldValue = value
value = newValue
if oldValue != newValue {
didChange(oldValue)
}
}
}
```
For example:
```swift
var [changeObserved] x: Int = 1 {
didChange { print("\(oldValue) => \(x)") }
}
x = 1 // Prints nothing
x = 2 // Prints 1 => 2
```
(Note that, like `didSet`/`willSet` today, neither behavior implementation
will observe changes through class references that mutate a referenced
class instance without changing the reference itself. Also, as currently
proposed, behaviors would force the property to be initialized in-line, which
is not acceptable for instance properties. That's a limitation that can
be lifted by future extensions.)
### Synchronized Property Access
Objective-C supports `atomic` properties, which take a lock on `get` and `set`
to synchronize accesses to a property. This is occasionally useful, and it can
be brought to Swift as a behavior. The real implementation of `atomic`
properties in ObjC uses a global bank of locks, but for illustrative purposes
(and to demonstrate referring to `self`) I'll use a per-object lock instead:
```swift
// A class that owns a mutex that can be used to synchronize access to its
// properties.
public protocol Synchronizable: class {
func withLock(@noescape body: () -> R) -> R
}
// Behaviors can refer to a property's containing type using
// the implicit `Self` generic parameter. Constraints can be
// applied using a 'where' clause, like in an extension.
public var behavior synchronized