[swift-evolution] When to use argument labels (a new approach)

Eric Summers eric.summers at icloud.com
Wed Feb 3 12:48:49 CST 2016


The current syntax doesn’t bother me too much, but I think just omitting the first argument and treating the second as the first could work:
func methodName(, moreThanTwoWords: Type) { … }

It may be less confusing when a function has a labeled variant with the same name:
func methodName(, aLabel: Type) { … }
func methodName(notALabel: Type) { … }

However, I think this would not be common enough to worry about.

Eric

> On Feb 3, 2016, at 12:19 PM, Radosław Pietruszewski via swift-evolution <swift-evolution at swift.org> wrote:
> 
> By the way. I know this isn’t the main topic for the thread, but I would adding back a shortcut syntax for making a variable name the external label. It’s tiring to have to write:
> 
> methodName(moreThanTwoWords moreThanTwoWords: Type) // exaggerated for dramatic effect.
> 
> Most methods, in my experience, still don’t need a label for the first argument, but in the ones that do, we shouldn’t penalize doing so with ugly repetitiveness.
> 
> (The Q is what syntax should do this. The old “#argument” obviously feels wrong, as “#” is otherwise reserved as “macro-like, or compiler-generated”.)
> 
> — Radek
> 
>> On 03 Feb 2016, at 01:32, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> 
>> This thread is related to the review of new API guidelines, but it's not
>> a review thread; it's exploratory.  The goal is to come up with
>> guidelines that:
>> 
>> * describe when and where to use argument labels
>> * require labels in many of the cases people have asked for them
>> * are understandable by humans
>> * preserve important semantics communicated by existing APIs.
>> 
>> Here's what I'm thinking
>> 
>> 1. If and only if the first argument could complete a sentence*
>>  beginning in the base name and describing the primary semantics of
>>  the call, it gets no argument label:
>> 
>>    a.contains(b)  // b completes the phrase "a contains b"
>>    a.mergeWith(b) // b completes the phrase "merge with b"
>> 
>>    a.dismiss(animated: b) // "a, dismiss b" is a sentence but 
>>                           // doesn't describe the semantics at all, 
>>                           // thus we add a label for b.
>> 
>>    a.moveTo(x: 300, y: 400) // "a, move to 300" is a sentence 
>>                             // but doesn't describe the primary 
>>                             // semantics, which are to move in both
>>                             // x and y.  Thus, x gets a label.
>> 
>>    a.readFrom(u, ofType: b) // "a, read from u" describes
>>                             // the primary semantics, so u gets no
>>                             // label. b is an
>>                             // option that tunes the primary
>>                             // semantics
>> 
>>  [Note that this covers all the direct object cases and, I believe,
>>  all the default argument cases too, so maybe that exception can be
>>  dropped.  We still need the exceptions for full-width type
>>  conversions and indistinguishable peers]
>> 
>>  Note: when there is a noun in the base name describing the role of the
>>  first argument, we skip it in considering this criterion:
>> 
>>     a.addObserver(b) // "a, add b" completes a sentence describing 
>>                      // the semantics.  "Observer" is omitted in 
>>                      // making this determination.
>> 
>> * We could say "clause" here but I think making it an *independent*
>> clause doesn't rule out any important use-cases (see
>> https://web.cn.edu/kwheeler/gram_clauses_n_phrases.html) and at that
>> point, you might as well say "sentence," which is a more
>> universally-understood term.
>> 
>> 2. Words that describe attributes of an *already-existing* instance
>>  should go in the base name rather than in a label:
>> 
>>     a.tracksHavingMediaType("Wax Cylinder")      // yes
>>     a.removeFirstTrackHavingMediaType("BetaMax") // yes
>> 
>>     a.tracks(mediaType: "Wax Cylinder")          // no
>>     a.removeFirstTrack(havingMediaType: "BetaMax") // no
>> 
>>  [yes, we could use "With" instead of "Having", but it's more
>>  ambiguous]
>> 
>>  Words that describe attributes of an instance *to be created* should
>>  go in argument labels, rather than the base name (for parity with
>>  initializers):
>> 
>>     AudioTrack(mediaType: "BetaMax")                   // initializer
>>     trackFactory.newTrack(mediaType: "Wax Cylinder")   // yes
>> 
>>     trackFactory.newTrackWithMediaType("Wax Cylinder") // no
>> 
>> 3. (this one is separable) When the first argument is the *name* or
>>  *identifier* of the subject in the base name, do not label it or
>>  describe it in the base name.
>> 
>>     a.transitionToScene(.GreatHall)               // yes
>>     a.transitionToSceneWithIdentifier(.GreatHall) // no
>> 
>>     let p = someFont.glyph("propellor")           // yes
>>     let p = someFont.glyphWithName("propellor")   // no
>>     let p = someFont.glyph(name: "propellor")     // no
>> 
>> Thoughts?
>> 
>> -- 
>> -Dave
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list