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

Dave Abrahams dabrahams at apple.com
Sun Jan 24 14:43:48 CST 2016


on Sat Jan 23 2016, Erica Sadun <swift-evolution at swift.org> wrote:

> Dave,
>
> I typoed on the second and I was insufficiently clear on my point. Trying again:
>
> Prefer external names for the first parameter when the natural
> semantic relationship between the parameters is stronger than their
> relation to the operation. 
>
> For example, the following calls use labels for the first parameter:
>
> login(userName: "blah", password: "...")
> moveTo(x: 50.0, y: 30.0)
>
> This example is contrary to Swift's normal naming scheme which integrates the
> first argument into the function or method name, for example:
>
> loginWithUserName("blah", password: "...")
> moveToX(50.0, y: 30.0)
>
> The coupling between x and y, username and password, (and yes it is a judgement call) 
> should be considered as a reason to employ an external label.

Yeah, I understand what you're going for, but it doesn't seem very crisp
to me.  Personally, I think Rob Mayoff's suggestion

  loginAs(me, password: mySecret)

is pretty awesome.  Fundamentally, the username is driving the call, and
the password is a piece of dependent information you have to match up to
it.

> I had included the following as a counter example:
>
> addLineToPoint(p1, withWidth: 25.0)
>
> In this call, the point and width have no natural or compelling relationship and there's no reason to
> create an external label for the first argument. This example follows the standard
> Swift call approach.

Up to now, there has been no "standard Swift call approach," so I don't
know what this means.

> Differentiate related calls whose implementations are distinguished by their
> parameters, as you would with initializers, using first parameter labels.
>
> Instead of loginWithUserName("blah", password: "...") and loginWithCredential(myCredential),
> prefer:
>
> login(userName: "blah", password: "...")
> login(credential: myCredential)

So, how does this proposal improve understandability of use-sites?

> And to reply to another point raised in-thread:
>
> When working with standard library calls, retain APIs even if they are
> not sufficiently clear from a Swift design perspective rather than
> wrapping-the-cat to provide a Swift interface that doesn't really
> exist. (As the call is just a redirection.)
>
> For example, prefer
>
> let x = pow(2.0, 5.0)
>
> to
>
> let x = raise(2.0, toPower: 5.0)
>
> In this example, the two arguments for pow are not specified as this call is sourced
> externally and follows the naming convention for math.h.

This idea is already captured in the guidelines; the reasons to use
"pow(x, y)" are the same as the reasons to use "sin(x)".

-- 
-Dave



More information about the swift-evolution mailing list