Skip to content

Commit 8d6b522

Browse files
committed
Make updates.
1 parent a0120cc commit 8d6b522

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

proposals/NNNN-method-and-initializer-keypaths.md

+25-18
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Authors: [Amritpan Kaur](https://github.com/amritpan), [Pavel Yaskevich](https://github.com/xedin)
55
* Review Manager: TBD
66
* Status: **Awaiting review**
7-
* Implementation: [swiftlang/swift#78823](https://github.com/swiftlang/swift/pull/78823) [swiftsyntax/swiftsyntax#2950](https://github.com/swiftlang/swift-syntax/pull/2950)
7+
* Implementation: [swiftlang/swift#78823](https://github.com/swiftlang/swift/pull/78823), [swiftlang/swiftsyntax#2950](https://github.com/swiftlang/swift-syntax/pull/2950), [swiftlang/swiftfoundation#1179](https://github.com/swiftlang/swift-foundation/pull/1179)
88
* Upcoming Feature Flag: `KeyPathWithMethodMembers`
99
* Review: ([pitch](https://forums.swift.org/t/pitch-method-key-paths/76678))
1010

@@ -85,27 +85,19 @@ If the member is a metatype (e.g., a static method, class method, initializer, o
8585

8686
```swift
8787
struct Calculator {
88-
func add(_ a: Int, _ b: Int) -> Int {
88+
static func add(_ a: Int, _ b: Int) -> Int {
8989
return a + b
9090
}
9191
}
9292

93-
let calc = Calculator.self
94-
let addKeyPath: KeyPath<Calculator.Type, (Calculator) -> (Int, Int) -> Int> = \Calculator.Type.add
93+
let addKeyPath: KeyPath<Calculator.Type, Int> = \Calculator.Type.add(4, 5)
9594
```
9695

97-
Here, `addKeyPath` is a key path that references the add method of `Calculator` as a metatype member. The key path’s root type is `Calculator.Type`, and it resolves to an unapplied instance method: `(Calculator) -> (Int, Int) -> Int`. This represents a curried function where the first step binds an instance of `Calculator`, and the second step applies the method arguments.
98-
99-
```swift
100-
let addFunction = calc[keyPath: addKeyPath]
101-
let fullyApplied = addFunction(Calculator())(20, 30)`
102-
```
103-
104-
`addFunction` applies an instance of Calculator to the key path method. `fullyApplied` further applies the arguments (20, 30) to produce the final result.
96+
Here, `addKeyPath` is a key path that references the add method of `Calculator` as a metatype member. The key path’s root type is `Calculator.Type`, and the value resolves to an applied instance method result type of`Int`.
10597

10698
### Overloads
10799

108-
Keypaths to methods with the same base name and distinct argument labels can be disambiguated by explicitly including the argument labels:
100+
Keypaths to methods with the same base name and distinct argument labels can be disambiguated with explicit argument labels:
109101

110102
```swift
111103
struct Calculator {
@@ -114,10 +106,25 @@ struct Calculator {
114106
func subtract(that: Int) -> Int { that + that }
115107
}
116108

117-
let kp1 = \S.subtract // KeyPath<S, (Int, Int) -> Int
118-
let kp2 = \S.subtract(this:) // WritableKeyPath<S, (Int) -> Int>
119-
let kp3 = \S.subtract(that:) // WritableKeyPath<S, (Int) -> Int>
120-
let kp4 = \S.subtract(that: 1) // WritableKeyPath<S, Int>
109+
let kp1 = \Calculator.subtract // KeyPath<Calculator, (Int, Int) -> Int
110+
let kp2 = \Calculator.subtract(this:) // KeyPath<Calculator, (Int) -> Int>
111+
let kp3 = \Calculator.subtract(that:) // KeyPath<Calculator, (Int) -> Int>
112+
let kp4 = \Calculator.subtract(that: 1) // KeyPath<Calculator, Int>
113+
```
114+
115+
### Implicit closure conversion
116+
117+
This feature also supports implicit closure conversion of key path methods, allowing them to used in expressions where closures are expected, such as in higher order functions:
118+
119+
```swift
120+
struct Calculator {
121+
func power(of base: Int, exponent: Int) -> Int {
122+
return Int(pow(Double(base), Double(exponent)))
123+
}
124+
}
125+
126+
let calculators = [Calculator(), Calculator()]
127+
let results = calculators.map(\.power(of: 2, exponent: 3))
121128
```
122129

123130
### Dynamic member lookups
@@ -141,7 +148,7 @@ print(subtract(10))
141148

142149
### Effectful value types
143150

144-
Methods annotated with `nonisolated` and `consuming` are supported by this feature. `mutating`, `throwing` and `async` are not supported for any other component type and will similarly not be supported for methods. Keypaths cannot capture method arguments that are not `Hashable`/`Equatable`, so `escaping` is also not supported.
151+
Methods annotated with `nonisolated` and `consuming` are supported by this feature. However, noncopying root and value types [are not supported](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0437-noncopyable-stdlib-primitives.md#additional-future-work). `mutating`, `throws` and `async` are not supported for any other component type and will similarly not be supported for methods. Additionally keypaths cannot capture closure arguments that are not `Hashable`/`Equatable`.
145152

146153
### Component chaining
147154

0 commit comments

Comments
 (0)