<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"><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=""><div class="">Ooookay, this thread took *a while* to go through. Phew!</div><div class=""><br class=""></div><div class="">Echoing from my reviews of SE-0005 and SE-0006:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">I’m overwhelmingly *for* this proposal. I think removing needless verbosity and keeping the signal-to-noise ratio high is one of the most immediately appealing aspects of Swift, as well as a great general improvement to the programming experience.</blockquote><br class=""></div><div class="">And these guidelines do a great job at this. Like Paul Cantrell said, they recognize that both verbosity and brevity endanger clarity of code, and present many formalized rules to try to strike a balance in between, and keep S/N high. Both by reminding writers (yes, software writers!) to be explicit when it’s important, and by getting rid of noise that conveys little to no information, especially in a statically-typed language.</div><div class=""><br class=""></div><div class="">Although the API Design Guidelines sometimes err slightly more on the side of explicitness than me, I’m +1 aside from some concerns below:</div><div class=""><br class=""></div><div class="">* * *</div><div class=""><br class=""></div><div class="">=&nbsp;Prefer to follow the language’s defaults for the presence of argument labels =</div><div class=""><br class=""></div><div class="">This has been extensively discussed in this thread, by Erica, Paul, Dave, and others, so apologies if I repeat arguments already made, but:</div><div class=""><br class=""></div><div class="">I think there are more use cases where it makes sense to make the first argument label explicit than the guidelines consider.</div><div class=""><br class=""></div><div class="">The way I see it, most of the time, the method name, its fundamental job describes the first parameter, or makes it obvious. And so, the default behavior of Swift, and the general guideline are correct. However, there are cases, where this isn’t so.</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;addObserver(foo)</div><div class=""><br class=""></div><div class="">Here, the method name says what first argument it takes right on the box. And `add(observer: …)` wouldn’t be appropriate, because this isn’t some general, generic “add”. The method adds an observer in particular. It’s fundamentally what it does, so it goes on the name.</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;array.contains(“foo”)</div><div class=""><br class=""></div><div class="">This doesn’t describe the parameter explicitly, but the parameter is obvious, and makes something of a “sentence”. No label needed.</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;login(username: “foo", password: “bar")</div><div class=""><br class=""></div><div class="">Here, “username” should _not_ be part of the name, because it doesn’t describe the fundamental job of the method. The method logs you in. Username is just a parameter.</div><div class=""><br class=""></div><div class="">One way to think about it, as Erica pointed out, is that the parameters are bound more strongly together than “username” is to the name. Another way to think about it, it would be completely natural to make the parameters a standalone tuple or a separate type:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;let credentials = (username: “foo”, password: “bar”)</div><div class="">&nbsp; &nbsp;login(credentials)</div><div class="">&nbsp; &nbsp;// or:</div><div class="">&nbsp; &nbsp;login(LoginPair(username: “foo”, password: “bar”))</div><div class=""><br class=""></div><div class="">Another way in which it makes sense, and again this was pointed out, is that if you have multiple ways of logging in, it’s still logging in:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;login(username: “foo”, password: “bar”)</div><div class="">&nbsp; &nbsp;login(token: “asdfg”)</div><div class=""><br class=""></div><div class="">Making the names “loginWithUsername” and “loginWithToken”:</div><div class=""><br class=""></div><div class="">- looks weird if you’re not used to Objective-C</div><div class="">- is unnecessarily verbose (tiny thing, but “with” conveys zero information, so I’d prefer to rely on Swift’s punctuation and make it an explicit parameter label)</div><div class="">- makes it seem as if the two methods were fundamentally different things, and they’re not. They’re two variants of the same method, so they should have a common name, and different parameters.</div><div class=""><br class=""></div><div class="">More examples:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;moveTo(x: Double, y: Double)</div><div class=""><br class=""></div><div class="">This passes multiple of the previous tests. “x” is a parameter, has nothing to do with the method itself. It could just as well be a tuple or a separate type. And if you had a different way of passing the position data, you’d still want the same name.</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;constructColor(red: 0.2, green: 0.3, blue: 0.1)</div><div class=""><br class=""></div><div class="">Same thing.</div><div class=""><br class=""></div><div class="">An example from SE-0005 I proposed:&nbsp;<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/007658.html" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/007658.html</a>&nbsp;</div><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class="">   func fill(blendMode: CGBlendMode, alpha: CGFloat)
   func stroke(blendMode: CGBlendMode, alpha: CGFloat)
   func encode(coder: Coder)</pre><div class="">Copying and pasting what I said in that thread:</div></div><div class=""><br class=""></div><div class=""><pre style="white-space: pre-wrap; background-color: rgb(255, 255, 255);" class=""><blockquote type="cite" class="">Again, the method, the action itself (“fill”, “stroke”, “encode”) doesn’t naturally describe the first parameter in a way “insert” on a collection, or “addObserver” would. The blend mode and coder values here are merely _options_ of the method, not its _fundamental job_.

