[swift-evolution] Will Swift ever support optional methods without @objc?
Haravikk
swift-evolution at haravikk.me
Tue Nov 15 12:00:57 CST 2016
> On 15 Nov 2016, at 14:59, Karl <razielim at gmail.com> wrote:
>> On 15 Nov 2016, at 12:22, Haravikk via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> What's different about having the method return nil vs being optional? You're attempting to call it either way, and presumably need some means of handling the return value, except in Swift it's all nice and explicit and easy to put in a conditional like:
>>
>> if let result = myObject.someOptionalMethod() { /* Do some stuff */ }
>> print(myObject.someOptionalStringMethod() ?? "")
>>
>> And so-on. If you need a method to be both optional, and return a nilable result then you can use a double optional like so:
>>
>> if let result = myObject.someDoubleOptionalMethod() { // Method was implemented
>> if let value = result { // Method returned a value
>> /* Do some stuff */
>> }
>> }
>>
>>
>> By defining the methods as returning an Optional and throwing in default implementations you can specify fewer, bigger protocols and make clear what the requirements really are, though personally given the choice I'd prefer a dozen smaller protocols that are absolutely explicit in what they do.
>>
>> But yeah, I think the tools you need are all there already; maybe there's an argument to be made for allowing default return values on protocol methods, to reduce the boiler-plate?
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> I think there is a difference between:
>
> - A method which returns an optional result, and
> - An optional method which, if present, always returns a result
>
> Perhaps not so much of a difference at the usage site (it’s just a question of placing a ? for optional chaining), but semantically and when conforming to the protocol, they mean different things.
Maybe, but it just seems like default implementations do everything that optional methods require, it's just not got a shorthand to make it easier.
Really the question is, do we adopt the optional keyword for non @objc methods, along with the special syntax for calling them (it's not exactly the same as chaining). Personally though I'd rather do the opposite and do away with both, and have @objc optional methods replaced by default implementations somehow.
The question then is how; simply making the methods optional (return type becomes optional, or more optional) is not the best solution as testing optionality isn't a one-size-fits-all solution. For example, API designers may prefer to return a method's non-implemented state with a specific int or enum case, or by throwing an exception or producing an error. You can do all of these things with default implementations.
Otherwise you could allow specifying of default return values within a protocol itself, functionally this would be identical to adding a default implementation, just a bit easier for the simplest case, I'm not sure it warrants special treatment though.
I mean, when it comes down to it an optional method is just one that might do nothing; but a default implementation that returns a default value or has no body achieves this just as effectively. The only advantage here is the call-site semantics, but you can enforce the same by having an optional return value if that's required.
Put another way, I don't see what's gained by the first of these two:
foo.someOptionalMethod?() // @objc optional method
foo.someMethod() // default implementation is empty
You've attempted to call both, and in both cases it just won't do anything. Your knowing that doesn't really change anything. Meanwhile if you have a return value:
if let result = foo.someOptionalMethod?() { /* Process result * / }
if let result = foo.someMethod() { /* Process result */ } // default implementation returns nil
If just doesn't seem like such a special case to require special treatment when Swift's optional support is already really good and encapsulates the same ideas, and the void case just needs a default implementation that's a no-op. Plus by using a default implementation you have more flexibility overall in how you actually respond when a method isn't implemented.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161115/fa4830e7/attachment.html>
More information about the swift-evolution
mailing list