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

That's nice! What do you think about moving “of” back out of the
parens? Does that help or hurt?

···

on Thu Feb 11 2016, Charles Kissinger <swift-evolution@swift.org> wrote:

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”
;-)

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.)

--
-Dave

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?

[Note: we're most likely looking at the particular API above because
AVFoundation comes first in alphabetical order. To get a good sense of
how the importer is doing, really, you need to look at a sequence of
random areas in any set of diffs. Just something to keep in mind when
evaluating these.]

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.

“With” is such a weak preposition, and has been so overused as a generic
separator for nouns that introduce arguments, that we're actually
considering whether it's an overall win to always strip “with” out of
names when importing Objective-C APIs. Doug is working on preparing the
importer results for review.

···

on Thu Feb 11 2016, Charles Kissinger <swift-evolution@swift.org> wrote:

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

#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

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 <Always split before preposition · apple/swift-3-api-guidelines-review@da7e512 · GitHub;

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

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

--
-Dave

A couple of reasons that I, personally, found motivating (some of which came up on this list before):

  (1) A prepositional phrase is a grammatical entity, and we probably shouldn’t split a grammatical phrase across ‘(‘.
  (2) It seemed to separate “what the method does” (base name) from “how it does it” (argument label) more effectively.
  (3) Related to (2), it pulled out more method families, where we had the same basic operation (described by the base name) and the argument labels differentiated how we got to that result.

… and we spent a while looking at the diff of Cocoa, here:

  https://github.com/apple/swift-3-api-guidelines-review/commit/b22b62bb98e5d44b2528b237d18efe96bf2940d6

  - Doug

···

On Feb 11, 2016, at 2:33 AM, Radosław Pietruszewski 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.

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?

Wouldn't rule 3b "unless the preposition would break a very tight association between parameters" apply, resulting in

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

This would not be applicable to the unary variant, though...

-Thorsten

···

Am 11.02.2016 um 11:33 schrieb Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org>:

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

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

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.

Looking at the fourth function in the diff and saying "I think this is probably the worst API in the frameworks" is a bit like looking at Jupiter and saying "I think this is probably the biggest planet in the universe". With such a small sample out of such a large set, it's far more likely that APIs with the defects seen here are *common*.

···

--
Brent Royal-Gordon
Architechies

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

Interesting! I’ll have to think about this; it might just be a special case. I haven’t seen this issue come up before.

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

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

Yeah. Our current heuristics produce:

  func comparePositionInDecodeOrder(positionOf cursor: AVSampleCursor) -> ComparisonResult

      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?

Yes, thanks!

  Treat "passing" as a preposition · apple/swift-3-api-guidelines-review@ba28833 · GitHub

     - 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]?

I did it in a different way, here:

  Handle "extended prepositions" like "compatible with". · apple/swift-3-api-guidelines-review@fd70e0e · GitHub

    - 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, …).

There was a ban on leaving “vacuous” argument labels like “for” or “with”, but it doesn’t make sense now. Addressed in

  https://github.com/apple/swift-3-api-guidelines-review/commit/aaec8d0fe9cf82cd6f4088721cf8968a6ac69164

      func createSampleBufferFor(request: AVSampleBufferRequest) -> CMSampleBuffer

Why wasn't this changed?

Similar issue to the rule above. It’s fixed now to

  func createSampleBuffer(for request: AVSampleBufferRequest) -> CMSampleBuffer

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

Handled in the subsequent discussion ;)

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.

Yes, generalizing the swift_name attribute to allow arbitrary renaming is one of specified steps to implementing SE-0005, so we can deal with special cases and bad translations.

Thanks!

  - Doug

···

On Feb 9, 2016, at 11:50 AM, Jacob Bandes-Storch via swift-evolution <swift-evolution@swift.org> wrote:

Yes, we could do this through some technical means, and it might make it easier to keep the APIs in sync.

  - Doug

···

On Feb 10, 2016, at 1:43 AM, Ben Rimmington <me@benrimmington.com> wrote:

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.

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.

