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

Huh, I’m not sure why it’s showing up as drawFromCenter in that paste. If I go to the source at:

  https://github.com/apple/swift-3-api-guidelines-review/blob/swift-3/Platforms/OSX/AppKit/NSGradient.swift

there’s a big “draw” family that pops out:

  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 draw(fromCenter startCenter: Point, radius startRadius: CGFloat, toCenter endCenter: Point, radius endRadius: CGFloat, options: NSGradientDrawingOptions)
  func draw(in rect: Rect, relativeCenterPosition: Point)
  func draw(in path: NSBezierPath, relativeCenterPosition: Point)

  - Doug

···

On Feb 11, 2016, at 5:50 PM, Matthew Judge <matthew.judge@gmail.com> wrote:

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

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)

Why isn't this:
func draw(fromCenter startCenter: Point, radius startRadius: CGFloat, toCenter endCenter: Point, radius endRadius: CGFloat, options: NSGradientDrawingOptions)

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:

  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?

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)

Why isn't this:
func draw(fromCenter startCenter: Point, radius startRadius: CGFloat, toCenter endCenter: Point, radius endRadius: CGFloat, options: NSGradientDrawingOptions)

···

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

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

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

- 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

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

Ha, true, being both a noun and a verb doesn’t help. Still, it’s not that uncommon — this might be a particularly tricky API, and I tend to agree — but mostly it’s an issue of how initializer/getter-like are named. There’s _a lot_ of method names that are just nouns — which is a large part of the “prepositions being useful” problem.

— Radek

···

On 11 Feb 2016, at 23:18, Charles Kissinger <crk@akkyra.com> wrote:

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

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

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.

I agree, though I thought it was better than nothing.

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)

Ah, neat. Probably uncommon overall, but I can see the advantage here, yeah.

* * *

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:

  Stop preventing argument labels named "for", "with", or other vacuous… · apple/swift-3-api-guidelines-review@aaec8d0 · GitHub

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

Ah, nice! That actually helps a lot, and seeing this and other refinements I’m more and more on board with the “prepositions inside parens” idea :)

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)

Yep, both seem good to me.

— Radek

···

On 12 Feb 2016, at 00:19, Douglas Gregor <dgregor@apple.com> wrote:

On Feb 11, 2016, at 2:29 PM, Radosław Pietruszewski <radexpl@gmail.com <mailto: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:

+1. It's not whether the "of" is on its own or not, it's whether it's describing the base noun or extracting something from it.

NSFont.userFont(ofSize: bestSizeForThursdays)
tiffFile.removeImageRepresentation(ofSize: CGSize(width: 16, height: 16)) // hypothetical, importer default would be "of:" but that looks wrong

vs.

items.appendContentsOf(newItems)
tabView.frameOf(subview: contentView) // hypothetical, could go either way?

Jordan

···

On Feb 11, 2016, at 11:57, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

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

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

+1. It's not whether the "of" is on its own or not, it's whether it's
describing the base noun or extracting something from it.

Yes, the point is that we are not sure how to reliably detect the
difference, and the “lonely of” approach makes for a very close
approximation.

···

on Thu Feb 11 2016, Jordan Rose <jordan_rose-AT-apple.com> wrote:

NSFont.userFont(ofSize: bestSizeForThursdays)
tiffFile.removeImageRepresentation(ofSize: CGSize(width: 16, height:
16)) // hypothetical, importer default would be "of:" but that looks
wrong

vs.

items.appendContentsOf(newItems)
tabView.frameOf(subview: contentView) // hypothetical, could go either way?

Jordan

On Feb 11, 2016, at 11:57, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

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

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

--
-Dave

I'd also guess the "of-meaning-having" cases are quite rare.

Jordan

···

On Feb 11, 2016, at 13:24, Dave Abrahams <dabrahams@apple.com> wrote:

on Thu Feb 11 2016, Jordan Rose <jordan_rose-AT-apple.com <http://at-apple.com/&gt;&gt; wrote:

+1. It's not whether the "of" is on its own or not, it's whether it's
describing the base noun or extracting something from it.

