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.

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to