I don't know enough about linguistics to express this properly, but I
suspect there's something to be said about the "verb phrase" being the part
that comes before the paren. To me,
"comparePositionInDecodeOrderWithPosition(of:)" is confusing because there
is a noun "Position" immediately preceding the parenthesis, which might
indicate that the argument should be a position, but in reality the most
meaningful part of the method name is the verb, "compare".

···

On Wed, Feb 10, 2016 at 6:05 PM, Matthew Judge via swift-evolution < swift-evolution@swift.org> wrote:

> 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.

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:

Always split before preposition · apple/swift-3-api-guidelines-review@da7e512 · GitHub

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.

Correct.

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.

I think I agree that it's better. I think I also agree that we could
avoid complication in the guidelines by leaving the
multiple-prepositions case unspecified and letting the judgement of API
designers come up with the right answer. However, we *are* looking into
the question of whether "Of" should get special treatment. It seems
like it may *always* be worse to put the parenthesis before "of," even
when it's the only preposition:

     x.appendContents(of: y)
     x.appendContentsOf(y) // I like this one a *lot* better

···

on Wed Feb 10 2016, Matthew Judge <swift-evolution@swift.org> wrote:

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

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

--
-Dave

Wouldn't rule 3b "unless the preposition would break a very tight association between parameters" apply, resulting in

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

I don't think so. Maybe it could be expressed better, but the intent of
the “tight association” language is that the multiple parameters are
really part of a single abstraction that could be replaced by a single
type, e.g. (x:, y:) => Point.

···

on Thu Feb 11 2016, Thorsten Seitz <swift-evolution@swift.org> wrote:
   

This would not be applicable to the unary variant, though...

-Thorsten

Am 11.02.2016 um 11:33 schrieb Radosław Pietruszewski via >> swift-evolution >> <swift-evolution@swift.org>:

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

_______________________________________________
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

And lo!, a diff appeared!

  The preposition "of" binds to the word preceding it. · apple/swift-3-api-guidelines-review@3f96534 · GitHub

  - Doug

···

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

on Thu Feb 11 2016, Charles Kissinger <swift-evolution@swift.org> wrote:

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”
;-)

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.)

That's nice! What do you think about moving “of” back out of the
parens? Does that help or hurt?

Wouldn't rule 3b "unless the preposition would break a very tight association between parameters" apply, resulting in

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

This would not be applicable to the unary variant, though…

Then we’re inconsistent between

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

and

a.tracks(withMediaType: b)

which doesn’t seem like a good thing.

— Radek

···

On 11 Feb 2016, at 11:40, Thorsten Seitz <tseitz42@icloud.com> wrote:

Wouldn't rule 3b "unless the preposition would break a very tight association between parameters" apply, resulting in

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

This would not be applicable to the unary variant, though...

-Thorsten

Am 11.02.2016 um 11:33 schrieb Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

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

Always split before preposition · apple/swift-3-api-guidelines-review@da7e512 · GitHub <https://github.com/apple/swift-3-api-guidelines-review/commit/da7e512cf75688e6da148dd2a8b27ae9efcb8821?diff=split&gt;

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 <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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.

Looking at the fourth function in the diff and saying "I think this is probably the worst API in the frameworks" is a bit like looking at Jupiter and saying "I think this is probably the biggest planet in the universe". With such a small sample out of such a large set, it's far more likely that APIs with the defects seen here are *common*.

I did in fact scan through large portions of the the Foundation universe before coming to that conclusion. :-) One problem with both “track” and “trackWith” is that track can be either a noun or a verb in either case. We’ve been using this function as an exemplar right from the start, but it probably isn’t a great one.

Those who feel there are a lot of problematic function names after the latest guideline changes should certainly collate a list.

—CK

···

On Feb 11, 2016, at 1:51 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

--
Brent Royal-Gordon
Architechies

>
>
>>
>>
>>>
>>> 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.

To clarify/be precise, the guidelines as written are clear on how to treat
this: put the prepositional phrase completed by the first argument in the
argument label (unless B.3.b applies).

Where the ambiguity arises is in deciding whether the first
argument completes the prepositional phrase "of" or "withPositionOf" (or
"inDecodeOrderWithPositionOf").

···

On Wed, Feb 10, 2016 at 9:05 PM, Matthew Judge <matthew.judge@gmail.com> wrote:

