Hi everyone,
Some of you may remember SE-0220, my proposal that added the count(where:)
function to sequences. This proposal was ultimately accepted in time for Swift 5, but sadly had to be reverted because it was causing issues with the type checker.
The issue was that when you reference count
, in an expression like myArray.count * 5
, you could be referring to the count
property, with type Int
, or the count(where:)
function, which has type ((Element) -> Bool) -> Int
, which you can refer to in shorthand as count
. When Swift tries to resolve what version of the *
function to use, it has to run through a lot more potential implementations, which explode combinatorially as you increase the number of operators in the expression.
I've thought about this problem for a while and chatted with a few folks about the issue, and I think the simplest path forward to solve this is to require parameter names when referencing functions.
In other words, you wouldn't be able to refer to functions with their shorthand anymore (i.e., count
), you'd have to refer to them by their full name (i.e., count(where:)
).
This change has the added benefit of making Swift a more precise language as well. There are currently other method resolution problems with situations like myArray.map(Int.init)
, where the compiler has to do a lot of work to determine which implementation to use. In addition, Int.init
isn't particularly specific, and therefore when new initializers get added, the meaning of this code can change or become ambiguous — which has actually already happened — causing an unintended source breakage. Requiring a more complete name would help in these situations as well.
If people like this solution, I'm happy to write up the proposal, and perhaps me and someone else can implement it together?