Yes, the point is that we are not sure how to reliably detect the
difference, and the “lonely of” approach makes for a very close
approximation.

Lonely “of”s move to the base name:

  Only move "lonely of" arguments back to the base name. · apple/swift-3-api-guidelines-review@f9cb1c4 · GitHub

  - Doug

···

On Feb 11, 2016, at 11:57 AM, Dave Abrahams <dabrahams@apple.com> wrote:

on Thu Feb 11 2016, Douglas Gregor <dgregor-AT-apple.com <http://dgregor-at-apple.com/&gt;&gt; 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

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)

I'm in the “only move the lonely of” camp.

—CK

···

On Feb 11, 2016, at 1:26 PM, Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 11, 2016, at 13:24, Dave Abrahams <dabrahams@apple.com <mailto:dabrahams@apple.com>> wrote:

on Thu Feb 11 2016, Jordan Rose <jordan_rose-AT-apple.com <http://at-apple.com/&gt;&gt; wrote:

+1. It's not whether the "of" is on its own or not, it's whether it's
describing the base noun or extracting something from it.

Yes, the point is that we are not sure how to reliably detect the
difference, and the “lonely of” approach makes for a very close
approximation.

I'd also guess the "of-meaning-having" cases are quite rare.

Jordan

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

[snip]

mostly it’s an issue of how initializer/getter-like are named. There’s _a lot_ of method names that are just nouns — which is a large part of the “prepositions being useful” problem.

I personally don’t have a problem with get… and set… method names, but I doubt that would be popular with the majority.

—CK

···

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

— Radek

`get` is usually in the wild as a getter of a property, i.e. taking no parameters. That’s not a problem — you can just skip “get” and there’s generally no confusion. Or just make it a property if possible. The cases I was describing were mostly factories/initializer-like (so I’d suggest “makeFoo” for new APIs), or finder-like (“findTrack”)

— Radek

···

On 12 Feb 2016, at 00:13, Charles Kissinger <crk@akkyra.com> wrote:

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

[snip]

mostly it’s an issue of how initializer/getter-like are named. There’s _a lot_ of method names that are just nouns — which is a large part of the “prepositions being useful” problem.

I personally don’t have a problem with get… and set… method names, but I doubt that would be popular with the majority.

A few random finds/thoughts:

- func magnifyToFit(rect: Rect)
+ func magnify(toFit rect: Rect)

Intentional? I guess it could be argued either way, but “magnify-to-fit” seems like one phrase.

* * *

Are those guidelines and automatic translations open for further changes and refinement after Swift 3 is released? It will be a *big* change and messing with it further could be painful, but I fear that there’s stuff we might be missing and insights we’ll only have after we start using all this in practice. It would be a shame to freeze it forever if that happens…

* * *

(NSArray)
+ func description(withLocale locale: AnyObject?) -> String
+ func description(withLocale locale: AnyObject?, indent level: Int) -> String

Another case where `with` doesn’t add anything IMHO and in fact makes things slightly confusing. The description isn’t somehow made *with* the locale, it’s just a variant of the `description` property that takes a locale as an setting.

* * *

- optional func scrollViewShouldScrollTo(top scrollView: UIScrollView) -> Bool
+ optional func scrollViewShouldScroll(toTop scrollView: UIScrollView) -> Bool
   @available(iOS 2.0, *)
- optional func scrollViewDidScrollTo(top scrollView: UIScrollView)
+ optional func scrollViewDidScroll(toTop scrollView: UIScrollView)

Similar case as “magnify to fit”. the scroll view has nothing to do with “toTop”. It should be:

scrollViewDidScrollToTop(_: UIScrollView)

* * *

I said that in the previous post, but I’ll say it again: looking at the full diff with the refinements applied since the first draft in this thread, I’m really coming around to this proposal. There are still some cases that make me a bit uncomfortable, but it passes the test of “as good as possible, but with fewest results I can’t live with”. So that’s +1 from me ;-)

* * *

PS. If someone wants to see the full diff between the pre-prepositions-inside-parens draft and the latest draft:

curl https://github.com/apple/swift-3-api-guidelines-review/compare/eeca3ac...swift-3.diff | mate

