[swift-evolution] [Idea] How to eliminate 'optional' protocol requirements

Brent Royal-Gordon brent at architechies.com
Mon Apr 11 04:55:40 CDT 2016

> And “optional” disappears from the language. Now, there’s no optionality left, so our useDelegate example tries to just do correct calls:
> func useDelegate(delegate: NSTableViewDelegate) -> NSView? {
>   let view = delegate.tableView(tableView, viewFor: column, row: row)
>   let height = delegate.tableView(tableView, heightOfRow: row)
> }
> Of course, the code above will fail if the actual delegate doesn’t implement both methods. We need some kind of default implementation to fall back on in that case. I propose that the code above produce a compiler error on both lines *unless* there is a “default implementation” visible. So, to make the code above compile without error, one would have to add:
> extension NSTableViewDelegate {
>   @nonobjc func tableView(_: NSTableView, viewFor: NSTableColumn, row: Int) -> NSView? { return nil }
>   @nonobjc func tableView(_: NSTableView, heightOfRow: Int) -> CGFloat { return 17 }
> } 

Okay, but NSTableViewDelegate is being imported from Objective-C. Suppose it doesn't ship with an extension that provides default values. What then? Are you unable to import AppKit? Do you have to write the extension yourself? (Even if you don't need it?)

And if you want to implement the exact semantics of `NSTableView`, including the fact that a table view whose delegate does not implement `tableView(_:heightOfRow:)` uses a fast path, what do you do?

* * *

Personally, I'm coming around to permitting optional methods in all types. Consider, for instance, WKWebView, which has a couple pairs like this:

	var canGoForward: Bool { get }
	func goForward()

You shouldn't be calling `goForward()` except on a WKWebView which `canGoForward`. So why are these pieces of information not conveyed together? Wouldn't it be better if WKWebView simply offered:

	optional func goForward()

And you couldn't call `goForward()` without checking or asserting that you're allowed to go forward at the moment?

Obviously that would require that you be able to *change* whether a given method was permitted or not based on circumstances. That would be a substantial expansion of the current `optional` feature, and overall, the whole thing simply doesn't seem important enough to prioritize.

But fundamentally, I don't think there's anything less coherent about saying "this member may not always exist" with an optional member than there is about saying "this property's value may not always exist" with an Optional value. "Subtypes may or may not support this thing, but if they do, this is what it'll look like" is a perfectly sensible thing to want from a type.

(Although we'll need to find a different name than "optional", that's for sure.)

Brent Royal-Gordon

More information about the swift-evolution mailing list