[swift-evolution] [Proposal draft] Remove objc requirement for optional protocol methods/properties

Douglas Gregor dgregor at apple.com
Sun Jan 10 22:56:09 CST 2016


> On Jan 10, 2016, at 1:31 AM, David Scrève via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi Chris,
> 
>> Le 10 janv. 2016 à 02:29, Chris Lattner <clattner at apple.com> a écrit :
>> 
>>> 
>> 
>> This is certainly a glaring hole in the system, and one we need to discuss.  Here are some problems with making optional requirements a first class thing in Swift:
>> 
>> 1. They overlap heavily (but are syntactically privileged) with optional properties, consider the difference between "optional func f() -> Int"  vs "var f : (() -> Int)?  {get}”.
> 	You are right. I suggest that we restrict optional keyword in protocol to methods only to fix this issue and keep the actual meaning.

That wasn’t Chris’s point. Compare

	protocol P {
	  optional func f() -> Int
	}

with

	protocol P {
	  var f: (() -> Int)? { get }
	}

	extension P {
	  var f: (() -> Int)? { return nil }
	}

Both will have the same “call-side” syntax, e.g., accessing the “f” member of something that conforms to “P” gives you a value of type “(() -> Int)?”. You can use ? to optionally call it like so:

	func testF<T : P>(t: T) {
	  let x = t.f?() // call “f’ if it is available.
	}



>> 
>> 2. Protocols with default implementations provide the vastly most common use-cases for these.
>> 
>> 3. They overload “optional” terminology in the language to mean something different.
>> 
>> 4. They are non-sensical - how can something be a requirement and be optional? :)
> 	Actually, optional methods allow to add methods to interface without breaking existing code and for me, conforming to protocol means « you can optionally implement this methods but you must implements others ». Conforming does not mean implements all feature but the protocol defines minimum requirements.

Although it’s not implemented now, one will be able to add new requirements to a protocol so long as those new requirements have a default implementation. The only thing “optional” requirements give you beyond default implementations is the ability to determine whether the requirement was fulfilled.

>> Doug has it on his plate to explore what we can do about this, in the Swift 3 timeframe, but not in the immediate future.  IMO, it would be really great if we could make Objective-C optional requirements disappear in the Clang importer, and transform them into requirements with a default implementation.
>> 
> 	I agree that default implementation seems to be the right solution but I’m afraid it introduces other problems with scope.
> 
> 	Consider the UITableViewDataSource protocol and the heightForRowAtIndexPath. The default implementation method uses UITableView internal properties and methods. Then, if we provide default implementation for this method in protocol, we will need to reference the called object in protocol.

Given the tight integration between UITableViewDataSource and UITableView, it is completely reasonable for the default implementation of a requirement in UITableViewDataSource to use internal methods of UITableView.

> 
> 	Actually, the default implementation may depend of the caller and can be different for each caller in the actual model. 
> 
> 	If you attach default implementation to protocol declaration, you will not be able to have caller specific default implementation and will have a basic and quite useless default implementation i.e. returning nil or invalid value.

If you need to distinguish between types that did or did not provide their own implementation, you can use a “nil” result or the property trick above.

> 	I thing this is a major issue because ObjC default implementation behavior is really powerful.

Given that we can get the same behavior in Swift without optional requirements, it’s not any more powerful… it’s just more convenient for those cases. So, the question is whether those cases are common enough—or the workarounds awful enough—to warrant having two very similar features in Swift.

> 	Java has introduced default implementation in interface and it create confusion between classes and interfaces and does not solve the issue I exposed below.

We already have default implementations for protocols (via extensions) as well as classes with implementation inheritance, so any related confusion is already there, so I don’t see how the comparison matters.

> 
> 	I think we should keep the actual model by limiting optional keyword to methods, which has really a meaning. 

I don’t see why you would limit it to methods. There are a number of optional properties in Cocoa[Touch], for example, and it “wrap the result in an extra level of optional” is a reasonable semantic approach here.

	- Doug



More information about the swift-evolution mailing list