I find that optional protocol methods to be very useful. However, there is a caveat -- it needs to be mapped to @objc. This puts a set of limitations, such as: structures cannot be used as parameters as it does not map to objective-c. What do you think about removing the requirement of using @objc and allow to create optional methods without these limitations?
(For those suggesting a separate protocol, consider UITableView. How many protocols would it take to model all the optional delegate methods as separate protocols? Certainly more than 10, perhaps a few dozen.)
I would welcome a standardized way to document the methods as optional-to-implement, though, beyond just requiring a protocol extension. My ideal option would be to allow the optional keyword and change it to simply require a default implementation in a protocol extension.
If we don't want a language change, then perhaps a conventional doc tag?
If you put “optional” there, the compiler would auto-generate an empty function in a protocol extension in your module as if you had specified one yourself. If the function has a return value, you would be required to specify the default return value in the protocol which provides automatic documentation of the default, too. (It would be an error to have an optional function with a return value that doesn’t have a default value specified in the protocol.) (I am not currently in favor of supplying a default implementation body inside of a protocol as has been discussed some previously.)
If you provide a default implementation of an optional protocol function in a protocol extension in the same module as the protocol itself is declared in, it would be an error and you’d have to make the function non-optional or get rid of your conflicting protocol extension implementation. If the protocol was declared in a different module, then that restriction would be lifted since presumably you’re providing a default implementation via protocol extension on purpose.
l8r
Sean
···
On Mar 31, 2016, at 1:34 AM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:
Just a thought: optional methods could be modeled by methods in a protocol that return optional closures.
-Thorsten
Am 31. März 2016 um 04:42 schrieb Andrey Tarantsov via swift-evolution <swift-evolution@swift.org>:
I'm missing those optional methods too, but protocol extensions sound like a better solution for this.
(For those suggesting a separate protocol, consider UITableView. How many protocols would it take to model all the optional delegate methods as separate protocols? Certainly more than 10, perhaps a few dozen.)
I would welcome a standardized way to document the methods as optional-to-implement, though, beyond just requiring a protocol extension. My ideal option would be to allow the optional keyword and change it to simply require a default implementation in a protocol extension.
If we don't want a language change, then perhaps a conventional doc tag?
A.
On Mar 30, 2016, at 8:08 PM, Yuval Tal via swift-evolution <swift-evolution@swift.org> wrote:
Hi,
I find that optional protocol methods to be very useful. However, there is a caveat -- it needs to be mapped to @objc. This puts a set of limitations, such as: structures cannot be used as parameters as it does not map to objective-c. What do you think about removing the requirement of using @objc and allow to create optional methods without these limitations?
This captures the idea of optional methods as used in Objective-C quite nicely IMO. And it already works without needing a new language feature.
If/when Swift gains the ability to declare default implementations within a protocol instead of needing an extension the boilerplate of having to repeat everything in the extension would drop away.
If you put “optional” there, the compiler would auto-generate an empty function in a protocol extension in your module as if you had specified one yourself. If the function has a return value, you would be required to specify the default return value in the protocol which provides automatic documentation of the default, too. (It would be an error to have an optional function with a return value that doesn’t have a default value specified in the protocol.) (I am not currently in favor of supplying a default implementation body inside of a protocol as has been discussed some previously.)
I do not understand why an optional method should require a default value. That’s not how optional methods work in Objective-C where the caller will ask whether the method is implemented and calls it or does something else. With a default value it would be much more difficult to do something different if the method is not implemented.
Actually with a default value the method would just be a normal method which has not been overridden, there would be nothing optional about it anymore.
-Thorsten
···
Am 31.03.2016 um 17:18 schrieb Sean Heber <sean@fifthace.com>:
If you provide a default implementation of an optional protocol function in a protocol extension in the same module as the protocol itself is declared in, it would be an error and you’d have to make the function non-optional or get rid of your conflicting protocol extension implementation. If the protocol was declared in a different module, then that restriction would be lifted since presumably you’re providing a default implementation via protocol extension on purpose.
l8r
Sean
On Mar 31, 2016, at 1:34 AM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:
Just a thought: optional methods could be modeled by methods in a protocol that return optional closures.
-Thorsten
Am 31. März 2016 um 04:42 schrieb Andrey Tarantsov via swift-evolution <swift-evolution@swift.org>:
I'm missing those optional methods too, but protocol extensions sound like a better solution for this.
(For those suggesting a separate protocol, consider UITableView. How many protocols would it take to model all the optional delegate methods as separate protocols? Certainly more than 10, perhaps a few dozen.)
I would welcome a standardized way to document the methods as optional-to-implement, though, beyond just requiring a protocol extension. My ideal option would be to allow the optional keyword and change it to simply require a default implementation in a protocol extension.
If we don't want a language change, then perhaps a conventional doc tag?
A.
On Mar 30, 2016, at 8:08 PM, Yuval Tal via swift-evolution <swift-evolution@swift.org> wrote:
Hi,
I find that optional protocol methods to be very useful. However, there is a caveat -- it needs to be mapped to @objc. This puts a set of limitations, such as: structures cannot be used as parameters as it does not map to objective-c. What do you think about removing the requirement of using @objc and allow to create optional methods without these limitations?
If you put “optional” there, the compiler would auto-generate an empty function in a protocol extension in your module as if you had specified one yourself. If the function has a return value, you would be required to specify the default return value in the protocol which provides automatic documentation of the default, too.
You can only have a single property named "gestureRecognizer", so you
either have to come up with other names for these, or change the language
to allow closure-typed properties to have multipart names.
Good point. That would obviously restrict the choice for naming the methods in such a protocol, but since we are talking about new protocols that would not be an impediment. It might result in non-optimal method names, of course.
-Thorsten
···
Am 31.03.2016 um 18:37 schrieb Rob Mayoff via swift-evolution <swift-evolution@swift.org>:
On Thu, Mar 31, 2016 at 10:56 AM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:
protocol UIGestureRecognizerDelegate {
var gestureRecognizerShouldBegin: ((gestureRecognizer: UIGestureRecognizer) -> Bool)? { get }
}
UIGestureRecognizerDelegate has five methods that are "named" gestureRecognizer:
gestureRecognizer(_:shouldRecognizeSimultaneouslyWithGestureRecognizer:)
gestureRecognizer(_:shouldRequireFailureOfGestureRecognizer:)
gestureRecognizer(_:shouldBeRequiredToFailByGestureRecognizer:)
gestureRecognizer(_:shouldReceiveTouch:)
gestureRecognizer(_:shouldReceivePress:)
You can only have a single property named "gestureRecognizer", so you either have to come up with other names for these, or change the language to allow closure-typed properties to have multipart names.
All use-cases I had for optional methods in protocols in Objective-C are covered nicely by providing a default implementation in a protocol extension, so I don't think optional protocol methods should be a thing in pure Swift.
I do not understand why an optional method should require a default value. That’s not how optional methods work in Objective-C where the caller will ask whether the method is implemented and calls it or does something else. With a default value it would be much more difficult to do something different if the method is not implemented.
Actually with a default value the method would just be a normal method which has not been overridden, there would be nothing optional about it anymore.
I've actually had multiple cases in Objective-C code where this feature (some object behaving differently depending on wether or not a delegate method has been implemented) has prevented me from implementing features the easy and obvious way. In those cases I resorted to implementing 'respondsToSelector:'. So I'd argue that optional protocol methods encourage this type of behavior, which imho is bad API design. If you need to behave differently for some types of delegates (or whatever else your protocol represents), a separate method to call to determine how to behave is much simpler and better to use.
I do not understand why an optional method should require a default value. That’s not how optional methods work in Objective-C where the caller will ask whether the method is implemented and calls it or does something else. With a default value it would be much more difficult to do something different if the method is not implemented.
Yes, and that's the best part. The way Obj-C optional methods currently work, they are very hard to wrap/proxy/etc. Swift has a lot more expressive power, so I'm sure that you can adjust the return value to express the “I don't care” case without making the absence of the method magical.
All use-cases I had for optional methods in protocols in Objective-C are covered nicely by providing a default implementation in a protocol extension, so I don't think optional protocol methods should be a thing in pure Swift.
I do not understand why an optional method should require a default value. That’s not how optional methods work in Objective-C where the caller will ask whether the method is implemented and calls it or does something else. With a default value it would be much more difficult to do something different if the method is not implemented.
Actually with a default value the method would just be a normal method which has not been overridden, there would be nothing optional about it anymore.
I've actually had multiple cases in Objective-C code where this feature (some object behaving differently depending on wether or not a delegate method has been implemented) has prevented me from implementing features the easy and obvious way. In those cases I resorted to implementing 'respondsToSelector:'. So I'd argue that optional protocol methods encourage this type of behavior, which imho is bad API design. If you need to behave differently for some types of delegates (or whatever else your protocol represents), a separate method to call to determine how to behave is much simpler and better to use.
+1. This is exactly the same thing I mentioned regarding the fast path for row height in UITableView. The fact that it depends on whether or not the delegate implements heightForRowAtIndexPath is a bad design decision.
···
Sent from my iPad
On Apr 2, 2016, at 7:04 AM, Lukas Stabe via swift-evolution <swift-evolution@swift.org> wrote:
I've actually had multiple cases in Objective-C code where this feature (some object behaving differently depending on wether or not a delegate method has been implemented) has prevented me from implementing features the easy and obvious way. In those cases I resorted to implementing 'respondsToSelector:'. So I'd argue that optional protocol methods encourage this type of behavior, which imho is bad API design. If you need to behave differently for some types of delegates (or whatever else your protocol represents), a separate method to call to determine how to behave is much simpler and better to use.
+1. This is exactly the same thing I mentioned regarding the fast path for row height in UITableView. The fact that it depends on whether or not the delegate implements heightForRowAtIndexPath is a bad design decision.
Yes, but please observe that the form of optional methods that we're discussing here is limited to avoid the case you mention (I hate that problem as well, very very much).