> On Apr 15, 2016, at 4:15 PM, Matthew Johnson <matt...@anandabits.com> wrote: > > > > Sent from my iPad > > On Apr 15, 2016, at 6:03 PM, Douglas Gregor <dgre...@apple.com > <mailto:dgre...@apple.com>> wrote: > >> >>> On Apr 15, 2016, at 3:55 PM, Matthew Johnson <matt...@anandabits.com >>> <mailto:matt...@anandabits.com>> wrote: >>> >>> >>>> On Apr 13, 2016, at 11:42 AM, Douglas Gregor <dgre...@apple.com >>>> <mailto:dgre...@apple.com>> wrote: >>>> >>>>> >>>>> On Apr 11, 2016, at 10:30 AM, Matthew Johnson <matt...@anandabits.com >>>>> <mailto:matt...@anandabits.com>> wrote: >>>>> >>>>> >>>>> >>>>> Sent from my iPad >>>>> >>>>>> On Apr 11, 2016, at 12:15 PM, Joe Groff via swift-evolution >>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>>> >>>>>> >>>>>>> On Apr 7, 2016, at 5:12 PM, Douglas Gregor via swift-evolution >>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>>>> >>>>>>> One could perhaps work around (a), (b), and (d) by allowing compound >>>>>>> (function-like) names like tableView(_:viewFor:row:) for properties, >>>>>>> and work around (c) by allowing a method to satisfy the requirement for >>>>>>> a read-only property, but at this point you’ve invented more language >>>>>>> hacks than the existing @objc-only optional requirements. So, I don’t >>>>>>> think there is a solution here. >>>>>> >>>>>> To me, compound names for closure properties and satisfying property >>>>>> requirements with methods aren't hacks, they're missing features we >>>>>> ought to support anyway. I strongly prefer implementing those over your >>>>>> proposed solution. It sounds to me like a lot of people using optional >>>>>> protocol requirements *want* the locality of control flow visible in the >>>>>> caller, for optimization or other purposes, and your proposed solution >>>>>> makes this incredibly obscure and magical. >>>>> >>>>> Do you have the same thought for optional closure properties? If so and >>>>> heightForRow was an optional closure property it would satisfy all use >>>>> cases elegantly. It could have a default implementation that returns >>>>> nil. When non-uniform heights are required a normal method >>>>> implementation can be provided. Delegates that have uniform row heights >>>>> some of the time, but not all of the time, would also be supported by >>>>> implementing the property. >>>> >>>> There are still some issues here: >>>> >>>> 1) It doesn’t handle optional read/write properties at all, because the >>>> setter signature would be different. Perhaps some future lens design would >>>> make this possible. For now, the workaround would have to be importing the >>>> setter as a second optional closure property, I guess. (The current system >>>> is similarly broken). >>> >>> I was only thinking about methods, not properties. :) How common are >>> optional, writeable property requirements? I don’t have a good guess off >>> the top of my head, but my hunch is that they are not that common. >> >> They are *very* rare. Aside from UITextInputTraits >> <https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/>, >> I see three in OS X and four in iOS. >> >>>> 2) For an @objc protocol, you won’t actually be able to fully implement >>>> the optional closure property with a property of optional type, because >>>> “return nil” in the getter is not the same as “-respondsToSelector: >>>> returns false”. Indeed, the getter result type/setter parameter type >>>> should be non-optional, so we would (at best) need a special rule that >>>> optional closure properties of @objc protocols can only be implemented by >>>> non-optional properties of closure type or by methods. >>> >>> This is related to why I asked about feasibility. I know that “return nil” >>> is not that same as a “respondsToSelector:” implementation that returns >>> false if the property was implemented to return nil. Some magic would need >>> to handle that translation to make it work with existing Objective-C >>> protocols. This would automate what I have done in Objective-C several >>> times by implementing respondsToSelector manually to hide protocol method >>> implementations when necessary. >>> >>> The advantage of going this route is that Swift implementations of the >>> legacy Cocoa protocols will still function as expected in Cocoa while >>> fitting the Swift model much better than optional protocol requirements. >> >> Both Joe’s suggestion and my proposal need hackery to do the right thing for >> Objective-C interoperability, and both are feasible. I feel like my proposal >> is more honest about the hackery going on :) > > Hmm. I agree that it's a little bit of hackers, but I don't think it's > really dishonest to translate "return nil" into "respondsToSelector:" false > and more than it is to make any other mapping from one system to another. > > The main reason I prefer that approach is that it enables functionality that > has been occasionally useful in Objective-C and is not otherwise possible in > Swift - namely the ability to implement the protocol in a general purpose > class and make a decision at initialization time whether you need a > particular feature (such as dynamic row sizing) or not. Your approach > doesn't allow for this.
My approach requires you to use a different design—either split into multiple protocols (which is probably the best answer in most of these cases) or introduce a different kind of API contract. My claim is that these solutions are more natural in Swift than “check if a particular requirement was actually implemented”. - Doug
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution