<div dir="ltr"><div>I find arguments with prepositions easier to read, on the whole, even when they're not strictly necessary.<br><div><br></div><div>Even though, this code makes sense:<br></div><div><div><br></div><div><b> a.move_to( b )</b></div><div><b><br></b></div><div><b> draw_line( origin: b, conclusion: c )</b></div><div><br></div><div>I'd prefer to see this:</div><div><br></div><div><div><b> a.move( to_point: b )</b></div><div><b><br></b></div><div><b> draw_line( from_point: b, to_point: c )</b></div></div><div><br></div><div>Similarly, for the example "<b>a.read_from( u, of_type: b )</b>" I find this easier to read:</div><div><br></div><div><b> a.read( from_url: u, from_type: b)</b><br></div><br></div><div>Which makes it easier to understand if it's followed by:</div><div><br></div><div><b> a.read( from_url: u, <font color="#ff0000">to</font>_type: b)<br></b></div></div><div><br></div><div>I find it helpful in my own code. Having said that, I'm not sure if it would suit huge multi-person projects, since it leads to a lot of similarly named functions.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 2, 2016 at 4:32 PM, Dave Abrahams via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
This thread is related to the review of new API guidelines, but it's not<br>
a review thread; it's exploratory. The goal is to come up with<br>
guidelines that:<br>
<br>
* describe when and where to use argument labels<br>
* require labels in many of the cases people have asked for them<br>
* are understandable by humans<br>
* preserve important semantics communicated by existing APIs.<br>
<br>
Here's what I'm thinking<br>
<br>
1. If and only if the first argument could complete a sentence*<br>
beginning in the base name and describing the primary semantics of<br>
the call, it gets no argument label:<br>
<br>
a.contains(b) // b completes the phrase "a contains b"<br>
a.mergeWith(b) // b completes the phrase "merge with b"<br>
<br>
a.dismiss(animated: b) // "a, dismiss b" is a sentence but<br>
// doesn't describe the semantics at all,<br>
// thus we add a label for b.<br>
<br>
a.moveTo(x: 300, y: 400) // "a, move to 300" is a sentence<br>
// but doesn't describe the primary<br>
// semantics, which are to move in both<br>
// x and y. Thus, x gets a label.<br>
<br>
a.readFrom(u, ofType: b) // "a, read from u" describes<br>
// the primary semantics, so u gets no<br>
// label. b is an<br>
// option that tunes the primary<br>
// semantics<br>
<br>
[Note that this covers all the direct object cases and, I believe,<br>
all the default argument cases too, so maybe that exception can be<br>
dropped. We still need the exceptions for full-width type<br>
conversions and indistinguishable peers]<br>
<br>
Note: when there is a noun in the base name describing the role of the<br>
first argument, we skip it in considering this criterion:<br>
<br>
a.addObserver(b) // "a, add b" completes a sentence describing<br>
// the semantics. "Observer" is omitted in<br>
// making this determination.<br>
<br>
* We could say "clause" here but I think making it an *independent*<br>
clause doesn't rule out any important use-cases (see<br>
<a href="https://web.cn.edu/kwheeler/gram_clauses_n_phrases.html" rel="noreferrer" target="_blank">https://web.cn.edu/kwheeler/gram_clauses_n_phrases.html</a>) and at that<br>
point, you might as well say "sentence," which is a more<br>
universally-understood term.<br>
<br>
2. Words that describe attributes of an *already-existing* instance<br>
should go in the base name rather than in a label:<br>
<br>
a.tracksHavingMediaType("Wax Cylinder") // yes<br>
a.removeFirstTrackHavingMediaType("BetaMax") // yes<br>
<br>
a.tracks(mediaType: "Wax Cylinder") // no<br>
a.removeFirstTrack(havingMediaType: "BetaMax") // no<br>
<br>
[yes, we could use "With" instead of "Having", but it's more<br>
ambiguous]<br>
<br>
Words that describe attributes of an instance *to be created* should<br>
go in argument labels, rather than the base name (for parity with<br>
initializers):<br>
<br>
AudioTrack(mediaType: "BetaMax") // initializer<br>
trackFactory.newTrack(mediaType: "Wax Cylinder") // yes<br>
<br>
trackFactory.newTrackWithMediaType("Wax Cylinder") // no<br>
<br>
3. (this one is separable) When the first argument is the *name* or<br>
*identifier* of the subject in the base name, do not label it or<br>
describe it in the base name.<br>
<br>
a.transitionToScene(.GreatHall) // yes<br>
a.transitionToSceneWithIdentifier(.GreatHall) // no<br>
<br>
let p = someFont.glyph("propellor") // yes<br>
let p = someFont.glyphWithName("propellor") // no<br>
let p = someFont.glyph(name: "propellor") // no<br>
<br>
Thoughts?<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
-Dave<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</font></span></blockquote></div><br></div>