> On Apr 15, 2016, at 4:15 PM, Matthew Johnson <[email protected]> wrote:
>
>
>
> Sent from my iPad
>
> On Apr 15, 2016, at 6:03 PM, Douglas Gregor <[email protected]
> <mailto:[email protected]>> wrote:
>
>>
>>> On Apr 15, 2016, at 3:55 PM, Matthew Johnson <[email protected]
>>> <mailto:[email protected]>> wrote:
>>>
>>>
>>>> On Apr 13, 2016, at 11:42 AM, Douglas Gregor <[email protected]
>>>> <mailto:[email protected]>> wrote:
>>>>
>>>>>
>>>>> On Apr 11, 2016, at 10:30 AM, Matthew Johnson <[email protected]
>>>>> <mailto:[email protected]>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> Sent from my iPad
>>>>>
>>>>>> On Apr 11, 2016, at 12:15 PM, Joe Groff via swift-evolution
>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>
>>>>>>
>>>>>>> On Apr 7, 2016, at 5:12 PM, Douglas Gregor via swift-evolution
>>>>>>> <[email protected] <mailto:[email protected]>> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution