<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 Feb 3, 2016, at 1:10 PM, Jonathan Tang &lt;<a href="mailto:jonathan.d.tang@gmail.com" class="">jonathan.d.tang@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Feb 3, 2016 at 9:44 AM, Douglas Gregor <span dir="ltr" class="">&lt;<a href="mailto:dgregor@apple.com" target="_blank" class="">dgregor@apple.com</a>&gt;</span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><blockquote type="cite" class=""><span class=""><div class="">On Feb 2, 2016, at 10:17 PM, Jonathan Tang via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class=""></span><div class=""><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" class=""><div class="gmail_extra"><br class=""><br class=""><div class="gmail_quote"><span class="">On Tue, Feb 2, 2016 at 4:32 PM, Dave Abrahams via swift-evolution<span class="">&nbsp;</span><span dir="ltr" class="">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>&gt;</span><span class="">&nbsp;</span>wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br class=""></blockquote></span><div class=""><div class="h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">2. Words that describe attributes of an *already-existing* instance<br class="">&nbsp; &nbsp;should go in the base name rather than in a label:<br class=""><br class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>a.tracksHavingMediaType("Wax Cylinder")&nbsp; &nbsp; &nbsp; // yes<br class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>a.removeFirstTrackHavingMediaType("BetaMax") // yes<br class=""><br class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>a.tracks(mediaType: "Wax Cylinder")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // no<br class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>a.removeFirstTrack(havingMediaType: "BetaMax") // no<br class=""><br class="">&nbsp; &nbsp;[yes, we could use "With" instead of "Having", but it's more<br class="">&nbsp; &nbsp;ambiguous]<br class=""><br class="">&nbsp; &nbsp;Words that describe attributes of an instance *to be created* should<br class="">&nbsp; &nbsp;go in argument labels, rather than the base name (for parity with<br class="">&nbsp; &nbsp;initializers):<br class=""><br class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>AudioTrack(mediaType: "BetaMax")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// initializer<br class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>trackFactory.newTrack(mediaType: "Wax Cylinder")&nbsp; &nbsp;// yes<br class=""><br class="">&nbsp; &nbsp; &nbsp;<span class="">&nbsp;</span>trackFactory.newTrackWithMediaType("Wax Cylinder") // no<br class=""><br class=""></blockquote><div class=""><br class=""></div><div class="">Very mixed feelings on this, probably adding up to a +0.2 or so.&nbsp; I'll mention a couple concerns that I haven't seen anyone raise:</div><div class=""><br class=""></div><div class="">Please consider the first-class function case when naming.&nbsp; Particularly since Swift encourages passing functions around as objects rather than using string selectors. &nbsp;#2 implies that the prepositional phrase will appear when *referencing* the method (vs. calling it):</div><div class=""><br class=""></div><div class="">&nbsp; let ops = [</div><div class="">&nbsp; &nbsp; self.removeFirstTrackHavingMediaType,</div><div class="">&nbsp; &nbsp; self.addTrackWithMediaType</div><div class="">&nbsp; &nbsp; self.populateTrackOperationsForMediaType</div><div class="">&nbsp; &nbsp; self.play</div><div class="">&nbsp; ]</div><div class=""><br class=""></div><div class="">vs.</div><div class=""><br class=""></div><div class="">&nbsp; let ops = [</div><div class="">&nbsp; &nbsp; self.removeFirstTrack</div><div class="">&nbsp; &nbsp; self.addTrack</div><div class="">&nbsp; &nbsp; self.populateTrackOperations</div><div class="">&nbsp; &nbsp; self.play</div><div class="">&nbsp; ]</div><div class=""><br class=""></div><div class="">The second option wins on verbosity, but the first arguably gives more clarity as to what the methods actually do.&nbsp; Also, the second has a potentially annoying semantic problem: if you have overloads for these methods that differ only in keyword, Swift won't be able to disambiguate them:</div><div class=""><br class=""></div><div class="">&nbsp; // Compile error: Invalid redeclaration of removeFirstTrack</div><div class="">&nbsp; func removeFirstTrack(havingMediaType: String) { ... }</div><div class="">&nbsp; func removeFirstTrack(named: String) { ... }</div><div class="">&nbsp; func removeFirstTrack(byArtist: String) { ... }</div><div class=""><div class=""><br class="">&nbsp; // Compile error only when the function is referenced</div><div class="">&nbsp; func removeTrack(n: Int, named: String)</div><div class="">&nbsp; func removeTrack(n: Int, byArtist: String)</div><div class="">&nbsp; let f = self.removeTrack &nbsp; // named: or byArtist:?</div></div><div class=""><br class=""></div><div class="">&nbsp; // Legal...</div><div class="">&nbsp; func removeFirstTrackHavingMediaType(_: String) { ... }</div><div class="">&nbsp; func removeFirstTrackNamed(_: String) { ... }</div><div class="">&nbsp; func removeFirstTrackByArtist(_: String) { ... }</div><div class=""><br class=""></div><div class="">Unless the Swift compiler were to change to make the former set legal, I think this is a powerful argument in favor of this proposal, because otherwise you may find that the compiler prevents you from writing the code that the guidelines encourage.&nbsp; You might also find that changing the type of an overload means you have to change the name to prevent a collision, which could be very surprising to users.</div></div></div></div></div></div></div></blockquote><br class=""></div><div class="">I suspect that you missed SE-0021:</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md" target="_blank" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md</a></div><div class=""><br class=""></div><div class="">which lets you name the arguments in a function reference, e.g:</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span>let f = self.removeTrack(_:named:)</div><div class=""><div class=""><span style="white-space:pre-wrap" class="">        </span>let f2 = self.removeTrack(_:byArtist:)</div><div class=""><br class=""></div><div class=""><span style="white-space:pre-wrap" class="">        </span>let ops = [</div><div class=""><span style="white-space:pre-wrap" class="">        </span>&nbsp; self.removeFirstTrack(mediaType:),</div><div class=""><span style="white-space:pre-wrap" class="">        </span>&nbsp; self.addTrack(mediaType:),</div><div class=""><span style="white-space:pre-wrap" class="">        </span>&nbsp; self.populateTrackOperationsForMediaType,</div><div class=""><span style="white-space:pre-wrap" class="">        </span>&nbsp; self.play</div><div class=""><span style="white-space:pre-wrap" class="">        </span>]</div><div class=""><span style="white-space:pre-wrap" class="">        </span></div></div><div class=""><span style="white-space:pre-wrap" class="">        </span>- Doug</div><div class=""><br class=""></div><br class=""></div></blockquote></div><br class=""></div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">There's still no outstanding proposal to that lets you disambiguate functions only by the first argument at the point of definition, right?</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">&nbsp; class C {</div><div class="gmail_extra">&nbsp; &nbsp; // Still a compiler error: "Invalid redeclaration of doSomething"</div><div class="gmail_extra"><span class="">&nbsp; &nbsp;&nbsp;</span><span class="">func</span><span class=""> doSomething(withBar: </span><span class="">String</span><span class="">) -&gt; </span><span class="">String</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">"Bar</span><span class="">\</span><span class="">(</span><span class="">withBar</span><span class="">)"</span><span class=""> }</span></div><div class="gmail_extra"><span class="">&nbsp; &nbsp;&nbsp;</span><span class="">func</span><span class=""> doSomething(withFoo: </span><span class="">String</span><span class="">) -&gt; </span><span class="">String</span><span class=""> { </span><span class="">return</span><span class=""> </span><span class="">"Foo</span><span class="">\</span><span class="">(</span><span class="">withFoo</span><span class="">)"</span><span class=""> }</span></div><div class="gmail_extra">&nbsp; }</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">Without this, I think there's still a big problem with moving the preposition to the first argument label, because it leads to recommended names that don't compile.</div></div></div></blockquote><div><br class=""></div><div>You’re tripping over the default behavior. If you want two different functions, doSomething(withBar:) and doSomething(withFoo:), then you need to specifically provide an argument label for each:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>class C {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&nbsp; func doSomething(withBar bar: String) -&gt; String { return “Bar\(withBar)” }</div><span class="Apple-tab-span" style="white-space: pre;">        </span>&nbsp; func doSomething(withFoo foo: String) -&gt; String { return “Foo\(withFoo)” }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class="">Per SE-0021, you can reference these with “C.doSomething(withBar:)” and “C.doSomething(withFoo:)”, respectively.</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra">With SE-0021 and the ability to define overloads that differ only in the first-arg label (they'd have to be called or referenced with the label, otherwise you'd get a compiler error at point of use) I think I'd move to about -0.5 on proposal #2, because:</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">1. Moving the preposition to the first argument adds brevity in the common case where there is no overload conflict.</div><div class="gmail_extra">2. You can still disambiguate or add clarity at the point of reference by including all the argument labels</div><div class="gmail_extra">3. It's more uniform with how you'd reference multi-arg functions.</div></div>
</div></blockquote><div class=""><br class=""></div><div class="">Given the above clarification, does this opinion still hold?</div></div><div class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div><br class=""></div><br class=""></body></html>