Skip to content

Commit dcb85ff

Browse files
committed
Make updates.
1 parent 27a40ab commit dcb85ff

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

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

+21-14
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 {
@@ -120,6 +112,21 @@ let kp3 = \S.subtract(that:) // WritableKeyPath<S, (Int) -> Int>
120112
let kp4 = \S.subtract(that: 1) // WritableKeyPath<S, Int>
121113
```
122114

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))
128+
```
129+
123130
### Dynamic member lookups
124131

125132
`@dynamicMemberLookup` can resolve method references through key paths, allowing methods to be accessed dynamically without explicit function calls:
@@ -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)