[Guidelines, First Argument Labels]: Prepositions inside the parens


(Dave Abrahams) #1

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:
  
  https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
   describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

   1. It does not form part of a grammatical phrase describing the
      primary semantics. For example,
      ```
      x.dismiss(animated: y)
      ```
      [more examples needed]
      Note that parameters with defaults never describe the primary
      semantics. so are always labeled.
      ```
      func invert(options options: SomeOptionSet = []) // yes
      func invert(_ options: SomeOptionSet = []) // no
      ```

   2. The method is a factory method; such calls should mirror
      initializers, with no preposition. For example,
      ```
      let x = UIColor(red: r, green: g, blue: b)
      let y = monitor.makeColor(red: r, green: g, blue: b)
      ```

   3. It is part of a prepositional phrase

     a. The label normally starts with the preposition.
        For example,
        ```
        x.move(from: a, to: b)
        x.loadValues(forKeys: ["fox", "box", "lox"])
        ```
     b. ...unless the preposition would break a very tight association
        between parameters:
        ```
        x.moveTo(x: a, y: b)
        ```
        [encourage grouping parameters into higher-level concepts,
        e.g. Point, in these cases]
      
Feedback most welcome, of course.

···

--
-Dave


(Jacob Bandes-Storch) #2

I think I like this direction in general. It feels more natural to have the
preposition in the label than outside the parenthesis (and it's worth
keeping the preposition because it improves clarity in most cases).

Here are some strange examples which need tweaking:

     + func accountType(withAccountTypeIdentifier typeIdentifier: String!)
-> ACAccountType!

Probably should just be "withIdentifier".

     + func comparePositionInDecodeOrderWithPosition(of cursor:
AVSampleCursor) -> ComparisonResult

I would suggest comparePositionInDecodeOrder(withPositionOf cursor:
AVSampleCursor). Tricky because there are two prepositions.

      func componentsPassingTest(testHandler: (AVAudioUnitComponent,
UnsafeMutablePointer<ObjCBool>) -> Bool) -> [AVAudioUnitComponent]
- func componentsMatching(desc: AudioComponentDescription) ->
[AVAudioUnitComponent]
+ func components(matching desc: AudioComponentDescription) ->
[AVAudioUnitComponent]

Should "passingTest" become the first label?

     - class func exportPresetsCompatibleWith(asset: AVAsset) -> [String]
     + class func exportPresetsCompatible(withAsset asset: AVAsset) ->
[String]

This is not an improvement. I'd suggest exportPresets(compatibleWith asset:
AVAsset), but that doesn't really fit under the current rules. Maybe a
special case for [noun][adjective][preposition]?

    - func compatibleTrackFor(compositionTrack: AVCompositionTrack) ->
AVAssetTrack?
    + func compatibleTrack(forCompositionTrack compositionTrack:
AVCompositionTrack) -> AVAssetTrack?

Does this indicate that some other suffix-matching rules are no longer
being applied? I'd have expected compatibleTrack(for compositionTrack:
AVCompositionTrack). I also see other examples like
renewCredentials(forAccount account: ACAccount, ...).

      func createSampleBufferFor(request: AVSampleBufferRequest) ->
CMSampleBuffer

Why wasn't this changed?

      - class func typeOf(property property: String!) -> ABPropertyType
      + class func type(ofProperty property: String!) -> ABPropertyType

I don't really like either of these. Maybe we need special rules for "of" ?

If anyone else is worried about special cases, I just looked this up:
there's a clang __attribute__((swift_name("x"))), or NS_SWIFT_NAME(x),
which can be used to expose Obj-C methods to Swift with particular custom
names.

Jacob

···

On Tue, Feb 9, 2016 at 11:18 AM, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
   describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

   1. It does not form part of a grammatical phrase describing the
      primary semantics. For example,
      ```
      x.dismiss(animated: y)
      ```
      [more examples needed]
      Note that parameters with defaults never describe the primary
      semantics. so are always labeled.
      ```
      func invert(options options: SomeOptionSet = []) // yes
      func invert(_ options: SomeOptionSet = []) // no
      ```

   2. The method is a factory method; such calls should mirror
      initializers, with no preposition. For example,
      ```
      let x = UIColor(red: r, green: g, blue: b)
      let y = monitor.makeColor(red: r, green: g, blue: b)
      ```

   3. It is part of a prepositional phrase

     a. The label normally starts with the preposition.
        For example,
        ```
        x.move(from: a, to: b)
        x.loadValues(forKeys: ["fox", "box", "lox"])
        ```
     b. ...unless the preposition would break a very tight association
        between parameters:
        ```
        x.moveTo(x: a, y: b)
        ```
        [encourage grouping parameters into higher-level concepts,
        e.g. Point, in these cases]

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jessy) #3

