Hmm, I don't recall the earlier discussion, but IMO, Charlie's proposal is pretty sensible. Seems backwards to adding much broader things like default argument support for protocols motivated by a use case that should Just Work(TM).
I recall that once upon a time Chris Lattner declared that the core team was perfectly willing to implement difficult things if it improved the Swift user experience. Here, it seems either this is something that *can* be made to just work in the default arguments handling department, and then it should be, or it can't, and then the closure syntax is a fairly obvious and workable if not pretty workaround. No point in designing features as a workaround for something that has both an obvious ideal solution and a current workaround. On Thu, Jan 19, 2017 at 23:07 David Sweeris via swift-evolution < [email protected]> wrote: > > On Jan 9, 2017, at 02:13, Charlie Monroe via swift-evolution < > [email protected]> wrote: > > I came across something that I'm not sure it's a bug or by design and if > it's by design, whether this should be discussed here. > > Example: > > class Foo { > init(number: Int) { /* ... */ } > } > > let closure = Foo.init(number:) // (Int) -> Foo > [1, 2, 3].map(closure) // [Foo, Foo, Foo] > > This works great until the initializer gets a default argument: > > class Foo { > init(number: Int, string: String = "") { /* ... */ } > } > > // Error: Foo has no member init(number:) > let closure = Foo.init(number:) > > I was wondering if we could get closures to methods without the default > arguments. Currently, this needs to be worked around by e.g. creating a > second closure that invokes the method without the default arguments: > > let closure: (Int) -> Foo = { Foo(number: $0) } > > But to me it seems like something that should work "out of the box". > > Thoughts? > > > IIRC, this issue was raised a while ago, and as best as I recall the gist > of the answer was that default arguments are implemented at the call site, > and because of that you can't pass a function with default arguments to > something expecting a function with fewer arguments even though the two > calls look identical in the source code. > > It causes other issues, too. For instance, if we have > protocol Initable { init() } > And > struct Foo { init(_ x: Int = 0) {} } > We're left in an odd situation where `Foo` can't meaningfully conform to > `Initable` because while "init(_: Int = 0)" is not the same as "init()", if > you add a "init()" to `Foo` > you'll get an ambiguous somethingerather error because there's no > mechanism for the compiler to know whether you want the actual "0 argument" > function or the "1 argument with 1 default value" function. > > Aside from re-architecting the default argument system (which I'm not even > sure is possible, let alone a good idea), I think I see couple ways forward > for the protocol conformance issue. Both have downsides, though. > > 1) Require any potentially conflicting protocol functions to be in an > extension so the compiler knows what's going on, have "Foo()" call the one > defined in the type, and use "(Foo as Initable)()" for the protocol version > defined in an extension. This could get real confusing real fast if people > don't realize there's two functions with, as far as they can tell, the same > signature. > > 2) Add default argument support to protocols. The syntax that makes sense > to me would be something like > protocol Bar { > func baz(_: Int = _) > } > On the downside, I suspect this would necessarily add a phantom "Self or > associated type requirement" so that the compiler could have a way to get > at each implementation's default value. It's not ideal... You'd get an > error kinda out of the blue if you tried to use the function > non-generically, but at least you couldn't have a function change out from > under you. > > - Dave Sweeris > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
