[swift-evolution] Modify optional method semantics for swift

Carlos Rodríguez Domínguez carlos at everywaretech.es
Mon May 9 11:15:31 CDT 2016


Rationale:

As a everybody knows, “optional” keyword is present in swift solely to maintain compatibility with objective-c protocols. Optional methods in protocols are neither a swift capability, nor a wanted one. In fact, proposal [0070] intends to begin the transition to an optionals-free language. In fact, optionals, as presented by objective-c, are a manner to avoid interface segregation.

Nonetheless, in many occasions, optionals are used to model customized behavior vs default one. For instance, if you take a look at the documentation of UITableViewDataSource or delegate, you’ll see that optional methods are not required, since the framework provides a default behavior that can be customized by implementing the corresponding optional methods.

Consequently, is most cases, optional methods in objective-c are a means to replace the semantics of default protocol method implementations, as supported through extensions in swift.

Therefore, my proposal is to modify the semantics of “optional” keyword in swift to mean: “you must provide a default implementation of this method through an extension”. This is different from objective-c semantics, which mean “the implementation of this method may not be provided”.

Detailed design:

In this proposal, protocols could be defined like this:

protocol Datasource {
	associatedtype Element

	var count:Int {get}
	func elementAt(index:Int) -> Element
	optional func color(elementIndex:Int) -> UIColor
}

However, this definition enforces the developer to create an extension a provide a default implementation of the optional method:

extension Datasource {
	func color(elementIndex:Int) -> UIColor {
		return UIColor.blackColor()
	}
}

In this way, what we are achieving is that we are avoiding objective-c optional semantics (which is a way to avoid interface segregation), but we are making explicit that a method in a protocol requires a default implementation, thus not requiring the developer to re-implement the method in any entity adopting the protocol (as it currently happens when we provide a default method implementation). Moreover, we are making explicit that a certain protocol method has a default implementation, which can be confusing right now.

Note that in this proposal, the intention is to keep both "@objc optional” and simply “optional” keywords, to highlight both semantics. However, in order to avoid @objc optional semantics as much as possible (to be able to remove it in a future swift release), new annotations could be incorporated to optional methods in objective-c code, to specify the default returned value. For instance, the annotations could be like this:

@protocol Datasource
	-(NSInteger) numberOfElements;
	-(NSObject*) elementAtIndex:(NSInteger)index;

	@optional
	-(UIColor*) colorOfElementAtIndex:(NSInteger)index __attribute__((swift_default_value(“UIColor.blackColor()")));
@end

Note that this annotation also allows to better understand the default behavior in case the method is not implemented without reading the documentation. This annotation should produce a swift code similar to the above one.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160509/e3f70350/attachment.html>


More information about the swift-evolution mailing list