That seems good, except…

  2. The method is a factory method; such calls should mirror
     initializers, with no preposition. For example,
     ```
     let x = UIColor(red: r, green: g, blue: b)
     let y = monitor.makeColor(red: r, green: g, blue: b)

I disagree with this. I believe that PascalCase for pseudo-initializers is more meaningful and modern than “make…”.

Because the compiler can’t yet deal with this…

protocol Monitor {
   typealias Color
   func Color(red: Float, green: Float, blue: Float) -> Color
}
let color = monitor.Color(red: r, green: g, blue: b)

… I hack around it with this…
func Color_init(red: Float, green: Float, blue: Float) -> Color

…but most of the time, the “_init” is not necessary. Normally we can just namespace out way out of the collision:
protocol Frog {}; extension Frog {
   func String() -> Swift.String {
      return "Frog"
   }
}


(Xiaodi Wu) #4

I'm having trouble with this example in 3(a):

x.loadValues(forKeys: ["fox", "box", "lox"])

Based on the preceding discussion, I understand that the above is
preferred by the working group over the following:

x.loadValuesFor(keys: ["fox", "box", "lox"])

Going by the guidelines, though, it seems like the first option is
also now preferred by the working group over the unlabeled version
below (which admittedly is only an option because 'keys' is not
duplicating type information):

x.loadValuesForKeys(["fox", "box", "lox"])

Is it really the case that the first option is preferred over the
third? It does look as though it is, based on this in the diff:

- func respondWith(data: Data)
+ func respond(withData data: Data)

Whichever one is preferred, could the guidelines be clarified in that
respect? Also, what of the guideline not to repeat type information?
For example, why isn't the method above `func respond(with data:
Data)`?

···

On Tue, Feb 9, 2016 at 1:18 PM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

  https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
   describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

   1. It does not form part of a grammatical phrase describing the
      primary semantics. For example,
      ```
      x.dismiss(animated: y)
      ```
      [more examples needed]
      Note that parameters with defaults never describe the primary
      semantics. so are always labeled.
      ```
      func invert(options options: SomeOptionSet = []) // yes
      func invert(_ options: SomeOptionSet = []) // no
      ```

   2. The method is a factory method; such calls should mirror
      initializers, with no preposition. For example,
      ```
      let x = UIColor(red: r, green: g, blue: b)
      let y = monitor.makeColor(red: r, green: g, blue: b)
      ```

   3. It is part of a prepositional phrase

     a. The label normally starts with the preposition.
        For example,
        ```
        x.move(from: a, to: b)
        x.loadValues(forKeys: ["fox", "box", "lox"])
        ```
     b. ...unless the preposition would break a very tight association
        between parameters:
        ```
        x.moveTo(x: a, y: b)
        ```
        [encourage grouping parameters into higher-level concepts,
        e.g. Point, in these cases]

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matt Whiteside) #5

I haven’t read through every bullet item in this email, but I definitely agree with what you’ve done as far as having the preposition inside the parenthesis, as it is in the git diff. This seems clearly better than putting the left-paren between the preposition and its object, which unnaturally breaks them apart.

-Matt

···

On Feb 9, 2016, at 11:18, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split


(Brent Royal-Gordon) #6

    a. The label normally starts with the preposition.
       For example,
       ```
       x.move(from: a, to: b)
       x.loadValues(forKeys: ["fox", "box", "lox"])
       ```

Would this mean we're returning to `stride(to:by:)` and `stride(through:by:)`? If so, I for one welcome our new argument label overlords.

···

--
Brent Royal-Gordon
Architechies


(Charles Constant) #7

+1

New versions are much prettier. I like.


(Ben Rimmington) #8

How will the new API Design Guidelines be applied to the Swift Core Libraries?

<https://swift.org/core-libraries/>

If they have to copy APIs from the heuristics-based importer, they're missing the opportunity to *manually* choose the best method names and argument labels.

It would also be difficult to improve the heuristics in later versions, because of binary compatibility with the Swift Core Libraries.

-- Ben


#9

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
   describing the primary semantics at the call site.

I assume that A is intended to cover:

a.addObserver(b) // yes
a.add(observer: b) // no

I believe I can read this behavior into A by inferring "a grammatical
phrase including [the base name and] the first argument" but I want to make
sure this is the intent.

B. The first argument gets a label when and only when:

   1. It does not form part of a grammatical phrase describing the
      primary semantics. For example,
      ```
      x.dismiss(animated: y)
      ```
      [more examples needed]
      Note that parameters with defaults never describe the primary
      semantics. so are always labeled.
      ```
      func invert(options options: SomeOptionSet = []) // yes
      func invert(_ options: SomeOptionSet = []) // no
      ```

   2. The method is a factory method; such calls should mirror
      initializers, with no preposition. For example,
      ```
      let x = UIColor(red: r, green: g, blue: b)
      let y = monitor.makeColor(red: r, green: g, blue: b)
      ```

If rule B.2 didn't exist

let y = monitor.makeColor(red: r, green: g, blue: b)

would still have the first argument labeled by B.1 wouldn't it? (Though
without this rule, the guidelines wouldn't be clear on whether or not to
include prepositions in the argument labels.)

   3. It is part of a prepositional phrase

     a. The label normally starts with the preposition.
        For example,
        ```
        x.move(from: a, to: b)
        x.loadValues(forKeys: ["fox", "box", "lox"])
        ```
     b. ...unless the preposition would break a very tight association
        between parameters:
        ```
        x.moveTo(x: a, y: b)
        ```
        [encourage grouping parameters into higher-level concepts,
        e.g. Point, in these cases]

This seems clear and straightforward to apply. The only place where
this isn't totally clear is when there are multiple prepositions (as
highlighted in Jacob's response), but I think B.3 provides the right level
of guidance... much more detail will start being too many guidelines and
special cases.

···

On Tue, Feb 9, 2016 at 2:18 PM, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #10

Appart from the kind of details that Jacob mentioned, this is perfect for me. Nothing else to add. :slight_smile: Great work!!

···

On 09 Feb 2016, at 20:18, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
  describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

  1. It does not form part of a grammatical phrase describing the
     primary semantics. For example,
     ```
     x.dismiss(animated: y)
     ```
     [more examples needed]
     Note that parameters with defaults never describe the primary
     semantics. so are always labeled.
     ```
     func invert(options options: SomeOptionSet = []) // yes
     func invert(_ options: SomeOptionSet = []) // no
     ```

  2. The method is a factory method; such calls should mirror
     initializers, with no preposition. For example,
     ```
     let x = UIColor(red: r, green: g, blue: b)
     let y = monitor.makeColor(red: r, green: g, blue: b)
     ```

  3. It is part of a prepositional phrase

    a. The label normally starts with the preposition.
       For example,
       ```
       x.move(from: a, to: b)
       x.loadValues(forKeys: ["fox", "box", "lox"])
       ```
    b. ...unless the preposition would break a very tight association
       between parameters:
       ```
       x.moveTo(x: a, y: b)
       ```
       [encourage grouping parameters into higher-level concepts,
       e.g. Point, in these cases]

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charles Kissinger) #11

FWIW, I think these new guidelines strike a very nice balance between all of the competing concerns. The result of applying them to some of my own code could best be described as “different but not unpleasant” :wink:

In looking over the diffs, one nice result I didn’t expect is that moving the prepositional phrases into the first argument label seems to increase the speed with which I absorb the general intent of a function -- the “at a glance” understanding -- by moving a “detail” (important as it might be) into the parameter list. (The split prepositional phrases had the opposite effect for me.)

—CK

···

On Feb 9, 2016, at 11:18 AM, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
  describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

  1. It does not form part of a grammatical phrase describing the
     primary semantics. For example,
     ```
     x.dismiss(animated: y)
     ```
     [more examples needed]
     Note that parameters with defaults never describe the primary
     semantics. so are always labeled.
     ```
     func invert(options options: SomeOptionSet = []) // yes
     func invert(_ options: SomeOptionSet = []) // no
     ```

  2. The method is a factory method; such calls should mirror
     initializers, with no preposition. For example,
     ```
     let x = UIColor(red: r, green: g, blue: b)
     let y = monitor.makeColor(red: r, green: g, blue: b)
     ```

  3. It is part of a prepositional phrase

    a. The label normally starts with the preposition.
       For example,
       ```
       x.move(from: a, to: b)
       x.loadValues(forKeys: ["fox", "box", "lox"])
       ```
    b. ...unless the preposition would break a very tight association
       between parameters:
       ```
       x.moveTo(x: a, y: b)
       ```
       [encourage grouping parameters into higher-level concepts,
       e.g. Point, in these cases]

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Radek Pietruszewski) #12

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

I find that… surprising.

Between these two (sorry to repeat the same example again):

func trackWith(trackID trackID: CMPersistentTrackID) -> AVAssetTrack?
func track(withTrackID trackID: CMPersistentTrackID) -> AVAssetTrack?

#1 seems nicer and clearer to me. Having “with” as the first word glued to a parameter label looks bizarre to my eyes:

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.

Another reason I don’t like this, say we have:

  a.tracks(withMediaType: b, composer: c)

This no longer looks symmetrical across the parameters. First parameter has label “with”, second doesn’t. The previous version:

  a.tracksWith(mediaType: b, composer: c)

Didn’t have that problem.

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”:

  a.tracks(withMediaType: b, andComposer: c)

To avoid this weird-looking construct where the first parameter has a starting preposition, and other parameters don’t. Again:

  a.tracksWith(mediaType: b, composer: c)

Doesn’t have this problem, because while the method name part ends with “With”, the parameters are consistently just nouns.

So -1 from me on this. Moving prepositions inside parens look like a step back from the Part DEUX Proposal.

Would you mind elaborating on the working group's rationale for moving prepositions inside parens?

— Radek

···

On 09 Feb 2016, at 20:18, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
  describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

  1. It does not form part of a grammatical phrase describing the
     primary semantics. For example,
     ```
     x.dismiss(animated: y)
     ```
     [more examples needed]
     Note that parameters with defaults never describe the primary
     semantics. so are always labeled.
     ```
     func invert(options options: SomeOptionSet = []) // yes
     func invert(_ options: SomeOptionSet = []) // no
     ```

  2. The method is a factory method; such calls should mirror
     initializers, with no preposition. For example,
     ```
     let x = UIColor(red: r, green: g, blue: b)
     let y = monitor.makeColor(red: r, green: g, blue: b)
     ```

  3. It is part of a prepositional phrase

    a. The label normally starts with the preposition.
       For example,
       ```
       x.move(from: a, to: b)
       x.loadValues(forKeys: ["fox", "box", "lox"])
       ```
    b. ...unless the preposition would break a very tight association
       between parameters:
       ```
       x.moveTo(x: a, y: b)
       ```
       [encourage grouping parameters into higher-level concepts,
       e.g. Point, in these cases]

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #13

I'm having trouble with this example in 3(a):

x.loadValues(forKeys: ["fox", "box", "lox"])

Based on the preceding discussion, I understand that the above is
preferred by the working group over the following:

x.loadValuesFor(keys: ["fox", "box", "lox"])

More than being compelled by that specific example, when we looked
through how Cocoa imported with splitting basenames both before and
after prepositions, it became immediately obvious that on the whole, it
was much better to split before the preposition.

Going by the guidelines, though, it seems like the first option is
also now preferred by the working group over the unlabeled version
below (which admittedly is only an option because 'keys' is not
duplicating type information):

x.loadValuesForKeys(["fox", "box", "lox"])

Yes, on balance, that's the direction we are leaning.

Is it really the case that the first option is preferred over the
third? It does look as though it is, based on this in the diff:

- func respondWith(data: Data)
+ func respond(withData data: Data)

Yes.

Whichever one is preferred, could the guidelines be clarified in that
respect?

Yes.

Also, what of the guideline not to repeat type information?

It

For example, why isn't the method above `func respond(with data:
Data)`?

It should be, AFAICT. I think there's a complicated set of importer
heuristic interactions at work here, and the heuristics aren't getting
the best answer in this case.

···

on Tue Feb 09 2016, Xiaodi Wu <swift-evolution@swift.org> wrote:

On Tue, Feb 9, 2016 at 1:18 PM, Dave Abrahams via swift-evolution > <swift-evolution@swift.org> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

  https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
   describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

   1. It does not form part of a grammatical phrase describing the
      primary semantics. For example,
      ```
      x.dismiss(animated: y)
      ```
      [more examples needed]
      Note that parameters with defaults never describe the primary
      semantics. so are always labeled.
      ```
      func invert(options options: SomeOptionSet = []) // yes
      func invert(_ options: SomeOptionSet = []) // no
      ```

   2. The method is a factory method; such calls should mirror
      initializers, with no preposition. For example,
      ```
      let x = UIColor(red: r, green: g, blue: b)
      let y = monitor.makeColor(red: r, green: g, blue: b)
      ```

   3. It is part of a prepositional phrase

     a. The label normally starts with the preposition.
        For example,
        ```
        x.move(from: a, to: b)
        x.loadValues(forKeys: ["fox", "box", "lox"])
        ```
     b. ...unless the preposition would break a very tight association
        between parameters:
        ```
        x.moveTo(x: a, y: b)
        ```
        [encourage grouping parameters into higher-level concepts,
        e.g. Point, in these cases]

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave


(Matt Whiteside) #14

I'm having trouble with this example in 3(a):

x.loadValues(forKeys: ["fox", "box", "lox"])

Based on the preceding discussion, I understand that the above is
preferred by the working group over the following:

x.loadValuesFor(keys: ["fox", "box", "lox"])

I had trouble with that example too.

More than being compelled by that specific example, when we looked
through how Cocoa imported with splitting basenames both before and
after prepositions, it became immediately obvious that on the whole, it
was much better to split before the preposition.

But that sounds reasonable.

Going by the guidelines, though, it seems like the first option is
also now preferred by the working group over the unlabeled version
below (which admittedly is only an option because 'keys' is not
duplicating type information):

x.loadValuesForKeys(["fox", "box", "lox"])

Yes, on balance, that's the direction we are leaning.

That seems fine, based on the above.

Is it really the case that the first option is preferred over the
third? It does look as though it is, based on this in the diff:

- func respondWith(data: Data)
+ func respond(withData data: Data)

Yes.

Whichever one is preferred, could the guidelines be clarified in that
respect?

Yes.

I haven’t read the entire document so I can’t say if more clarity is needed, but I hope to have a chance to read it later.

Matt

···

On Feb 9, 2016, at 13:55, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:
on Tue Feb 09 2016, Xiaodi Wu <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:


(Dave Abrahams) #15

   a. The label normally starts with the preposition.
      For example,
      ```
      x.move(from: a, to: b)
      x.loadValues(forKeys: ["fox", "box", "lox"])
      ```

Would this mean we're returning to `stride(to:by:)` and `stride(through:by:)`? If so, I for one welcome our new argument label overlords.

Yup!

···

Sent from my moss-covered three-handled family gradunza
On Feb 9, 2016, at 5:39 PM, Brent Royal-Gordon <brent@architechies.com> wrote:


(Douglas Gregor) #16

How will the new API Design Guidelines be applied to the Swift Core Libraries?

<https://swift.org/core-libraries/>

If they have to copy APIs from the heuristics-based importer, they're missing the opportunity to *manually* choose the best method names and argument labels.

The core libraries need to match what the heuristics-based importer produces, or we won’t have source portability. If manual intervention is necessary, we have mechanisms to override the names produced by the automatic translation.

It would also be difficult to improve the heuristics in later versions, because of binary compatibility with the Swift Core Libraries.

Correct.

  - Doug

···

On Feb 9, 2016, at 4:20 PM, Ben Rimmington via swift-evolution <swift-evolution@swift.org> wrote:


(Ben Rimmington) #17

If the Swift Core Libraries were the "source of truth" for Foundation APIs, they could be annotated with @objc attributes, to override your heuristics in the Clang importer.

// Swift Core Libraries:
@objc(encodeWithCoder:)
func encode(into coder: Coder)

// Darwin platforms:
// Implicit NS_SWIFT_NAME(encode(into:))
- (void)encodeWithCoder:(NSCoder *)aCoder;

You'd have stable Foundation APIs which could be fine-tuned in Swift, but the @objc attributes would clutter the source code.

-- Ben

···

On 10 Feb 2016, at 07:40, Douglas Gregor <dgregor@apple.com> wrote:

The core libraries need to match what the heuristics-based importer produces, or we won’t have source portability. If manual intervention is necessary, we have mechanisms to override the names produced by the automatic translation.


(Dave Abrahams) #18

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
   describing the primary semantics at the call site.

I assume that A is intended to cover:

a.addObserver(b) // yes
a.add(observer: b) // no

I don't know what you mean by "cover." It isn't intended to assign the
"yes/no" decision to those; they both form (the same) grammatical phrase
at the call site. The choice between those two is governed by B, below.

I believe I can read this behavior into A by inferring "a grammatical
phrase including [the base name and] the first argument" but I want to make
sure this is the intent.

B. The first argument gets a label when and only when:

   1. It does not form part of a grammatical phrase describing the
      primary semantics. For example,
      ```
      x.dismiss(animated: y)
      ```
      [more examples needed]
      Note that parameters with defaults never describe the primary
      semantics. so are always labeled.
      ```
      func invert(options options: SomeOptionSet = []) // yes
      func invert(_ options: SomeOptionSet = []) // no
      ```

   2. The method is a factory method; such calls should mirror
      initializers, with no preposition. For example,
      ```
      let x = UIColor(red: r, green: g, blue: b)
      let y = monitor.makeColor(red: r, green: g, blue: b)
      ```

If rule B.2 didn't exist

let y = monitor.makeColor(red: r, green: g, blue: b)

would still have the first argument labeled by B.1 wouldn't it?

Yes, but you could have done this grammatically, as

     let y = monitor.makeColorHavingRed(r, green: g, blue: b)

That's what B2 is designed to prevent.

(Though without this rule, the guidelines wouldn't be clear on whether
or not to include prepositions in the argument labels.)

   3. It is part of a prepositional phrase

     a. The label normally starts with the preposition.
        For example,
        ```
        x.move(from: a, to: b)
        x.loadValues(forKeys: ["fox", "box", "lox"])
        ```
     b. ...unless the preposition would break a very tight association
        between parameters:
        ```
        x.moveTo(x: a, y: b)
        ```
        [encourage grouping parameters into higher-level concepts,
        e.g. Point, in these cases]

This seems clear and straightforward to apply. The only place where
this isn't totally clear is when there are multiple prepositions (as
highlighted in Jacob's response),

Multiple prepositions before the first argument?

but I think B.3 provides the right level of guidance... much more
detail will start being too many guidelines and special cases.

Thanks!

···

on Wed Feb 10 2016, Matthew Judge <matthew.judge-AT-gmail.com> wrote:

On Tue, Feb 9, 2016 at 2:18 PM, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

--
-Dave


#19

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
  describing the primary semantics at the call site.

I assume that A is intended to cover:

a.addObserver(b) // yes
a.add(observer: b) // no

I don't know what you mean by "cover." It isn't intended to assign the
"yes/no" decision to those; they both form (the same) grammatical phrase
at the call site. The choice between those two is governed by B, below.

By cover I meant assign the "yes/no" decision. So because the first argument is part of the primary semantics, it doesn't get an argument label (per B.1) and the word observer needs to be in the base name so as not to change the semantic meaning.

I believe I can read this behavior into A by inferring "a grammatical
phrase including [the base name and] the first argument" but I want to make
sure this is the intent.

B. The first argument gets a label when and only when:

  1. It does not form part of a grammatical phrase describing the
     primary semantics. For example,
     ```
     x.dismiss(animated: y)
     ```
     [more examples needed]
     Note that parameters with defaults never describe the primary
     semantics. so are always labeled.
     ```
     func invert(options options: SomeOptionSet = []) // yes
     func invert(_ options: SomeOptionSet = []) // no
     ```

  2. The method is a factory method; such calls should mirror
     initializers, with no preposition. For example,
     ```
     let x = UIColor(red: r, green: g, blue: b)
     let y = monitor.makeColor(red: r, green: g, blue: b)
     ```

If rule B.2 didn't exist

let y = monitor.makeColor(red: r, green: g, blue: b)

would still have the first argument labeled by B.1 wouldn't it?

Yes, but you could have done this grammatically, as

    let y = monitor.makeColorHavingRed(r, green: g, blue: b)

That's what B2 is designed to prevent.

(Though without this rule, the guidelines wouldn't be clear on whether
or not to include prepositions in the argument labels.)

  3. It is part of a prepositional phrase

    a. The label normally starts with the preposition.
       For example,
       ```
       x.move(from: a, to: b)
       x.loadValues(forKeys: ["fox", "box", "lox"])
       ```
    b. ...unless the preposition would break a very tight association
       between parameters:
       ```
       x.moveTo(x: a, y: b)
       ```
       [encourage grouping parameters into higher-level concepts,
       e.g. Point, in these cases]

This seems clear and straightforward to apply. The only place where
this isn't totally clear is when there are multiple prepositions (as
highlighted in Jacob's response),

Multiple prepositions before the first argument?

Yes, before and including the first argument label. For example (from Jacob's response):

comparePositionInDecodeOrderWithPosition(of cursor: AVSampleCursor) -> ComparisonResult

Jacob suggests spelling it:

comparePositionInDecodeOrder(withPositionOf cursor: AVSampleCursor) -> ComparisonResult

I agree that Jacob's spelling is better, but not enough better to justify additional guidelines about prepositions.

···

On Feb 10, 2016, at 18:17, Dave Abrahams <dabrahams@apple.com> wrote:

on Wed Feb 10 2016, Matthew Judge <matthew.judge-AT-gmail.com> wrote:
On Tue, Feb 9, 2016 at 2:18 PM, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

but I think B.3 provides the right level of guidance... much more
detail will start being too many guidelines and special cases.

Thanks!
--
-Dave


(Charles Kissinger) #20

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

I find that… surprising.

Between these two (sorry to repeat the same example again):

func trackWith(trackID trackID: CMPersistentTrackID) -> AVAssetTrack?
func track(withTrackID trackID: CMPersistentTrackID) -> AVAssetTrack?

I think this one particular function is possibly the worst case in the entire API. Neither “track” nor “trackWith” is a particularly good function name. But as I mentioned in a previous post, I think, for many of the Foundation functions, moving the prepositional phrase into the argument label actual aids clarity slightly. I was surprised that I ended up liking it, but I do.

#1 seems nicer and clearer to me. Having “with” as the first word glued to a parameter label looks bizarre to my eyes:

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.

Another reason I don’t like this, say we have:

  a.tracks(withMediaType: b, composer: c)

This no longer looks symmetrical across the parameters. First parameter has label “with”, second doesn’t.

I sympathize with this. My attitude about it, though, is that we would normally only say “with” before the first item in a list, and dropping the “and” from before the final item is a fairly minor offense against the English language. I personally don’t think clarity is really harmed. It might help to add specific guidance that using “and” in these cases is discouraged.

—CK

···

On Feb 11, 2016, at 2:33 AM, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

The previous version:

  a.tracksWith(mediaType: b, composer: c)

Didn’t have that problem.

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”:

  a.tracks(withMediaType: b, andComposer: c)

To avoid this weird-looking construct where the first parameter has a starting preposition, and other parameters don’t. Again:

  a.tracksWith(mediaType: b, composer: c)

Doesn’t have this problem, because while the method name part ends with “With”, the parameters are consistently just nouns.

So -1 from me on this. Moving prepositions inside parens look like a step back from the Part DEUX Proposal.

Would you mind elaborating on the working group's rationale for moving prepositions inside parens?

— Radek

On 09 Feb 2016, at 20:18, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hi everybody,

Having looked at some examples, the API guidelines working group members
that were present this morning agreed we really want prepositions inside
the parentheses of method calls.

Here are some results for the importer; we're still tuning some of the
heuristics but overall we feel very good about the preposition
placement:

https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split <https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split>

Note that this is not final wording, but here are the guidelines we're
working with for first argument labels:

A. Try to form a grammatical phrase including the first argument and
  describing the primary semantics at the call site.

B. The first argument gets a label when and only when:

  1. It does not form part of a grammatical phrase describing the
     primary semantics. For example,
     ```
     x.dismiss(animated: y)
     ```
     [more examples needed]
     Note that parameters with defaults never describe the primary
     semantics. so are always labeled.
     ```
     func invert(options options: SomeOptionSet = []) // yes
     func invert(_ options: SomeOptionSet = []) // no
     ```

  2. The method is a factory method; such calls should mirror
     initializers, with no preposition. For example,
     ```
     let x = UIColor(red: r, green: g, blue: b)
     let y = monitor.makeColor(red: r, green: g, blue: b)
     ```

  3. It is part of a prepositional phrase

    a. The label normally starts with the preposition.
       For example,
       ```
       x.move(from: a, to: b)
       x.loadValues(forKeys: ["fox", "box", "lox"])
       ```
    b. ...unless the preposition would break a very tight association
       between parameters:
       ```
       x.moveTo(x: a, y: b)
       ```
       [encourage grouping parameters into higher-level concepts,
       e.g. Point, in these cases]

Feedback most welcome, of course.
--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution