<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 24, 2016, at 5:57 PM, Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class="">on Sat Jan 23 2016, plx &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">On Jan 23, 2016, at 2:33 PM, Dave Abrahams via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><br class="">on Sat Jan 23 2016, plx<br class=""></blockquote><br class=""><blockquote type="cite" class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>&gt;&gt; wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">On Jan 22, 2016, at 6:12 PM, Ross O'Brien via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">How would we apply this to delegate patterns?<br class="">For example, would we keep<br class="">tableview(tableView:cellForRowAtIndexPath:), or would we switch to<br class="">delegate(tableView:cellForRowAtIndexPath:) ?<br class="">Or perhaps better, for clarity over which protocol is being<br class="">conformed to / which property of the delegator is calling the<br class="">function:<br class="">dataSource(tableView:cellForRowAtIndexPath:),<br class="">delegate(tableView:didSelectRowAtIndexPath:)<br class=""></blockquote><br class="">FWIW, I am personally favorable to a more radical-renaming for delegate methods, roughly the below:<br class=""><br class="">func numberOfSections(inTableView tableView: UITableView) -&gt; Int // &lt;- against guidelines, but symmetric<br class="">func numberOfRows(inTableView tableView: UITableView, forSection section: Int) -&gt; Int<br class="">func cellForRow(inTableView tableView: UITableView, atIndexPath indexPath: NSIndexPath) -&gt; UITableView<br class=""></blockquote><br class="">The interesting thing about delegate methods is that, for the most part,<br class="">use-sites don't appear in user code. &nbsp;So *if* you're going to come up with<br class="">special conventions just for delegate methods you'd want to serve the<br class="">declaration site. &nbsp;I don't know what these things *ought* to look like,<br class="">but the declarations above look to me like they've got an awful lot of<br class="">redundancy that doesn't help readability.<br class=""></blockquote><br class="">Most of what follows should really be in the discussion about the<br class="">Objective-C import, not here, but I’ll respond here with the parts<br class="">relevant to the guidelines.<br class=""><br class="">It seems self-evident that imported delegate methods violate the<br class="">spirit of Swift’s API guidelines; in particular, the rule that<br class="">“Methods can share a base name when they share the same basic meaning<br class="">but operate on different types, or are in different domains” seems<br class="">relevant. <br class=""></blockquote><br class="">That's quite true.<br class=""><br class=""><blockquote type="cite" class="">It’s thus been a bit surprising to me that delegate-style methods<br class="">haven’t *already* gotten some special treatment; <br class=""></blockquote><br class="">Well, it's a fact of life that major efforts like this one (probably<br class="">property behaviors are the same bucket) are going to have to land<br class="">without solving all the problems they are related to. &nbsp;I believe<br class="">strongly that we should do *something* about delegate methods. &nbsp;I also<br class="">believe they're a separable problem and we should be able to evaluate<br class="">the current direction without working out all the details of how we're<br class="">going to handle them. &nbsp;That's why I changed the subject line: I'd like<br class="">to agree that special treatment for delegate methods in the importer is<br class="">out-of-scope in this review.<br class=""><br class=""><blockquote type="cite" class="">what I had isn’t great, but put it and some variants up against the<br class="">original, like so:<br class=""><br class="">func numberOfRows(in tableView: UITableView, forSection section: Int) -&gt; Int<br class="">func numberOfRowsIn(tableView: UITableView, forSection section: Int) -&gt; Int<br class="">func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int<br class="">func numberOfRows(inTableView tableView: UITableView, forSection section: Int) -&gt; Int<br class=""></blockquote><br class="">I assume you mean the 3rd one to be "the original?”</div></div></blockquote><div><br class=""></div><div>Yes, here:&nbsp;<a href="https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/#//apple_ref/occ/intfm/UITableViewDataSource/tableView:numberOfRowsInSection:" class="">tableView(_:numberOfRowsInSection:)</a></div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">…(note the longest is only ~10 characters longer than the shortest!). <br class=""></blockquote><br class="">Sorry, I don't see why that is relevant. &nbsp;Care to explain?<br class=""></div></div></blockquote><div><br class=""></div><div>I did not make the intention clear; apologies. I was intending to illustrate that although all of the examples contain redundancies, none of them are egregiously worse than the others (including the original); the worst case is only moderately more-redundant than the best case.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">Although there might be an as-yet unseen option that’s superior to all<br class="">of the above, just out of those 4 it’s hard to see how you can justify<br class="">option #3 using the API guidelines; <br class="">it also seems hard to envision a self-consistent expansion of the<br class="">guidelines that’d lead to favoring #3.<br class=""></blockquote><br class="">You can't.<br class=""><br class=""><blockquote type="cite" class="">As already noted this is really more-relevant to the “objective-c<br class="">import revision”, but you can frame my points as obliquely asking “to<br class="">what extent should the Swift API guidelines actually matter when doing<br class="">the big Objective-C import?”<br class=""></blockquote><br class="">We're willing to accept that some imported APIs will not follow the<br class="">guidelines.<br class=""><br class=""><blockquote type="cite" class="">I also question your sense of real-world use of delegate protocols;<br class="">just taking inventory of the most recent project I completed, it looks<br class="">like it had 5 custom delegate-style protocols. Of these, 4 had exactly<br class="">one implementation each, and 1 had exactly 2 implementations; <br class=""></blockquote><br class="">And how many use-sites were there?<br class=""></div></div></blockquote><div><br class=""></div><div>5, just counting “classes using said delegates”; 14 if you go by individual method use.&nbsp;</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">I don’t think this is that untypical. If you accept it as not too<br class="">atypical,<br class=""></blockquote><br class="">I do.<br class=""><br class=""><blockquote type="cite" class="">it suggests a more uniform balance between defining a delegate<br class="">protocol, using said protocol, and implementing said protocol.<br class=""></blockquote><br class="">Not necessarily. &nbsp;How many times did this project implement delegate<br class="">protocols that were defined elsewhere? &nbsp;<br class=""></div></div></blockquote><div><br class=""></div><div>Looks like 12, for implementations; “a lot”, going by by the method count.</div><div><br class=""></div><div>In any case I don’t dispute the general point, just perhaps the exit.</div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class="">In any case, for what it's worth, I personally think the direction<br class="">you're going with those delegate APIs is great, and it has the benefit<br class="">of bringing them into conformance with other guidelines. &nbsp;My only point<br class="">in saying that the declaration site is more important with delegate<br class="">methods than with others is that there's more type information at the<br class="">declaration site of a method than at its use site, so there's definitely<br class="">no reason to make them more verbose than others. &nbsp;Making them simply<br class="">follow the existing guidelines exactly is a simple solution that IMO<br class="">leads to good code, and one I would support.<br class=""><br class="">However, what Cocoa guys like Tony Parker say about the eventual<br class="">direction of delegate APIs should probably carry a lot more weight than<br class="">what I say.<br class=""><br class=""><blockquote type="cite" class="">To wind this digression down now, the API guidelines’ attitude towards<br class="">redundancy seems somewhat troubling; no one wants needless redundancy,<br class="">but natural languages tend towards redundancy (cf<br class="">agreement/pleonasm/etc) and it’s not at all self-evident that less<br class="">redundancy always implies increased readability (which you may or may<br class="">not be intending to imply; I can’t tell)…especially when it’s easy to<br class="">get fooled by increased speed-of-reading.<br class=""></blockquote><br class="">This seems like a pretty vague concern. &nbsp;Let's see concrete examples of<br class="">problems you think the guidelines' attitude toward redundancy will<br class="">cause. &nbsp;FWIW, "omit needless words" isn't something we just came<br class="">up with ourselves: it's a time-honored principle of clear English<br class="">writing (google it).<br class=""></div></div></blockquote><div><br class=""></div><div>Sure, sure, but if you’ll forgive a cheap shot I’d point out Strunk would’ve tut-tutted here and suggested, perhaps, “we didn’t invent ‘omit needless words’”. The tricky part of that rule is that what’s needless is highly contextual, and to be *understood* when writing in a highly-condensed style usually requires a large amount of shared context.</div><div><br class=""></div><div>Which need-for-context is at the root of my admittedly-vague concern; I’ve done my best to come up with a concrete-ish example, but it’s a bit contrived and not as strong as I’d like, either. It’s more of an "ecosystem concern”, too.</div><div><br class=""></div><div>Here are *six* functions that could conceivably be named `min` under the guidelines:</div><div><br class=""></div><div>func min() -&gt; Generator.Element? // obviously only where `Generator.Element` is `Comparable`</div><div>func min(isLessThan comparator: (Generator.Element,Generator.Element) -&gt; Bool) -&gt; Generator.Element?</div><div><div>func&nbsp;min&lt;K:Comparable&gt;(extractor: (Generator.Element) -&gt; K) -&gt; K?</div><div><div>func&nbsp;min&lt;K:Comparable&gt;(extractor: (Generator.Element) -&gt; K?) -&gt; K?</div><div></div><div>func min&lt;T&gt;(extractor: (Generator.Element) -&gt; T, isLessThan comparator: (T,T) -&gt; Bool) -&gt; T?</div><div class=""><div>func min&lt;T&gt;(extractor: (Generator.Element) -&gt; T?, isLessThan comparator: (T,T) -&gt; Bool) -&gt; T?</div><div><div class=""><br class=""></div><div class="">…and perhaps they *all* should be named `min` (and we simply let context and type information sort it all out for us).</div><div class=""><br class=""></div><div class="">But if the names should be different, what’re good choices?</div><div class=""><br class=""></div><div class="">My vague concern is that having “maximally-terse” names for the standard library functions makes it trickier to choose "non-misleading” names for such closely-related variants.</div><div class=""><br class=""></div><div class="">EG: if you go with `minValue` for the variants, to a casual reader there’s room for confusion vis-a-vis `min` (I suspect many would initially guess that `minValue` does what `minElement` does today, but would guess the behavior correctly if given a choice between `minElement` and `minValue`).</div><div class=""><br class=""></div><div class="">Unfortunately for my case, I think `minFor` is a perfectly-reasonable choice here, which undermines my concrete example (I warned you the case wasn’t going to be very convincing).</div><div class=""><br class=""></div><div class="">But that’s the kind of vague concern I have here: that a “maximally-terse” naming convention can be harder to extend in a way that’s both self-consistent and not-potentially-misleading.&nbsp;</div><div class=""><br class=""></div><div class="">But I don’t have a great suggestion for an additional guideline, and there may be nothing serious to worry about here, either.</div><div class=""><br class=""></div></div></div></div></div><blockquote type="cite" class=""><div class=""><div class=""><br class=""><br class="">-- <br class="">-Dave<br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></body></html>