> On Apr 1, 2016, at 5:37 PM, Brent Royal-Gordon via swift-evolution > <swift-evolution@swift.org> wrote: > >> Protocol requirements with default (no-op) implementations already satisfy >> that design goal, no? > > Kind of. If I may steelman* optional members for a moment... > > In cases where a default implementation would do, the default implementation > will usually also be the behavior you want for a nil instance, but there's no > convenient way to share logic between the two. For example, consider this: > > protocol UITableViewDelegate { > ... > func tableView(_ tableView: UITableView, > heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat > } > extension UITableViewDelegate { > func tableView(_ tableView: UITableView, > heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { > return tableView.rowHeight > } > } > > class UITableView { > ... > private func addRow(at indexPath: NSIndexPath) { > ... > cell.size.height = delegate?.tableView(self, > heightForRowAtIndexPath: indexPath) ?? rowHeight > ... > } > ... > > You have to duplicate the default logic both in the default implementation > and at the call site, but there is no convenient way to share it—the > extension method can't call into an expression at some call site, and > contrarily the call site can't invoke the default logic from the extension.
Interesting point. > > If the method were optional, then optional chaining would solve this problem > for us: > > protocol UITableViewDelegate { > ... > optional func tableView(_ tableView: UITableView, > heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat > } > > class UITableView { > ... > private func addRow(at indexPath: NSIndexPath) { > ... > cell.size.height = delegate?.tableView?(self, > heightForRowAtIndexPath: indexPath) ?? rowHeight > ... > } > ... > > This way, there is only one source of default behavior: the call site. It’s “each" call site, not “the” call site. If there are multiple call sites, we’d presumably want to factor out the default behavior computation anyway. > I'm also concerned by the thought of just how many sub-protocols we might end > up with. When I try to fully factor NSTableViewDelegate (as it currently > exists in the headers), I end up with ten protocols: > > NSTableViewDelegate > - tableView:willDisplayCell:forTableColumn:row: > > NSTableViewLayoutDelegate: NSTableViewDelegate > - tableView:heightOfRow: > > NSTableViewRowSelectionDelegate: NSTableViewDelegate > - tableView:shouldSelectRow: > - selectionShouldChangeInTableView: > - tableViewSelectionIsChanging: > - tableViewSelectionDidChange: > - tableView:shouldTrackCell:forTableColumn:row: (10.5) > - tableView:selectionIndexesForProposedSelection: (10.5) > > NSTableViewTypeSelectDelegate: NSTableViewDelegate (10.5) > - tableView:typeSelectStringForTableColumn:row: > - tableView:nextTypeSelectMatchFromRow:toRow:forString: > - tableView:shouldTypeSelectForEvent:withCurrentSearchString: > > NSTableViewToolTipDelegate: NSTableViewDelegate > - tableView:toolTipForCell:rect:tableColumn:row:mouseLocation: > > NSTableViewColumnDelegate: NSTableViewDelegate > - tableView:shouldEditTableColumn:row: > - tableView:shouldSelectTableColumn: > - tableView:mouseDownInHeaderOfTableColumn: > - tableView:didClickTableColumn: > - tableView:didDragTableColumn: > - tableViewColumnDidMove: > - tableViewColumnDidResize: > - tableView:sizeToFitWidthOfColumn: (10.6) > - tableView:shouldReorderColumn:toColumn: (10.6) > > NSTableViewCellExpansionDelegate: NSTableViewDelegate (10.5) > - tableView:shouldShowCellExpansionForTableColumn:row: > > NSTableViewCustomCellDelegate: NSTableViewDelegate (10.5) > - tableView:dataCellForTableColumn:row: > - tableView:isGroupRow: > > NSTableViewCellViewDelegate: NSTableViewDelegate (10.7) > - tableView:viewForTableColumn:row: > > NSTableViewRowViewDelegate: NSTableViewDelegate (10.7) > - tableView:rowViewForRow: > - tableView:didAddRowView:forRow: > - tableView:didRemoveRowView:forRow: > - tableView:rowActionsForRow:edge: (10.11) > > Some of these are probably unnecessary; they could be merged into > NSTableViewDelegate and given default implementations. But at least a few of > them would be very much needed. Would users be able to navigate this mess? > Would they discover the features tucked away in sub-protocols? I'm just not > sure. This is what concerns me most. Delegate protocols tend to grow large over time (for good reason), and having a large family of related protocols is hard to navigate. - Doug _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution