public protocol PatternMatcher {
associatedtype Element
func matchingPrefix<C: Collection>(for collection: C) -> C.Index?
where C.Element == Element
}
I thought you could do this:
enum BasicPatternMatcher { /*...*/ }
extension BasicPatternMatcher: PatternMatcher {
public func matchingPrefix<C: Collection>(
for collection: C,
checkInvariants: Bool = true
) -> C.Index?
where C.Element == Element {
//...
}
}
but it isn't actually accepted! The playground flags an error of a missing method and suggests a new stub. I know if you use a protocol with a non-generic method, and your type defines a generic method with the same signature pattern such that the protocol's requirement would match, the compiler will use that method. I thought a defaulted extra parameter would work too.
Does this actually not work? Or does it work but I messed up somewhere? I'm using Xcode 11.6 on a Catalina system.
If it doesn't actually work, I think we should add this.
Test.extension.foo(a: Bool = true) isn't considered a witness for Test.foo(). You'll get the same error if you did:
struct S: Test {} // Type 'S' does not conform to protocol 'Test'
although I think it would be reasonable to allow functions with default arguments to satisfy protocol requirements (as I mentioned in the Protocol Witness Matching Manifesto).
With that in mind a lot of quirks with defaulted arguments make sense:
you cannot refer to this method as f(x:) because we only defined f(x:defaulted:)
you cannot cast it to (Int) -> Void because there exists only two argument version
if you have #line as a default value it shows the line where the function was called, not defined
it satisfies func f(x: Int, defaulted: Bool) protocol requirement, but not func f(x: Int)
Why is it like that? I am not a compiler developer, but if swift generated a function for every combination of defaulted parameters, just imagine what would happen if you had a function with 10 parameters, all defaulted. If my math is correct, compiler would have to create 2^10 functions which is 1024. With current implementation it generates only 11 functions (one with 10 arguments, and 10 functions that return default arguments). I could imagine that it could be made to work if functions were generated only if they were used