8 ms·
It's Coming: The Great Swift API Transformation
- TillE 11y agoI hope they do adopt that suggested change to method calls. Swift is a nice language, but there's still some awkwardness due to its required compatibility with Objective C. I think if you don't come from that background, then having all named arguments except the first one seems really arbitrary and nonsensical.
- ChrisLTD 11y agoI would screw up that first named argument thing every time if it weren't for Xcode's autocomplete.
- ceeK 11y agoTo be honest, even as a fairly seasoned iOS developer I still prefer to have a non-optional first argument in my APIs. Whereas the post's example compares: path.addLineToPoint(CGPoint(x: 100, y: 0)) -- to -- path.addLineTo(CGPoint(x: 100, y: 0)) I've been doing it as so: path.addLine(toPoint: CGPoint(x: 100, y: 0)) ...requiring the "toPoint", which can swapped out true method overloading style: path.addLine(toArc:...) In your internal method implementation, Swift allows you to replace the external method name with an internal one, so that it's still nice to work with: func addLine(toPoint point: CGPoint) { ... } I personally think it's a lot more readable. Otherwise the first argument has to have a really descriptive class name (recommended for sure, but often not the case).
- seivan 11y agoYup, that's what I would like. It's silly to remove the point from the method name and not makes it into a named argument that could be overloaded for others. I might just do that for my own stuff. I don't like the notion of the first argument not being in either the method name or as a named argument.
- nardi 11y agoThe point here (no pun intended) is to stop repeating noun phrases at the call site. Your call site says "point" twice for no reason: path.addLine(toPoint: CGPoint(x: 100, y: 0)) See the "toPoint: CGPoint". It's useless repetition. The new form eliminates it: path.addLineTo(CGPoint(x: 100, y: 0)) It's clear you're adding a line to a point, because it says "Point" right there. Even if you have a variable for this point already, it works great: path.addLineTo(point) Or maybe this is a more specifically named point? path.addLineTo(centerPoint) It's clear from all that you're adding a line to a point. Swift has an emphasis on concise syntax, and removing the repetition, IMO, is a nice win in readability.
- ceeK 11y agoYou do have a good point, and something I didn't explicitly notice before. This does seem to have the indirect consequence of enforcing some sort of type information in the variable name, but I expect many iOS developers do that regardless. It'd also be interesting to see the impact on readability when you have longer variable names. `point` definitely makes it more concise here. But if you had several points within the same scope, readability may suffer given type information is typically at the end of a variable name? path.addLineTo(childViewTopLeftPoint) path.addCurveTo(childViewTopRightPoint, withControlPoint1: arbitrary1Point, andControlPoint2: arbitrary2Point) path.addLine(toPoint: childViewTopLeftPoint) path.addCurve(toPoint: childViewTopRightPoint, withControlPoint1: arbitrary1Point, andControlPoint2: arbitrary2Point) I feel the second version here allows me to bypass obtaining the type information "..Point" from the variable name when reading. Interestingly, I wonder how this type of method would be converted: addArcWithCenter(center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) You'd perhaps think of addArcWith(center: CGPoint), but then you'd need to have 'center' in the variable name to convey meaning. Keeping addArcWithCenter maintains obj-c status quo. addArc(withCenter: CGPoint) is more Swifty, but you may have repetition if your variable is named centerPoint, or similar. I have a feeling it would be kept as is.
- equalarrow 11y agoThere has been discussion on one of the Swift lists (forget which one off the top of my head) to require first param. So this is definitely a known and active (still) topic.
- protomyth 11y agoI do wish the Swift developers had allowed actual Objective-C calls in Swift to make it look the same. Objective-C [aPath addLineToPoint:CGPointMake(200.0, 40.0)]; proposed aPath.(addLineToPoint:CGPoint(200.0, 40.0)); the more complicated example would be: Objective-C [object selector1:item1 selector2:item2]; to object.(selector1:item1, selector2:item2); although I'm still not sure about the love of commas
- ricardobeat 11y agoWhy would that be better than this, which still 'looks the same'? aPath.addLineToPoint(CGPoint(200.0, 40.0)) I don't see how your proposal would fit with Swift's syntax.
- protomyth 11y agoI'm more concerned about multiple selectors and what a mess it becomes, and yes, I wish they'd change the syntax.
- nicky0 11y agoNot that it really matters, but you have your terminology wrong, those aren't selectors. The selector is the whole thing, not the parts.
- protomyth 11y agook, sorry - long ago habit - yes the entire selector:part2: is the actual selector.
- sadawi 11y agoTo me, something like your syntax makes sense when there isn't a clear hierarchy among selectorPart1, selectorPart2, selectorPart3, etc. However, in every case where a method can be thought of as having a single primary action that is refined by arguments, I believe the action(argument1:value1, argument2:value2) syntax makes more sense. I wouldn't want to see, for example: collectionView.(dequeueReusableCellWithReuseIdentifier:identifier, forIndexPath: indexPath) because that obscures the primary purpose of the method, which is to dequeue a cell. To me, this is preferable: collectionView.dequeueReusableCell(reuseIdentifier: "ImageCell", îndexPath: indexPath) The long first component of the Objective C selector ("dequeueReusableCellWithReuseIdentifier") is just an artifact of ObjC's lack of distinction between method names and parameter names, which forces the API creator to use words like "With" to accomplish what Swift can do natively. What are some examples of methods you think make more sense with your syntax?
- deleted 11y ago[deleted]
- bjourne 11y agoIf it is one that that should be known about Apple software by now, is that things will change from under your feet. :)
- jeremy_wiebe 11y agoTrue, but given how young Swift is I'm happy they're not afraid to challenge how things work currently in order to make Swift better in the long run.
- pjmlp 11y agoAnd yet only Microsoft gets criticised for doing it. :)
- breakingcups 11y agoMicrosoft is actually the king of backwards compatibility in my view, and anyone who claims otherwise should peruse Raymond Chen's blog.
- fleshweasel 11y agoThe title they chose implies that they're actually changing the APIs to take full advantage of Swift language features. Perhaps they should have named the article "We're renaming some classes and methods."
- e28eta 11y agoThey're actually changing the way Obj-C APIs are "imported" into Swift. This doesn't rename the method calls, it does more invasive name changes as part of the bridging. So the class UIBezierPath and it's method addLineToPoint: haven't changed, and are still written in Obj-C. The difference is in how they're called from Swift code. Presumably it'll operate the same way in reverse, and this isn't specific to Apple frameworks/classes.
- Benjammer 11y agoCould they just go all the way and use a mandatory first argument name to make things even more concise? That would get away from something that annoys a lot of people about Swift, the implicitly unnamed first arguments. Something like this: class BezierPath: NSObject { func add(LineTo lineTo: CGPoint) {} func add(ArcWithCenter center: CGPoint, radius: CGFloat, startAngle: CGFloat, endAngle: CGFloat, clockwise: Bool) {} func add(CurveTo endPoint: CGPoint, controlPoint1 point1: CGPoint, controlPoint2 point2: CGPoint) {} func add(QuadCurveTo endPoint: CGPoint, controlPoint: CGPoint) {} } class main { func run() { let path = BezierPath() let point1 = CGPoint() let point2 = CGPoint() path.add(LineTo: CGPoint(x: 100, y: 0)) path.add(ArcWithCenter: CGPointZero, radius: 20.0, startAngle: 0.0, endAngle: CGFloat(M_PI) * 2.0, clockwise: true) path.add(CurveTo: CGPoint(x: 100, y: 0), controlPoint1: point1, controlPoint2: point2) path.add(QuadCurveTo: point2, controlPoint: point1) } } The difference is mostly that it looks even more concise when using code completion. You would see: path.add(LineTo: CGPoint) Instead of: path.addLineTo(point: CGPoint)
- nostrademons 11y agoIt gets really annoying when you have short single-arg functions. Imagine what swap(_:_) or Collection.suffix(_) would look like with mandatory first arguments.