> 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

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?

A couple of reasons that I, personally, found motivating (some of which came up on this list before):

  (1) A prepositional phrase is a grammatical entity, and we probably shouldn’t split a grammatical phrase across ‘(‘.
  (2) It seemed to separate “what the method does” (base name) from “how it does it” (argument label) more effectively.
  (3) Related to (2), it pulled out more method families, where we had the same basic operation (described by the base name) and the argument labels differentiated how we got to that result.

… and we spent a while looking at the diff of Cocoa, here:

  Split before last preposition in most cases. · apple/swift-3-api-guidelines-review@b22b62b · GitHub

  - Doug

Thank you.

I’d love to see a response from the team as for my concerns in the post above — I wonder if the arguments were not compelling because I’ve missed something, or simply that the rationale _for_ prepositions inside the parens seemed stronger.

  (1) A prepositional phrase is a grammatical entity, and we probably shouldn’t split a grammatical phrase across ‘(‘.

A fair point — I guess I just don’t find it as important. Either way, it’s not an English sentence, only English-like.

  (3) Related to (2), it pulled out more method families, where we had the same basic operation (described by the base name) and the argument labels differentiated how we got to that result.

Any examples? How was that different from having a preposition just before the paren?

* * *

I’ve given the diff a look again, and I can now see how some methods look really nice after the change, and only some make me slightly uncomfortable.

func value(at index: Int) -> AnyObject!
func read(from url: URL, options: ….)
class func strokeLine(from point1: Point, to point2: Point)
func appendWithOval(in rect: Rect)
func sendAction(on mask: Int) -> Int
func rows(in rect: Rect) -> NSRange
func translateOrigin(to translation: Point)

I actually like those a lot! There’s no need to repeat parameter name/type information in argument label, because it’s going to be obvious in context on call site. But having a preposition, just alone by itself, actually is a nice thing in explaining the first argument and the method semantics.

What I’m not so sure about is when the preposition is glued to a noun. And I guess it’s largely because the noun seems to repeat type information that’s not needed for clarity at call site:

  func accessibilityFrame(forRange range: NSRange) -> Rect
  func fractionOfDistanceThroughGlyph(forPoint aPoint: Point) -> CGFloat
  func borderColor(forEdge edge: RectEdge) -> NSColor?
  func value(forDimension dimension: NSTextBlockDimension) -> CGFloat
  func cellFrame(forTextContainer textContainer: NSTextContainer, proposedLineFragment lineFrag: Rect, glyphPosition position: Point, characterIndex charIndex: Int) -> Rect

Why are here the nouns not trimmed like in the examples above?

I think:

  accessibilityFrame(for: someRange)
  fractionOfDistanceThroughGlyph(for: somePoint)
  borderColor(for: edge)
  value(for: someTextBlockDimension)
  cellFrame(for: someTextContainer, …)

Would also work. No?

In other cases, I’m bothered by the preposition glued to an argument label, because the preposition seems unnecessary:

  func copy(withZone zone: Zone = nil) -> AnyObject
  optional func shouldPerformSegue(withIdentifier identifier: String, sender: AnyObject?) -> Bool
  func statusItem(withLength length: CGFloat) -> NSStatusItem
  func instantiateController(withIdentifier identifier: String) -> AnyObject
  func performClickOnCell(atColumn column: Int, row: Int)

I guess this is mostly a problem with “with”s. The last example is more arguable — what bothers me there more is the inconsistent treatment of argument labels (first label starts with a preposition that conveys semantics for both parameters, and the second label is just a parameter name).

Best,
— Radek

···

On 11 Feb 2016, at 20:34, Douglas Gregor <dgregor@apple.com> wrote:

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

Hmm, looking at these I think it's really the “lonely ‘of’” that we want
to pull out of the parens, i.e.

        indexOf(x)

but not

        animal(ofGenus: .reptile)

···

on Thu Feb 11 2016, Douglas Gregor <dgregor-AT-apple.com> wrote:

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

on Thu Feb 11 2016, Charles Kissinger <swift-evolution@swift.org> wrote:

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”
;-)

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.)

That's nice! What do you think about moving “of” back out of the
parens? Does that help or hurt?