(or your favorite editor of choice. GH doesn’t show the *full* highlighted diff, and unhighlighted diff is hard to read.)

— Radek

···

On 13 Feb 2016, at 11:23, Radosław Pietruszewski <radexpl@gmail.com> wrote:

On 12 Feb 2016, at 00:19, Douglas Gregor <dgregor@apple.com <mailto:dgregor@apple.com>> wrote:

On Feb 11, 2016, at 2:29 PM, Radosław Pietruszewski <radexpl@gmail.com <mailto: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:

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.

I agree, though I thought it was better than nothing.

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)

Ah, neat. Probably uncommon overall, but I can see the advantage here, yeah.

* * *

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:

  Stop preventing argument labels named "for", "with", or other vacuous… · apple/swift-3-api-guidelines-review@aaec8d0 · GitHub

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

Ah, nice! That actually helps a lot, and seeing this and other refinements I’m more and more on board with the “prepositions inside parens” idea :)

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)

Yep, both seem good to me.

— Radek

We've lost consistency between "indexOf(_ object:)", "indexOfObjects(_
opts: passingTest:)" and "indexes(ofObjectsPassingTest:)".

Also, what about "lonely to"? Are folks okay with
"indexOfObjectIdentical(to: x)" ?

Jacob

···

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

On Feb 11, 2016, at 11:57 AM, Dave Abrahams <dabrahams@apple.com> wrote:

on Thu Feb 11 2016, Douglas Gregor <dgregor-AT-apple.com > <http://dgregor-at-apple.com/&gt;&gt; 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

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)

Lonely “of”s move to the base name:

Only move "lonely of" arguments back to the base name. · apple/swift-3-api-guidelines-review@f9cb1c4 · GitHub

- Doug

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

Doug and I reviewed these, and we don't think they work. The right
criterion for cocoa seems to be “pull ‘of’ into the base name unless—as
Jordan suggested—it means “having.”

Fortunately that seems to be easily determined. After looking at all
the APIs in Cocoa, “of” in the base name means “having” exactly when it
is followed by one of the following words: “type,” “types,” “kind,”
“size,” “length,” and maybe “stage” (we're trying to analyze
removeModifiersOfStage
<https://developer.apple.com/library/mac/documentation/SceneKit/Reference/SCNParticleSystem_Class/#//apple_ref/doc/uid/TP40014177-CH1-SW132&gt;
to figure out how “of”is being used—assistance welcome).

···

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

On Feb 11, 2016, at 11:57 AM, Dave Abrahams <dabrahams@apple.com> wrote:

on Thu Feb 11 2016, Douglas Gregor <dgregor-AT-apple.com <http://dgregor-at-apple.com/&gt;&gt; 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

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)

Lonely “of”s move to the base name:

  Only move "lonely of" arguments back to the base name. · apple/swift-3-api-guidelines-review@f9cb1c4 · GitHub

--
-Dave

A few random finds/thoughts:

- func magnifyToFit(rect: Rect)
+ func magnify(toFit rect: Rect)

Intentional? I guess it could be argued either way, but “magnify-to-fit” seems like one phrase.

It's all heuristic-based; there are very few one-off APIs that have
“intentional” results. We expect to have quite a few things that “could
be argued either way,” but in this case I prefer the result we got, FWIW.

* * *

Are those guidelines and automatic translations open for further
changes and refinement after Swift 3 is released? It will be a *big*
change and messing with it further could be painful, but I fear that
there’s stuff we might be missing and insights we’ll only have after
we start using all this in practice. It would be a shame to freeze it
forever if that happens…

Yes, we expect some flux after this lands.

* * *

(NSArray)
+ func description(withLocale locale: AnyObject?) -> String
+ func description(withLocale locale: AnyObject?, indent level: Int) -> String

Another case where `with` doesn’t add anything IMHO and in fact makes
things slightly confusing. The description isn’t somehow made *with*
the locale, it’s just a variant of the `description` property that
takes a locale as an setting.

Yes, the current plan is that we'll audit these and “manually” remove
the vacuous “with”s.

