Same for the member-wise defaults! Especially in concert with optionals. I hate having callers explicitly pass in nil, but I'm also not fond of provided a convince initializer, as it is one more thing to change when you add a new member to a struct.
I remember hearing at WWDC that memberwise defaults were added to Swift by a student. Apparently pitched the idea in the forums, then went straight PR on it!
You could almost argue the real feature here is how open the community is to additions like this, and there's no need to wait for people at Apple to do it.
There are. Python, Ruby, Perl (sort of), and many other languages via macro/syntax extension (e.g. Rust via https://github.com/comex/namedarg and an RFC).
Do any of them use this specific syntax to disambiguate positionals from named arguments/kwargs? No. Do they all have some form of special syntax in method signatures for making the delineation? Absolutely.
With type safety checks, you're mostly eliminating a class of problem by ensuring coders don't call the function with some argumetn of a type they didn't mean to.
But suppose I have a method that takes 5 different strings and performs some computation on them - the type safety check doesn't help me there.
In functions that take multiple arguments of the same type, it can be easy to be mistaken about the intended order of parameters, for example passing the 5 strings (name, address, level, phonenumber, cellphonenumber instead of in the order the function expects (name, address, phonenumber, cellphonenumber, level).
Named parameters -if using meaningful names- make it clear in the calling function the semantics of which parameter has which meaning, so the above mistake gets caught at compile time instead of (worst case) not at all.
Of course, in functions with arguments of heterogenous types they're probably overkill.
Others explained what benefit this has, but it's also helpful to understand the Objective-C heritage here. Swift on Apple platforms run on top of the Objective-C runtime, making it possible to call Objective-C from Swift and vice versa. Objective-C uses named parameters.
The Swift translation layer lets you call that like this:
let newString = myClassInstance.method(param1: val1, param2: val)
And the translation works the other way around too, making Objective-C able to call a subset of Swift methods that use types representable in Objective-C. You need the named parameters to make it work, because the names of the parameters are part of the method name.
So it's a nice feature, but it was also necessary for Apple to be able to make Swift an incremental addition to their platform (yes I know of the Python/Ruby/etc translation layers for Objective-C but they're nowhere near as nice.)
They are still positional in Swift. color(r: 255, g: 255, b: 255) is not the same as color(b: 255, g: 255, r: 255). Also the parameter names are part of the method signature.
Self is rarely needed with Swift, the only time I use it is when differentiating an instance variable from a local variable with the same name and type.
This is a great release, but the thing I'd really like the swift developers to focus on is performance. It seems surprising given how similar swift is to rust, but I've heard some reports of programs spending 60% of their time updating reference counts. I'm not sure the best way to fix that - do programmers need a way to opt out of swift's default memory model? Is there a way to elide some of those checks in the optimizer? But it seems like for small objects something like that would make a big difference in performance.
This probably doesn't matter much when making iOS apps, but it would make swift much more useful in other domains (like as a web server).
> [...] there are already substantial improvements to RC optimization in 5.1 (and even more in top-of-tree). Using Unmanaged is "cheating" in a sense because it's unsafe, and it should not be necessary in normal circumstances to get adequate performance from idiomatic code—if it's safe to use unmanaged references, then the compiler should know that and avoid reference counting in the first place. The current Swift implementation is still nowhere near representative of the performance that should be possible, since we've been primarily in the "make it work" phase of development, and are only now starting to get into the "make it fast" work.
> Since Swift optionals are implemented using the Optional enum under the hood, we’re no longer able to perform the above kind of optional pattern matching on any enum that contains either a some or none case — since those will now conflict with the cases that Optional contains.
Wait, so if I wrote my own custom enum with .some and .none cases this will not work correctly? This seems like an overly broad scope; why can't the change have only affected Optional.some and Optional.none?
public extension Sequence where Element: Identifiable {
func keyedByID() -> [Element.ID : Element] {
var dictionary = [Element.ID : Element]()
forEach { dictionary[$0.id] = $0 }
return dictionary
}
}
23 comments
[ 6.4 ms ] story [ 123 ms ] threadIf you use any language long enough you will think, hey it would be nice to have X. Alejandro (in high-school at the time) thought exactly that and implemented it himself - https://github.com/apple/swift-evolution/blob/master/proposa...
You could almost argue the real feature here is how open the community is to additions like this, and there's no need to wait for people at Apple to do it.
let z = add(x:2, y:2)
Are there other languages with this type of method declaration/use site syntax? If so, what's the advantage?
Do any of them use this specific syntax to disambiguate positionals from named arguments/kwargs? No. Do they all have some form of special syntax in method signatures for making the delineation? Absolutely.
With type safety checks, you're mostly eliminating a class of problem by ensuring coders don't call the function with some argumetn of a type they didn't mean to.
But suppose I have a method that takes 5 different strings and performs some computation on them - the type safety check doesn't help me there.
In functions that take multiple arguments of the same type, it can be easy to be mistaken about the intended order of parameters, for example passing the 5 strings (name, address, level, phonenumber, cellphonenumber instead of in the order the function expects (name, address, phonenumber, cellphonenumber, level).
Named parameters -if using meaningful names- make it clear in the calling function the semantics of which parameter has which meaning, so the above mistake gets caught at compile time instead of (worst case) not at all.
Of course, in functions with arguments of heterogenous types they're probably overkill.
An Objective-C class interface might look like
And you'd call it like this: The Swift translation layer lets you call that like this: And the translation works the other way around too, making Objective-C able to call a subset of Swift methods that use types representable in Objective-C. You need the named parameters to make it work, because the names of the parameters are part of the method name.So it's a nice feature, but it was also necessary for Apple to be able to make Swift an incremental addition to their platform (yes I know of the Python/Ruby/etc translation layers for Objective-C but they're nowhere near as nice.)
This probably doesn't matter much when making iOS apps, but it would make swift much more useful in other domains (like as a web server).
> [...] there are already substantial improvements to RC optimization in 5.1 (and even more in top-of-tree). Using Unmanaged is "cheating" in a sense because it's unsafe, and it should not be necessary in normal circumstances to get adequate performance from idiomatic code—if it's safe to use unmanaged references, then the compiler should know that and avoid reference counting in the first place. The current Swift implementation is still nowhere near representative of the performance that should be possible, since we've been primarily in the "make it work" phase of development, and are only now starting to get into the "make it fast" work.
Swift 5.1 enables the creation of binary frameworks that can be shared with others leveraging the language’s added support for module stability.
https://swift.org/blog/swift-5-1-released/
Wait, so if I wrote my own custom enum with .some and .none cases this will not work correctly? This seems like an overly broad scope; why can't the change have only affected Optional.some and Optional.none?
Perhaps this could use Dictionary(grouping:by:)?