And lo!, a diff appeared!

  The preposition "of" binds to the word preceding it. · apple/swift-3-api-guidelines-review@3f96534 · GitHub

--
-Dave

I think they almost all read better with “of” inside the parens, except for ones that end up with a standalone “of", like this:

func column(of matrix: NSMatrix) -> Int
func columnOf(matrix: NSMatrix) -> Int

To my eyes the red line reads worse in this case.

Matt

···

On Feb 11, 2016, at 11:35, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

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

on Thu Feb 11 2016, Charles Kissinger <swift-evolution@swift.org> wrote:

That's nice! What do you think about moving “of” back out of the
parens? Does that help or hurt?

And lo!, a diff appeared!

  The preposition "of" binds to the word preceding it. · apple/swift-3-api-guidelines-review@3f96534 · GitHub

  - Doug

Huge improvement overall moving the 'of'. However, these and related
functions stand out as regressing in clarity:
'''
- class func userFont(ofSize fontSize: CGFloat) -> NSFont?
- class func userFixedPitchFont(ofSize fontSize: CGFloat) -> NSFont?
+ class func userFontOf(size fontSize: CGFloat) -> NSFont?
+ class func userFixedPitchFontOf(size fontSize: CGFloat) -> NSFont?
'''
My rationalization: here, 'of' is being used differently than in other
places. In fact, userFont(ofSize:) could be equally renamed
userFont(withSize:) or userFont(havingSize:).

···

On Thu, Feb 11, 2016 at 1:35 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

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

on Thu Feb 11 2016, Charles Kissinger <swift-evolution@swift.org> wrote:

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”
;-)

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.)

That's nice! What do you think about moving “of” back out of the
parens? Does that help or hurt?

And lo!, a diff appeared!

        The preposition "of" binds to the word preceding it. · apple/swift-3-api-guidelines-review@3f96534 · GitHub

        - Doug

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

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.

*Personally*, I don’t find the “with” to be compelling in either case. Presumably, it is implying that this is a “find” rather than a “create” operation, but I don’t consider “with” a good way to communicate that… the optional result type and lack of a verb like “add” or “insert” implies “find” stronger than “with”, IMO.

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.

When we were looking through the results, it seemed like cases where the preposition distributed to multiple arguments were fairly rare… rare enough that it didn’t seem worth complicating the rules or giving up the gains we got elsewhere from moving the prepositions inside.

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

A couple of reasons that I, personally, found motivating (some of which came up on this list before):

  (1) A prepositional phrase is a grammatical entity, and we probably shouldn’t split a grammatical phrase across ‘(‘.
  (2) It seemed to separate “what the method does” (base name) from “how it does it” (argument label) more effectively.
  (3) Related to (2), it pulled out more method families, where we had the same basic operation (described by the base name) and the argument labels differentiated how we got to that result.

… and we spent a while looking at the diff of Cocoa, here:

  https://github.com/apple/swift-3-api-guidelines-review/commit/b22b62bb98e5d44b2528b237d18efe96bf2940d6

  - Doug

Thank you.

I’d love to see a response from the team as for my concerns in the post above — I wonder if the arguments were not compelling because I’ve missed something, or simply that the rationale _for_ prepositions inside the parens seemed stronger.

  (1) A prepositional phrase is a grammatical entity, and we probably shouldn’t split a grammatical phrase across ‘(‘.

A fair point — I guess I just don’t find it as important. Either way, it’s not an English sentence, only English-like.

  (3) Related to (2), it pulled out more method families, where we had the same basic operation (described by the base name) and the argument labels differentiated how we got to that result.

Any examples? How was that different from having a preposition just before the paren?

Here’s a fun set of examples from NSGradient:

- func drawFrom(startingPoint: Point, to endingPoint: Point, options: NSGradientDrawingOptions)
- func drawIn(rect: Rect, angle: CGFloat)
- func drawIn(path: NSBezierPath, angle: CGFloat)
+ func draw(from startingPoint: Point, to endingPoint: Point, options: NSGradientDrawingOptions)
+ func draw(in rect: Rect, angle: CGFloat)
+ func draw(in path: NSBezierPath, angle: CGFloat)
    func drawFromCenter(startCenter: Point, radius startRadius: CGFloat, toCenter endCenter: Point, radius endRadius: CGFloat, options: NSGradientDrawingOptions)
- func drawIn(rect: Rect, relativeCenterPosition: Point)
- func drawIn(path: NSBezierPath, relativeCenterPosition: Point)
+ func draw(in rect: Rect, relativeCenterPosition: Point)
+ func draw(in path: NSBezierPath, relativeCenterPosition: Point)

* * *

I’ve given the diff a look again, and I can now see how some methods look really nice after the change, and only some make me slightly uncomfortable.

func value(at index: Int) -> AnyObject!
func read(from url: URL, options: ….)
class func strokeLine(from point1: Point, to point2: Point)
func appendWithOval(in rect: Rect)
func sendAction(on mask: Int) -> Int
func rows(in rect: Rect) -> NSRange
func translateOrigin(to translation: Point)

I actually like those a lot! There’s no need to repeat parameter name/type information in argument label, because it’s going to be obvious in context on call site. But having a preposition, just alone by itself, actually is a nice thing in explaining the first argument and the method semantics.

What I’m not so sure about is when the preposition is glued to a noun. And I guess it’s largely because the noun seems to repeat type information that’s not needed for clarity at call site:

  func accessibilityFrame(forRange range: NSRange) -> Rect
  func fractionOfDistanceThroughGlyph(forPoint aPoint: Point) -> CGFloat
  func borderColor(forEdge edge: RectEdge) -> NSColor?
  func value(forDimension dimension: NSTextBlockDimension) -> CGFloat
  func cellFrame(forTextContainer textContainer: NSTextContainer, proposedLineFragment lineFrag: Rect, glyphPosition position: Point, characterIndex charIndex: Int) -> Rect

Why are here the nouns not trimmed like in the examples above?

I had a ban on creating “vacuous” argument labels from long ago. It didn’t kick in much before, but I removed it in the follow-up commit to what you’re looking at:

  https://github.com/apple/swift-3-api-guidelines-review/commit/aaec8d0fe9cf82cd6f4088721cf8968a6ac69164

Essentially, all of those examples above end up with the argument label “for”.

I think:

  accessibilityFrame(for: someRange)
  fractionOfDistanceThroughGlyph(for: somePoint)
  borderColor(for: edge)
  value(for: someTextBlockDimension)
  cellFrame(for: someTextContainer, …)

Would also work. No?

Yep, the next commit ;)

In other cases, I’m bothered by the preposition glued to an argument label, because the preposition seems unnecessary:

  func copy(withZone zone: Zone = nil) -> AnyObject

Here, I feel like we need *a* label because we aren’t copying the first argument… we’re copying “self” and using the first argument. The second commit I referenced above would make this just “with”; I, personally, would prefer “coder” or something meaningful like “into”.

  optional func shouldPerformSegue(withIdentifier identifier: String, sender: AnyObject?) -> Bool
  func statusItem(withLength length: CGFloat) -> NSStatusItem
  func instantiateController(withIdentifier identifier: String) -> AnyObject

The “with”s don’t seem to add anything here.

  func performClickOnCell(atColumn column: Int, row: Int)

I guess this is mostly a problem with “with”s. The last example is more arguable — what bothers me there more is the inconsistent treatment of argument labels (first label starts with a preposition that conveys semantics for both parameters, and the second label is just a parameter name).

Here, the “at” distributes, but it’s also not needed for clarity. We’d be find with either

  func performClickOnCellAt(column: Int, row: Int)

or

  func performClickOnCell(column: Int, row: Int)

  - Doug

···

On Feb 11, 2016, at 2:29 PM, Radosław Pietruszewski <radexpl@gmail.com> wrote:

On 11 Feb 2016, at 20:34, Douglas Gregor <dgregor@apple.com <mailto:dgregor@apple.com>> wrote:

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

That was our reaction, too, pretty much.

···

on Thu Feb 11 2016, Radosław Pietruszewski <swift-evolution@swift.org> wrote:

I’ve given the diff a look again, and I can now see how some methods
look really nice after the change, and only some make me slightly
uncomfortable.

--
-Dave