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

Ross O'Brien narrativium at gmail.com
Fri Jan 22 18:12:42 CST 2016


How would we apply this to delegate patterns?
For example, would we keep tableview(tableView:cellForRowAtIndexPath:), or
would we switch to delegate(tableView:cellForRowAtIndexPath:) ?
Or perhaps better, for clarity over which protocol is being conformed to /
which property of the delegator is calling the function:
dataSource(tableView:cellForRowAtIndexPath:),
delegate(tableView:didSelectRowAtIndexPath:)

On Sat, Jan 23, 2016 at 12:00 AM, David Owens II via swift-evolution <
swift-evolution at swift.org> 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.
>
> 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).
>
> 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. 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. 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.
>
> 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.
>
>
> *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?
>
> As other have pointed out, this is also very hard to do all the time. I
> think the alternatives are worse. It would be nice if there were a way to
> annotate all member functions as mutating/non-mutating to really by-pass
> this ambiguity.
>
> Other than the above, the proposal looks pretty good to me.
>
> -David
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> 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/c051e538/attachment.html>


More information about the swift-evolution mailing list