[swift-evolution] [Review] SE-0023 API Design Guidelines

J. Cheyo Jimenez cheyo at masters3d.com
Sat Jan 23 14:44:13 CST 2016


The inPlace proposal is excellent. As suggested something like x.=f() would
be perfect to distinguish mutating methods .Something I don't like from the
API design guidelines is that non mutating methods like enumerate would be
become enumerated. In my mind enumerate is a word of art and I don't ever
think of it as muting so having to always use enumerated in the future
seems weird. Also having to ed/ing non mutating methods seems to make
mutating methods more important.

//non mutating suggestion
x.sort()
x.split()

//other ideas for mutating methods names
x.sort*()
x.sort&() // I like & the most
x.split&()
x.sort@()

By marking a method with a special character at the end, the reader would
know that the method mutates.

On Saturday, January 23, 2016, Dave Abrahams via swift-evolution <
swift-evolution at swift.org> wrote:

>
> on Fri Jan 22 2016, David Owens II <swift-evolution at swift.org
> <javascript:;>> wrote:
>
> >> Compensate For Weak Type Information as needed to clarify a parameter’s
> role.
> >>
> >> Especially when a parameter type is NSObject, Any, AnyObject, or a
> >> fundamental type such Int or String, type information and context at
> >> the point of use may not fully convey intent. In this example, the
> >> declaration may be clear, but the use site is vague:
> >>
> >> func add(observer: NSObject, for keyPath: String)
> >> grid.add(self, for: graphics) // vague
> >>
> >> To restore clarity, precede each weakly-typed parameter with a noun
> describing its role:
> >>
> >> func addObserver(_ observer: NSObject, forKeyPath path: String)
> >> grid.addObserver(self, forKeyPath: graphics) // clear
> >
> > I don’t understand why to compensate for weak type information we put
> > some of that compensation in the name of the function and other parts
> > of it in the [external] name of the parameter.
>
> IIUC, some people feel strongly that it would be really strange and
> nonuniform to have a substantial fraction of methods with an argument
> label on the first argument unless that percentage was nearly 100.
>
> [I don't know whether there's an "official terminology" for these names,
> but we've been calling them "argument labels" in the naming discussions.
> Note that the ("internal") parameter names aren't strictly internal as
> they get used in documentation comments, and should be chosen
> accordingly.  So, I'm using the terms "argument label" and "parameter
> name".]
>
> > If we were going to reference functions like this:
> > addObserver:forKeyPath, then I can understand it. But that’s not the
> > plan of record, it’s to do this: addObserver(_:forKeyPath).
>
> That's an interesting argument.
>
> > Regardless of the default naming scheme, it seems like the rule should
> > be to use external names to clarify that parameters role.
> >
> > func add(observer observer: NSObject, forKeyPath path: String)
> > grid.add(observer: self, forKeyPath: graphics)
> >
> > This promotes a very clear and consistent rule: weak type information
> > should be clarified by the parameter’s external name. There are no
> > exceptions for the first parameter.
>
> That seems very clean to me.
>
> > Otherwise, it seems like there is super fine line between this rule
> > and the next one below.
> >
> > Additionally, this also alleviates my concerns with the default
> > parameter have _ as the external name by default because this
> > addresses the case when it would be desirable to have that
> > name.
>
> Sorry, I don't understand what you're getting at here.
>
> > Further, the case below handles the case when it’s not.
> >
> >> Omit Needless Words. Every word in a name should convey salient
> information at the use site.
> >>
> >> More words may be needed to clarify intent or disambiguate meaning,
> >> but those that are redundant with information the reader already
> >> possesses should be omitted. In particular, omit words that merely
> >> repeat type information:
> >>
> >> public mutating func removeElement(member: Element) -> Element?
> >> allViews.removeElement(cancelButton)
> >>
> >> In this case, the word Element adds nothing salient at the call site.
> This API would be better:
> >>
> >> public mutating func remove(member: Element) -> Element?
> >> allViews.remove(cancelButton) // clearer
> >>
> >> Occasionally, repeating type information is necessary to avoid
> >> ambiguity, but in general it is better to use a word that describes
> >> a parameter’s role rather than its type. See the next item for
> >> details.
> >
> > The description here seems to overlap with the “Compensate for Weak
> > Type Information” rule, especially with the clause: “repeating type
> > information”. It may be better to re-work the example to be
> > `removeItem(member: Element)` to make this distinction more clear that
> > it’s not type information being removed.
>
> Oh, great point!
>
> > Also, by clarifying that statement, the above rule change I suggested
> > would be consistent. Type information clarification goes into the
> > external parameter name, functionality clarification goes into the
> > function name. Those are hard-n-fast rules that are straight-forward.
>
> I like 'em, FWIW.
>
> >> Be Grammatical
> >>
> >> When a mutating method is described by a verb, name its non-mutating
> >> counterpart according to the “ed/ing” rule, e.g. the non-mutating
> >> versions of x.sort() and x.append(y) are x.sorted() and
> >> x.appending(y).
> >
> > Is this guideline suggesting that we should design our APIs to
> > generally have both mutating and non-mutaging counterparts?
>
> Definitely not.
>
> > As other have pointed out, this is also very hard to do all the
> > time. I think the alternatives are worse.
>
> The alternatives to always creating mutating/nonmutating pairs?  What
> alternatives have you considered, and what do you see the consequences
> to be?
>
> > It would be nice if there were a way to annotate all member functions
> > as mutating/non-mutating to really by-pass this ambiguity.
>
> I don't know what you mean by that.  Can you explain?
>
> FWIW, there are potential language-level approaches to this problem
> (e.g.
> https://github.com/apple/swift/blob/master/docs/proposals/Inplace.rst),
> but in the absence of language features, it's something we need a
> convention for.
>
> --
> -Dave
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160123/bd18520c/attachment.html>


More information about the swift-evolution mailing list