[swift-evolution] API Guidelines Update

Dave Abrahams dabrahams at apple.com
Wed Feb 24 13:25:18 CST 2016


on Wed Feb 24 2016, David Owens II <swift-evolution at swift.org> wrote:

>> On Feb 22, 2016, at 11:02 AM, Jordan Rose via swift-evolution
>> <swift-evolution at swift.org> wrote:
>> 
>> In case it's been lost in all the discussion, the -ing/-ed rule is
>> essentially the rule Objective-C uses, minus the noun labels for the
>> return value and types and the word "by". It's definitely very
>> different grammatically from most other API guidelines, but so are
>> Objective-C's guidelines.
>> 
>
> Sure, but I'd actually argue that the noun-labels in ObjC are what
> actually provide the context of the non-mutating nature of the
> function. 

I disagree with that assertion.  The nouns tell you what type is going
to be returned and what type is being passed, not whether there will be
mutation to the receiver.

> The -ed/-ing suffixes are a by-product of the preceding noun-phrase
> and/or trailing preposition.
>
> stringByTrimmingCharactersInSet(_:)
>
> We are taking information about the returned data out of the function
> name and assuming that the return type makes up for it.

The return type and context, yes.  
> trimming(_:)
>
> For a string-type, that may be ok, but I'd argue that `trimming` is
> significantly more ambiguous that the ObjC version. There is no
> reasonable assumption that `stringByTrimmingCharactersInSet` would
> ever mutate the caller. However, `trimming` carries no such
> implication _unless_ you are well versed in the API guidelines, 

I disagree with that assertion.  We didn't invent that usage out of thin
air; it's based on regular English usage.  Neither of these names really
directly addresses mutation at all; to do that you'd have to append
"WithoutChangingSelf" or something.

It seems like you may (quite reasonably) associate having a return value
with being non-mutating, and you may be making the conclusion that
removing information about the return type removes any implication that
there *is* a returned value.  But there are still lots of clues left
about that:

* the call forms a noun phrase, therefore must be non-side-effectful, so
  to be useful must return something.
* unused result warnings ensure that the fact that it returns a value is
  quite visible at the call site.

> and even then, I'd still argue that your confidence level between the
> two versions is not equal.

I understand that you may be less confident with APIs written according
to the new guidelines.

> A counter example for -ing usage: if we have a streaming-type and
> `trimming` is actually the process for continually removing those
> characters from the stream. The likely implementation of this is going
> to be a mutating function that fires events, or maybe it's a
> promise-like API that wraps the event handling differently. The
> corollary is that `trim` would actually be the one that produces no
> side-effects as it would be able to give a snapshot of the current
> state of a trimmed stream.

I don't believe this is actually a confusable scenario; please show us
what that code looks like.

> I think we are opening ourselves up to the potential of many confusing
> APIs when an -ed/-ing form of a function name is an appropriate
> candidate with the opposite meaning that the guidelines set out.
>
> The -ed/-ing suffix choice doesn't seem outright bad, but it does seem
> to be "death by paper cuts" bad, at least to me. The guidelines are
> already a bit complicated in this area. Also, like others, I find the
> -ing suffix to imply a state of work to be done that will be completed
> later or cover an extended amount of time; mutation has no bearing on
> the implementation choice here.
>
> Side note: the guidelines are also unintentionally narrow: "Use the
> “ed/ing” rule to name the nonmutating counterpart of a mutating
> method."
>
> We should *always* be following this pattern regardless of the
> existence of a nonmutating counterpart. Otherwise, if you implement
> just a non-mutating function for sorting without the counterpart, you
> need to use a noun-phrase, like `sortBy`. Then if you later add a
> mutating version, you need to rename the `sortBy` to `sorted`. That
> seems like the wrong outcome of the guidelines.

I think you're confused: `sortBy(x)`—or more properly, `sort(by:
x)`—isn't a noun-phrase; it's an imperative verb phrase, so it would be
an ineligible form for a nonmutating method call.

-- 
-Dave



More information about the swift-evolution mailing list