Skip to content

Commit 43401a7

Browse files
authored
Merge pull request #1611 from xedin/se-0347-simplify-introduction
SE-0347: Add clarifying example and supporting text to Introduction section
2 parents 14f6c98 + 8501d55 commit 43401a7

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

proposals/0347-type-inference-from-default-exprs.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,35 @@
99

1010
## Introduction
1111

12-
I propose to allow type inference for generic parameters from concretely-typed default parameter values (referred as default expressions in the proposal) when the call-site omits an explicit argument. Concretely-typed default expressions would still be rejected by the compiler if generic parameters associated with a defaulted parameter could be inferred _at a call site_ from any other location in a parameter list by an implicit or explicit argument. For example, declaration `func compute<T, U>(_:T = 42, _: U) where U: Collection, U.Element == T` is going to be rejected by the compiler because it's possible to infer a type of `T` from the first argument, but declaration `func compute<T, U>(_: T = 42, _: U = []) where U: Collection, U.Element == Int` is going to be accepted because `T` and `U` are independent.
12+
It's currently impossible to use a default value expression with a generic parameter type to default the argument and its type:
13+
14+
```swift
15+
func compute<C: Collection>(_ values: C = [0, 1, 2]) {
16+
...
17+
}
18+
```
19+
20+
An attempt to compile this declaration results in the following compiler error - `default argument value of type '[Int]' cannot be converted to type 'C'` because, under the current semantic rules, the type of a default expression has to work for every possible concrete type replacement of `C` inferred at a call site. There are couple of ways to work around this expressivity limitation, but all of them require overloading which complicates APIs:
21+
22+
```
23+
func compute<C: Collection>(_ values: C) { // original declaration without default
24+
...
25+
}
26+
27+
func compute(_ values: [Int] = [0, 1, 2]) { // concretely typed overload of `compute` with default value
28+
...
29+
}
30+
```
31+
32+
I propose to allow type inference for generic parameters from concretely-typed default parameter values (referred to as default expressions in the proposal) when the call-site omits an explicit argument. Concretely-typed default expressions would still be rejected by the compiler if generic parameters associated with a defaulted parameter could be inferred _at a call site_ from any other location in a parameter list by an implicit or explicit argument. For example, declaration `func compute<T, U>(_: T = 42, _: U) where U: Collection, U.Element == T` is going to be rejected by the compiler because it's possible to infer a type of `T` from the second argument, but declaration `func compute<T, U>(_: T = 42, _: U = []) where U: Collection, U.Element == Int` is going to be accepted because `T` and `U` are independent.
33+
34+
Under the proposed rules, the original `compute` declaration becomes well formed and doesn't require any additional overloads:
35+
36+
```swift
37+
func compute<C: Collection>(_ values: C = [0, 1, 2]) {
38+
...
39+
}
40+
```
1341

1442
Swift-evolution thread: [Discussion thread topic for that proposal](https://forums.swift.org/t/pitch-type-inference-from-default-expressions/55585)
1543

0 commit comments

Comments
 (0)