[swift-evolution] When to use argument labels, part DEUX

Dave Abrahams dabrahams at apple.com
Fri Feb 5 19:59:04 CST 2016


on Fri Feb 05 2016, Erica Sadun <swift-evolution at swift.org> wrote:

>> On Feb 5, 2016, at 2:32 PM, Dave Abrahams via swift-evolution
>> <swift-evolution at swift.org> wrote:
>> 
>> 
>> Given all the awesome feedback I've gotten on this thread, I went back
>
>> to the drawing board and came up with something new; I think this one
>> works.  The previously-stated goals still apply:
>> 
>> * describe when and where to use argument labels
>> * require labels in many of the cases people have asked for them
>> * are understandable by humans (this means relatively simple)
>> * preserve important semantics communicated by existing APIs.
>> 
>> Please keep in mind that it is a non-goal to capture considerations we
>> think have a bearing on good names (such as relatedness of parameters):
>> it's to create simple guidelines that have the right effect in nearly
>> all cases.
>> 
>> A. When arguments can't be usefully distinguished from one another, none
>>   should have argument labels, e.g. min(x,y), zip(x,y,z).  
>
> Personal bugaboo. Guidance should guide: Avoid argument labels when
> arguments cannot be usefully distinguished from one another.

Noted, but this is not intended to be wording for the guidelines
document; it's intended to describe the substance of what the guidelines
will say..

>> 
>> B. Otherwise,
>> 
>>  1. At the call site, a first parameter that has no argument label must
>>     form part of a grammatical phrase that starts with the basename, less
>>     any trailing nouns.  
>> 
>>       print(x)
>>       a.contains(b)
>>       a.mergeWith(b)
>>       a.addGestureRecognizer(x)
>>            ^~~~~~~~~~~~~~~~~ trailing noun
>> 
>>     This phrase must have the correct semantic implications, so, e.g.
>> 
>>       a.dismiss(b)           // no, unless a is really dismissing b
>>       a.dismissAnimated(b)   // no, not grammatical
>>       a.dismiss(animated: b) // yes, using a label
>
> Skip parameter labels when the first argument completes a
> grammatically meaningful phrase starting with the base name (and apart
> from trailing nouns).

No; “completing” a phrase is needless complexity.  It isn't needed to
make these guidelines work.

But again, I don't know *why* you're rewriting what I wrote.  If you're
going to respond with a rewrite, please explain how you think your
rewrite improves on the original.

>>       a.dismiss(b)           // Not unless a is really dismissing some instance of b
>
>> 
>>  2. If the first argument is part of a prepositional phrase, put the
>>     parenthesis immediately after the preposition. 
>> 
>>       a.encodeWith(b)
>>       a.moveFrom(b, to: c)
>> 
>>     Thus, if words are required for any reason between the preposition
>>     and the first argument, they go into the first argument label.
>> 
>>       a.tracksWith(mediaType: b, composer: c)
>>       a.moveTo(x: 22, y: 99)
>
> When using prepositional phrases, use parentheses after the
> preposition. Place any supporting words into first argument labels.
>
> a.dismissUsing(animation: b)
> a.tracksOf(mediaType: b, composer: c)
> a.moveTo(x: 22, y: 99)
>
> AGAINST: this worked better with your "creating new instance rule" and
> should probably be called out as such.  I'd like to see the "if it
> works like an initializer it should be named with initializer label"
> bits come back.
>
> a.colorWith(red: r, green: g, blue: b, alpha: a)
>
> I think this should probably be:
>
> a.color(red:, green:, blue:, alpha:)

That's already covered under "omit needless words."  "With" is vacuous
here, so you drop it.

>> 
>> Notes: 
>> 
>> a. I would recommend prepositions other than "with" in nearly all
>>   cases, but that's not the point of these rules.
>
> When using "with" as your go-to preposition, carefully consider
> whether other more meaningful prepositions could apply. "With" tends
> to describe use at a call site rather than method or function
> semantics.

Yes, a guideline for this could be useful, but no, I'm not asking for
feedback on that.  This is in a note because I'm merely accounting for
the fact that I had used "Having" and other such prepositions in earlier
drafts, and now I'm going back to "With" so that people will more
readily see the connection with foundation APIs.

>> b. I can understand the aesthetic appeal of
>> 
>>    a.move(from: b, to: c)
>> 
>>   but I believe it is not a clear enough improvement to justify
>>   additional complexity in the guidelines.
>
> When the natural semantic relationship between the arguments is
> stronger than the relationship between the method name and the first
> argument, use first argument labels, whether the label is a noun or a
> preposition:
>
> a.move(from: b, to: c)
> a.login(username: b, password: c)

You don't need this additional guideline to get

  a.login(username: b, password: c)

a login b is not part of a grammatical phrase with the right semantics,
therefore the first argument gets a label.  As for 

  a.move(from: b, to: c)

the extra complication in the guidelines required to make this happen
makes for aesthetically pleasing results in a few cases, that don't seem
substantially more comprehensible.  If you want to argue for doing it,
it should be justified on the basis of something more objective than "it
feels better to me."

> -- E, always attempting to be helpful, but understanding your
> frustration at getting this kind of feedback

I appreciate the understanding.  What would actually help would be to
accompany your rewrites by rationales and explanations.  Without them, I
have no idea how to evaluate your suggestions.

-- 
-Dave



More information about the swift-evolution mailing list