One way to conceptualize the difference is to think of arguments as being either “inputs” or “options”. A passed element to be inserted to a collection is an input, but blend mode is only an option of a fill, an operation that conceptually takes no inputs.

(I also don’t believe that “don’t repeat type information” rule applies here. “blend mode” is a description of the parameter, not only its type. Same with coder. We’re not needlessly repeating type information here, we’re describing option parameters, which happen to be the same as type names.)
</blockquote></pre></div><div class="">I think the language defaults and general guidelines are good. But the guidelines should be slightly more open about other situations where overriding the default is clearer to the reader.</div><div class=""><br class=""></div><div class="">* * *</div><div class=""><br class=""></div><div class="">= Omit Needless Words =</div><div class=""><br class=""></div><div class="">One more example to the parameters discussion, and also related to omitting needless words:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;array.joinWithSeparator(“,”)</div><div class=""><br class=""></div><div class="">I have multiple problems with this API. First of all, this should be, in my mind:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;array.join(separator: “,”)</div><div class=""><br class=""></div><div class="">because “separator” is a parameter, not the description of the method itself.</div><div class=""><br class=""></div><div class="">(In fact, I would go as far as to say `array.join(“,”)` because it seems always obvious from context.)</div><div class=""><br class=""></div><div class="">But aside from that, I take issue with this pattern because of the word “with”. This is a needless word that should be omitted. It contains no information. It’s just syntactic glue, which is not necessary here since we can say `join(separator: …)` instead.</div><div class=""><br class=""></div><div class="">(A rule of thumb: If you’re tempted to write `fooWithBar(…)`, you probably should use `foo(bar:)`, just like `initWithFoo:` from ObjC is translated to `init(foo:)`)</div><div class=""><br class=""></div><div class="">And I see that in many places. Not much in Swift, but a lot more in Objective-C APIs. Needless words like “with”, “and”, “by”, “using”, “for". I’m not saying they’re always unnecessary; they often help convey the semantics or intent, or are needed for the method name to make sense. Or sometimes they replace a noun in describing a parameter (see: stride). But too often they’re just glue words used to make code sound like English without any actual readability benefits, and merely adding noise.</div><div class=""><br class=""></div><div class="">Sorry about this mini-rant. I’m not sure if this requires additional examples or clarification in the Guidelines text aside from the first-parameter discussion, but something I wanted to point out.</div><div class=""><br class=""></div><div class="">* * *</div><div class=""><br class=""></div><div class="">=&nbsp;If the first parameter of a method is defaulted, it should have an argument label. =</div><div class=""><br class=""></div><div class="">Okay, I think you all got the idea by now, but I can’t help myself. This rule says you should do something like:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;mutating func removeAll(keepingCapacity keepingCapacity: Bool = false)</div><div class="">&nbsp; &nbsp;close(completionHandler completion: ((Bool) -&gt; Void)? = nil)</div><div class=""><br class=""></div><div class="">But consider what would happen if these parameters weren't defaulted, for whatever reason:</div><div class=""><br class=""></div><div class="">It would still make more sense to say:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;removeAll(keepingCapacity: false)</div><div class="">&nbsp; &nbsp;close(completionHandler: { … })</div><div class=""><br class=""></div><div class="">Than:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;removeAllKeepingCapacity(false)</div><div class="">&nbsp; &nbsp;closeWithCompletionHandler({ … })</div><div class=""><br class=""></div><div class="">This suggests to me that this rule is not fundamental, rather it derives from the distinction between the implied function input and method options/parameters I discussed earlier. The use case with default values is just the most common example of this in practice, since “options” (vs inputs) very often have a sensible default.</div><div class=""><br class=""></div><div class="">* * *</div><div class=""><br class=""></div><div class="">= -ed / - ing / -inPlace =</div><div class=""><br class=""></div><div class="">I have nothing to add others haven’t, but I agree that these rules are still really awkward.</div><div class=""><br class=""></div><div class="">* * *</div><div class=""><br class=""></div><div class="">I haven’t found any other serious issues with the proposal. I have some ideas to _add_ to the Guidelines, but I figure those can wait and should get their own thread later. The overall language and spirit is exactly what I was hoping for.</div><div class=""><br class=""></div><div class="">And just don’t forget:</div><div class=""><br class=""></div><div class=""><div class=""></div><blockquote type="cite" class=""><div class="">Good APIs aren't the result of</div><div class="">applying a set of mechanical rules. &nbsp;You have to consider what the usage</div><div class="">will look like.</div></blockquote></div><div class=""><blockquote type="cite" class="">(Dave Abrahams)</blockquote><br class=""></div><div class="">These are guidelines, not the law. It’s a great thing to have a set of guidelines applicable in 95% of cases, and have the community consistently apply them, but there’s always room for good judgement along the edges.</div><div class=""><br class=""></div><div class="">Best,</div><div class="">
<div class="">— Radek</div>
</div>
<br class=""><div class=""><blockquote type="cite" class=""><div class="">On 22 Jan 2016, at 22:02, Douglas Gregor 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=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Hello Swift community,</p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The review of SE-0023"API Design Guidelines" begins now and runs through January 31, 2016. The proposal is available here:</p><blockquote style="box-sizing: border-box; margin: 0px 0px 16px; padding: 0px 15px; border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221); background-color: rgb(255, 255, 255);" class=""><div style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px;" class=""><font color="#777777" face="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol" size="3" class=""><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0023-api-guidelines.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0023-api-guidelines.md</a></font></div></blockquote><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at</p><blockquote style="box-sizing: border-box; margin: 0px 0px 16px; padding: 0px 15px; color: rgb(119, 119, 119); border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><div style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:</p><blockquote style="box-sizing: border-box; margin: 0px 0px 16px; padding: 0px 15px; border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221); background-color: rgb(255, 255, 255);" class=""><p style="color: rgb(119, 119, 119); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class="">Proposal link:</p><blockquote style="box-sizing: border-box; margin: 0px 0px 16px; padding: 0px 15px; border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221);" class=""><div style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px;" class=""><font color="#777777" face="Helvetica Neue, Helvetica, Segoe UI, Arial, freesans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol" size="3" class=""><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0023-api-guidelines.md" class="">https://github.com/apple/swift-evolution/blob/master/proposals/0023-api-guidelines.md</a></font></div></blockquote><p style="color: rgb(119, 119, 119); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; box-sizing: border-box; margin-top: 0px; margin-bottom: 16px;" class="">Reply text</p><blockquote style="color: rgb(119, 119, 119); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; box-sizing: border-box; margin: 0px; padding: 0px 15px; border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221);" class=""><div style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px;" class="">Other replies</div></blockquote></blockquote><h5 style="box-sizing: border-box; margin-top: 1em; margin-bottom: 16px; line-height: 1.4; font-size: 1em; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; background-color: rgb(255, 255, 255);" class=""><a id="user-content-what-goes-into-a-review-1" class="anchor" href="https://github.com/apple/swift-evolution#what-goes-into-a-review-1" aria-hidden="true" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none; display: inline-block; padding-right: 2px; margin-left: -18px; line-height: 1.1;"><span aria-hidden="true" class="octicon octicon-link" style="box-sizing: border-box; font-weight: normal; font-size: 16px; line-height: 1; font-family: octicons; display: inline-block; text-rendering: auto; -webkit-font-smoothing: antialiased; -webkit-user-select: none; vertical-align: middle; visibility: hidden;"></span></a>What goes into a review?</h5><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:</p><ul style="box-sizing: border-box; padding: 0px 0px 0px 2em; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><li style="box-sizing: border-box;" class="">What is your evaluation of the proposal?</li><li style="box-sizing: border-box;" class="">Is the problem being addressed significant enough to warrant a change to Swift?</li><li style="box-sizing: border-box;" class="">Does this proposal fit well with the feel and direction of Swift?</li><li style="box-sizing: border-box;" class="">If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?</li><li style="box-sizing: border-box;" class="">How much effort did you put into your review? A glance, a quick reading, or an in-depth study?</li></ul><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">More information about the Swift evolution process is available at</p><blockquote style="box-sizing: border-box; margin: 0px 0px 16px; padding: 0px 15px; color: rgb(119, 119, 119); border-left-width: 4px; border-left-style: solid; border-left-color: rgb(221, 221, 221); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class=""><div style="box-sizing: border-box; margin-top: 0px; margin-bottom: 0px;" class=""><a href="https://github.com/apple/swift-evolution/blob/master/process.md" style="box-sizing: border-box; background-color: transparent; color: rgb(64, 120, 192); text-decoration: none;" class="">https://github.com/apple/swift-evolution/blob/master/process.md</a></div></blockquote><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Thank you,</p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">-Doug Gregor</p><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(51, 51, 51); font-family: 'Helvetica Neue', Helvetica, 'Segoe UI', Arial, freesans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; background-color: rgb(255, 255, 255);" class="">Review Manager</p></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></body></html>