* * *

- optional func scrollViewShouldScrollTo(top scrollView: UIScrollView) -> Bool
+ optional func scrollViewShouldScroll(toTop scrollView: UIScrollView) -> Bool
   @available(iOS 2.0, *)
- optional func scrollViewDidScrollTo(top scrollView: UIScrollView)
+ optional func scrollViewDidScroll(toTop scrollView: UIScrollView)

Similar case as “magnify to fit”. the scroll view has nothing to do with “toTop”. It should be:

scrollViewDidScrollToTop(_: UIScrollView)

Yup. NS_SWIFT_NAME, I guess.

···

on Sat Feb 13 2016, Radosław Pietruszewski <radexpl-AT-gmail.com> wrote:

* * *

I said that in the previous post, but I’ll say it again: looking at
the full diff with the refinements applied since the first draft in
this thread, I’m really coming around to this proposal. There are
still some cases that make me a bit uncomfortable, but it passes the
test of “as good as possible, but with fewest results I can’t live
with”. So that’s +1 from me ;-)

* * *

PS. If someone wants to see the full diff between the
pre-prepositions-inside-parens draft and the latest draft:

curl https://github.com/apple/swift-3-api-guidelines-review/compare/eeca3ac...swift-3.diff | mate

(or your favorite editor of choice. GH doesn’t show the *full*
highlighted diff, and unhighlighted diff is hard to read.)

— Radek

On 13 Feb 2016, at 11:23, Radosław Pietruszewski <radexpl@gmail.com> wrote:

On 12 Feb 2016, at 00:19, Douglas Gregor <dgregor@apple.com <mailto:dgregor@apple.com>> wrote:

On Feb 11, 2016, at 2:29 PM, Radosław Pietruszewski >>>> <radexpl@gmail.com <mailto: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:

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.

I agree, though I thought it was better than nothing.

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)

Ah, neat. Probably uncommon overall, but I can see the advantage here, yeah.

* * *

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:

  Stop preventing argument labels named "for", "with", or other vacuous… · apple/swift-3-api-guidelines-review@aaec8d0 · GitHub
<https://github.com/apple/swift-3-api-guidelines-review/commit/aaec8d0fe9cf82cd6f4088721cf8968a6ac69164&gt;

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

Ah, nice! That actually helps a lot, and seeing this and other
refinements I’m more and more on board with the “prepositions inside
parens” idea :)

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)

Yep, both seem good to me.

— Radek

--
-Dave

Hi all,
I reviewed the changes and I feel positive about them in general. For whatever it’s worth, I like them.
There were some changes in Core Data for example where the with preposition is used in other parameters in addition to the first one. I thought only the first parameter label was to use the with preposition. For example, I think I would remove the forObjectWith and the withContext labels and keep objectID and context as the labels:
+ func newValue(forRelationship relationship: NSRelationshipDescription, forObjectWith objectID: NSManagedObjectID, withContext context: NSManagedObjectContext?) throws -> AnyObject
Thanks
Ricardo Parada

···

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

- func magnifyToFit(rect: Rect)
+ func magnify(toFit rect: Rect)

Intentional? I guess it could be argued either way, but “magnify-to-fit” seems like one phrase.

I prefer the change; to me “magnify” is the operation, the rectangle just happens to be what controls the result. It makes sense IMO that there could be other magnify operations with different requirements.

(NSArray)
+ func description(withLocale locale: AnyObject?) -> String
+ func description(withLocale locale: AnyObject?, indent level: Int) -> String

Another case where `with` doesn’t add anything IMHO and in fact makes things slightly confusing. The description isn’t somehow made *with* the locale, it’s just a variant of the `description` property that takes a locale as an setting.

I suppose in this case withLocale might be clearer as forLocale or withinLocale or something along those lines?

- optional func scrollViewShouldScrollTo(top scrollView: UIScrollView) -> Bool
+ optional func scrollViewShouldScroll(toTop scrollView: UIScrollView) -> Bool
   @available(iOS 2.0, *)
- optional func scrollViewDidScrollTo(top scrollView: UIScrollView)
+ optional func scrollViewDidScroll(toTop scrollView: UIScrollView)

