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

Tyler Fleming Cloutier cloutiertyler at aol.com
Sun Jan 24 18:01:14 CST 2016


> On Jan 24, 2016, at 12:43 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> 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)”.

I’m going to actually make the argument here that `pow` would be much clearer as `raise(_:toPower:)`.

The main reason is that if I want to convert this to a method with mutating versions and non-mutating versions, there’s no good translation of pow.

pow(x, y)
x.pow(y) -> muating
x.powed(y) -> non-mutating

vs

raise(x, to: y)
x.raiseTo(y)
x.raisedTo(y)

Under the current guidelines, I’m not really sure what to do. There’s also the fact that in my estimation pow(x, y) is not as natural of a function as sin(x) for example. 

I really just want to avoid having a global function called `pow` and a method called `raiseTo` and then have a user confused when they can’t find x.pow(y)

I can also see the benefit of just not providing a method version of the function, but then my API is somewhat arbitrarily split between functions that can be both global and methods, those that are just methods, and those that are just global. I would really like the guidelines to provide more information on how to design this split. 

Tyler


> 

> -- 
> -Dave
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution



More information about the swift-evolution mailing list