[swift-evolution] [Review] SE-0023 API Design Guidelines
dabrahams at apple.com
Sat Jan 30 21:49:30 CST 2016
on Fri Jan 29 2016, Erica Sadun <swift-evolution at swift.org> wrote:
> It suddenly occurs to me it's almost the 31st and I haven't actually
> responded to the proposal as a proposal.
Thanks for taking the time to do this, Erica. I'm going to take issue
with some of your feedback below, but please know this is motivated by a
desire to make the most of your contribution. I think your feedback is
valuable, but much of the signal is getting lost.
> I heartily endorse a general set of API guidelines and I appreciate
> this first approach towards satisfying that goal. I have issues with
> two sections.
> First, I'd entirely eliminate the guidance in the "Be Grammatical"
> section and move the section with boolean assertions and property
> names to Special Instructions.
I *think* I may know why you want to eliminate the first part, but I
have no clue why you think it'd be better to move the other part.
Statements like these don't really provide much useful feedback, because
we can't tell what problems you think you're solving.
> * I disagree with the mutating/non-mutating differentiation. I started
> writing about this here before personally abandoning it as too big a
> question: Grammatical.md
> <https://github.com/erica/SwiftStyle/blob/master/Grammatical.md>. In a
> nutshell, side-effects and pure functionality are not considered the
> way I'd want them to be and the ed/ing naming is problematic.
I still don't really understand this objection. I do believe that
generalizing beyond "mutating" to cover "anything with side-effects"
would improve the guideline quite a lot. I don't understand any of the
rest of your beef with this guideline.
> * The protocol question is big and wide as well, and I have written
> on-list: it's not "the role of a protocol to describe implementation
> details...Going that way leads you to over-designated hungarian-esque
> guidelines that I'd rather keep loose, friendly, and sensible."
You have written that, but nothing in the guidelines suggests describing
> In "Conventions":
> * I don't like endorsing that any property could or should not be O(1)
> (vs recommending using a function instead)
We don't do that. We merely say that if it's not O(1) it should be
documented as such.
> * The case convention for enumerations remains conventional without a
> guiding principle. I'd rather have a firm "use lower camel case for
> members" that I can complain about (because it feels to me like "pick
> a type layout for this memory", so upper camel) rather than "use upper
> camel and let everyone on the Swift team complain about it" once and
> for all.
* With regard to argument labels, I'd like to add two rules,
> as detailed in-thread and written about here: ArgumentLabels.md
> Differentiate related calls whose implementations are distinguished by
> their parameters, as you would with initializers, using first
> parameter labels. Instead of loginWithUserName("blah", password:
> "...") and loginWithCredential(myCredential), prefer:
> login(userName: "blah", password: "...")
> login(credential: myCredential)
> This approach emphasizes the action being taken (login) and demotes
> the actual arguments involved in performing that action. In doing so,
> they require labels to differentiate which implementation of that
> action is to be used.
> Prefer external names for the first parameter when the natural
> semantic relationship between the parameters is stronger than their
> relation to the operation.
That rule doesn't work for any one-parameter methods, unless you think
they should never have first argument labels.
> For example, the following calls use labels for the first parameter:
> login(userName: "blah", password: "...")
> moveTo(x: 50.0, y: 30.0)
> constructColor(red: 0.2, green: 0.3, blue: 0.1)
> This example is contrary to Swift's normal naming scheme which
> integrates the first argument into the function or method name, for
> loginWithUserName("blah", password: "...")
> moveToX(50.0, y: 30.0)
> constructColorWithRed(0.2, green: 0.3, blue: 0.1)
> The relationships between (x, y), (username, password), and (red,
> green, blue) are strong enough to allow you to make a judgement call
> to employ an external label.
> The following shows a counter-example.
> addLineTo(p1, withWidth: 25.0)
> In this call, the point and width have no natural
> relationship. There's no reason to create an external label for the
> first argument so this example follows the standard Swift call
Thanks again for your feedback, Erica. If you'd care to clarify any of
the points above, that'd be extra awesome.
More information about the swift-evolution