<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 11, 2016, at 2:29 PM, Radosław Pietruszewski <<a href="mailto:radexpl@gmail.com" class="">radexpl@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class="">On 11 Feb 2016, at 20:34, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Feb 11, 2016, at 2:33 AM, Radosław Pietruszewski via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class="">Hi everybody,<br class=""><br class="">Having looked at some examples, the API guidelines working group members<br class="">that were present this morning agreed we really want prepositions inside<br class="">the parentheses of method calls.</blockquote><br class=""></div><div class="">I find that… surprising.</div><div class=""><br class=""></div><div class="">Between these two (sorry to repeat the same example again):</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="">func trackWith(trackID trackID: CMPersistentTrackID) -> AVAssetTrack?</div><div class="">func track(withTrackID trackID: CMPersistentTrackID) -> AVAssetTrack?</div><div class=""><br class=""></div></blockquote>#1 seems nicer and clearer to me. Having “with” as the first word glued to a parameter label looks bizarre to my eyes:<div class=""><br class=""></div><div class="">As far as I understand it, the whole reason to keep “with” etc in many APIs was to make cases like this one clearer. Because “track” as a name doesn’t tell you much. Someone said that having the method name end with “With” creates a sense of suspense, and to me that was precisely what was a good thing about it. It’s not just “track”, it’s a “track with” — ooh, here come the criteria for the track! Having removed “with” from the name itself, we lose, IMHO, the clarity this word was supposed to bring in initializer/getter/finder-like methods. And we still keep the word later inside the parens, but to my eyes it no longer helps clarity, just exists as a vacuous, needless word.</div></div></div></blockquote></div></div></blockquote></div></div></div></blockquote><div><br class=""></div><div>*Personally*, I don’t find the “with” to be compelling in either case. Presumably, it is implying that this is a “find” rather than a “create” operation, but I don’t consider “with” a good way to communicate that… the optional result type and lack of a verb like “add” or “insert” implies “find” stronger than “with”, IMO.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><br class=""></div><div class="">Another reason I don’t like this, say we have:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>a.tracks(withMediaType: b, composer: c)</div><div class=""><br class=""></div><div class="">This no longer looks symmetrical across the parameters. First parameter has label “with”, second doesn’t. The previous version:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>a.tracksWith(mediaType: b, composer: c)</div><div class=""><br class=""></div><div class="">Didn’t have that problem.</div><div class=""><br class=""></div><div class="">I fear that people will take that as a signal that they should make the whole method, including parameter labels, sound like an English sentence and will start applying needless words like “and”:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>a.tracks(withMediaType: b, andComposer: c)</div><div class=""><br class=""></div><div class="">To avoid this weird-looking construct where the first parameter has a starting preposition, and other parameters don’t. Again:<br class=""><div class=""><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>a.tracksWith(mediaType: b, composer: c)</div><div class=""><br class=""></div><div class="">Doesn’t have this problem, because while the method name part ends with “With”, the parameters are consistently just nouns.</div><div class=""><br class=""></div><div class="">So -1 from me on this. Moving prepositions inside parens look like a step back from the Part DEUX Proposal.</div></div></div></div></div></blockquote></div></div></blockquote></div></div></div></blockquote><div><br class=""></div><div>When we were looking through the results, it seemed like cases where the preposition distributed to multiple arguments were fairly rare… rare enough that it didn’t seem worth complicating the rules or giving up the gains we got elsewhere from moving the prepositions inside.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><br class=""></div><div class="">Would you mind elaborating on the working group's rationale for moving prepositions inside parens?<br class=""></div></div></div></div></div></blockquote><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">A couple of reasons that I, personally, found motivating (some of which came up on this list before):</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""> (1) A prepositional phrase is a grammatical entity, and we probably shouldn’t split a grammatical phrase across ‘(‘.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""> (2) It seemed to separate “what the method does” (base name) from “how it does it” (argument label) more effectively.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""> (3) Related to (2), it pulled out more method families, where we had the same basic operation (described by the base name) and the argument labels differentiated how we got to that result.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">… and we spent a while looking at the diff of Cocoa, here:</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><a href="https://github.com/apple/swift-3-api-guidelines-review/commit/b22b62bb98e5d44b2528b237d18efe96bf2940d6" class="">https://github.com/apple/swift-3-api-guidelines-review/commit/b22b62bb98e5d44b2528b237d18efe96bf2940d6</a></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>- Doug</div></div></blockquote></div><br class=""><div class="">Thank you.</div><div class=""><br class=""></div><div class="">I’d love to see a response from the team as for my concerns in the post above — I wonder if the arguments were not compelling because I’ve missed something, or simply that the rationale _for_ prepositions inside the parens seemed stronger.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class=""> (1) A prepositional phrase is a grammatical entity, and we probably shouldn’t split a grammatical phrase across ‘(‘.</div></blockquote><br class=""></div><div class="">A fair point — I guess I just don’t find it as important. Either way, it’s not an English sentence, only English-like.</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class=""> (3) Related to (2), it pulled out more method families, where we had the same basic operation (described by the base name) and the argument labels differentiated how we got to that result.</div></blockquote></div><div class=""><div class=""><br class=""></div></div><div class="">Any examples? How was that different from having a preposition just before the paren?</div></div></div></blockquote><div><br class=""></div><div>Here’s a fun set of examples from NSGradient:</div><div><br class=""></div><div><div> - func drawFrom(startingPoint: Point, to endingPoint: Point, options: NSGradientDrawingOptions)</div><div> - func drawIn(rect: Rect, angle: CGFloat)</div><div> - func drawIn(path: NSBezierPath, angle: CGFloat)</div><div> + func draw(from startingPoint: Point, to endingPoint: Point, options: NSGradientDrawingOptions)</div><div> + func draw(in rect: Rect, angle: CGFloat)</div><div> + func draw(in path: NSBezierPath, angle: CGFloat)</div><div> func drawFromCenter(startCenter: Point, radius startRadius: CGFloat, toCenter endCenter: Point, radius endRadius: CGFloat, options: NSGradientDrawingOptions)</div><div> - func drawIn(rect: Rect, relativeCenterPosition: Point)</div><div> - func drawIn(path: NSBezierPath, relativeCenterPosition: Point)</div><div> + func draw(in rect: Rect, relativeCenterPosition: Point)</div><div> + func draw(in path: NSBezierPath, relativeCenterPosition: Point)</div><div class=""><br class=""></div></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">* * *</div><div class=""><br class=""></div><div class="">I’ve given the diff a look again, and I can now see how some methods look really nice after the change, and only some make me slightly uncomfortable.</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">func value(at index: Int) -> AnyObject!</div><div class="">func read(from url: URL, options: ….)</div><div class="">class func strokeLine(from point1: Point, to point2: Point)</div><div class="">func appendWithOval(in rect: Rect)</div><div class="">func sendAction(on mask: Int) -> Int</div><div class="">func rows(in rect: Rect) -> NSRange</div><div class="">func translateOrigin(to translation: Point)</div></blockquote><div class=""><br class=""></div><div class="">I actually like those a lot! There’s no need to repeat parameter name/type information in argument label, because it’s going to be obvious in context on call site. But having a preposition, just alone by itself, actually is a nice thing in explaining the first argument and the method semantics.</div><div class=""><br class=""></div><div class="">What I’m not so sure about is when the preposition is glued to a noun. And I guess it’s largely because the noun seems to repeat type information that’s not needed for clarity at call site:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func accessibilityFrame(forRange range: NSRange) -> Rect</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func fractionOfDistanceThroughGlyph(forPoint aPoint: Point) -> CGFloat</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func borderColor(forEdge edge: RectEdge) -> NSColor?</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func value(forDimension dimension: NSTextBlockDimension) -> CGFloat</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func cellFrame(forTextContainer textContainer: NSTextContainer, proposedLineFragment lineFrag: Rect, glyphPosition position: Point, characterIndex charIndex: Int) -> Rect</div><div class=""><br class=""></div><div class="">Why are here the nouns not trimmed like in the examples above?</div></div></div></blockquote><div><br class=""></div><div>I had a ban on creating “vacuous” argument labels from long ago. It didn’t kick in much before, but I removed it in the follow-up commit to what you’re looking at:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span><a href="https://github.com/apple/swift-3-api-guidelines-review/commit/aaec8d0fe9cf82cd6f4088721cf8968a6ac69164" class="">https://github.com/apple/swift-3-api-guidelines-review/commit/aaec8d0fe9cf82cd6f4088721cf8968a6ac69164</a></div><div><br class=""></div><div>Essentially, all of those examples above end up with the argument label “for”.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">I think:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>accessibilityFrame(for: someRange)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>fractionOfDistanceThroughGlyph(for: somePoint)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>borderColor(for: edge)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>value(for: someTextBlockDimension)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>cellFrame(for: someTextContainer, …)</div><div class=""><br class=""></div><div class="">Would also work. No?</div></div></div></blockquote><div><br class=""></div>Yep, the next commit ;)</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">In other cases, I’m bothered by the preposition glued to an argument label, because the preposition seems unnecessary:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func copy(withZone zone: Zone = nil) -> AnyObject</div></div></div></blockquote><div><br class=""></div><div>Here, I feel like we need *a* label because we aren’t copying the first argument… we’re copying “self” and using the first argument. The second commit I referenced above would make this just “with”; I, personally, would prefer “coder” or something meaningful like “into”.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>optional func shouldPerformSegue(withIdentifier identifier: String, sender: AnyObject?) -> Bool</div><span class="Apple-tab-span" style="white-space:pre">        </span>func statusItem(withLength length: CGFloat) -> NSStatusItem<div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func instantiateController(withIdentifier identifier: String) -> AnyObject<br class=""></div></div></div></blockquote><div><br class=""></div><div>The “with”s don’t seem to add anything here.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>func performClickOnCell(atColumn column: Int, row: Int)</div><div class=""><br class=""><div class="">I guess this is mostly a problem with “with”s. The last example is more arguable — what bothers me there more is the inconsistent treatment of argument labels (first label starts with a preposition that conveys semantics for both parameters, and the second label is just a parameter name).</div></div></div></div></blockquote><br class=""></div><div>Here, the “at” distributes, but it’s also not needed for clarity. We’d be find with either</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>func performClickOnCellAt(column: Int, row: Int)</div><div><br class=""></div><div>or </div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>func performClickOnCell(column: Int, row: Int)</div><div><br class=""></div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><br class=""></body></html>