Similar case as “magnify to fit”. the scroll view has nothing to do with “toTop”. It should be:

I think in this case it’s less clear than magnify, as it’s a bit of a weird pattern to begin with. It depends really on whether you feel that scrollViewShouldScroll is a discrete event that could potentially have different parameters (e.g- toBottom etc.) in which case it’s a good distinction to have. Not nearly as clear to me as magnify though, it’s not a style of callback that I like at all =)

···

On 13 Feb 2016, at 10:51, Radosław Pietruszewski via swift-evolution <swift-evolution@swift.org> wrote:

We've lost consistency between "indexOf(_ object:)", "indexOfObjects(_ opts: passingTest:)" and "indexes(ofObjectsPassingTest:)".

Also, what about "lonely to"? Are folks okay with "indexOfObjectIdentical(to: x)” ?

I don’t know if that’s a “lonely to” rule or whether “IdenticalTo” might be some kind of extended preposition, like “CompatibleWith”, where you want to treat the whole thing as a preposition.

  - Doug

···

On Feb 11, 2016, at 1:44 PM, Jacob Bandes-Storch <jtbandes@gmail.com> wrote:

Jacob

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

On Feb 11, 2016, at 11:57 AM, Dave Abrahams <dabrahams@apple.com <mailto:dabrahams@apple.com>> wrote:

on Thu Feb 11 2016, Douglas Gregor <dgregor-AT-apple.com <http://dgregor-at-apple.com/&gt;&gt; wrote:

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

on Thu Feb 11 2016, Charles Kissinger <swift-evolution@swift.org <mailto: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

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)

Lonely “of”s move to the base name:

  Only move "lonely of" arguments back to the base name. · apple/swift-3-api-guidelines-review@f9cb1c4 · GitHub

  - Doug

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

  - Doug

···

On Feb 11, 2016, at 4:00 PM, Dave Abrahams <dabrahams@apple.com> wrote:

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

On Feb 11, 2016, at 11:57 AM, Dave Abrahams <dabrahams@apple.com> wrote:

on Thu Feb 11 2016, Douglas Gregor <dgregor-AT-apple.com <http://dgregor-at-apple.com/&gt;&gt; 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

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)

Lonely “of”s move to the base name:

  Only move "lonely of" arguments back to the base name. · apple/swift-3-api-guidelines-review@f9cb1c4 · GitHub

Doug and I reviewed these, and we don't think they work. The right
criterion for cocoa seems to be “pull ‘of’ into the base name unless—as
Jordan suggested—it means “having.”

Fortunately that seems to be easily determined. After looking at all
the APIs in Cocoa, “of” in the base name means “having” exactly when it
is followed by one of the following words: “type,” “types,” “kind,”
“size,” “length,” and maybe “stage” (we're trying to analyze
removeModifiersOfStage
<https://developer.apple.com/library/mac/documentation/SceneKit/Reference/SCNParticleSystem_Class/#//apple_ref/doc/uid/TP40014177-CH1-SW132&gt;
to figure out how “of”is being used—assistance welcome).

As usual, I object to hardcoded supposedly-exhaustive lists. I'd rather have people fix these up manually with NS_SWIFT_NAME and such.

Given that the parallel to -removeModifiersOfStage: is -addModifierForProperties:atStage:withBlock:, I think the stage is not being treated as part of the modifier.

Jordan

···

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

Doug and I reviewed these, and we don't think they work. The right
criterion for cocoa seems to be “pull ‘of’ into the base name unless—as
Jordan suggested—it means “having.”

Fortunately that seems to be easily determined. After looking at all
the APIs in Cocoa, “of” in the base name means “having” exactly when it
is followed by one of the following words: “type,” “types,” “kind,”
“size,” “length,” and maybe “stage” (we're trying to analyze
removeModifiersOfStage
<https://developer.apple.com/library/mac/documentation/SceneKit/Reference/SCNParticleSystem_Class/#//apple_ref/doc/uid/TP40014177-CH1-SW132&gt;
to figure out how “of”is being used—assistance welcome).