Swift Roadmap for performance predictability: ARC improvements and ownership
forums.swift.org
forums.swift.org
I really like what Swift is doing with many parts of the language, as someone who just sort of passively follows their developer announcements (but has never written it).
But at this point, I am starting to wonder whether it's suffering a bit of the "operator soup" situation that C++ has.
It feels like so many features are getting piled on top of each other in the language.
Recently with Swift 5.5, the whole distributed actors thing, now adding these move and reference semantics, etc.
I'm glad that this is happening in the open, lots of smart people are working on it and sharing their insights, design decisions and code.
I wonder if some day we will see a platform ship with an obvious system language and an obvious application language. Right now everyone seem to want to do everything at the same time, and I'm not sure if it's the best approach.
It's also always very interesting to see how programming languages evolve. If I don't change industries, I still have at least 30 years to spend in this one. 30 years ago Java, Ruby and JavaScript didn't even exist, but something like ML was already 18 years old, and records, sum types and pattern matching are just landing in Java/C#. So there's a lot to learn by studying history, and what's happening right now is part of it. I've also followed Go's generics, OCaml multicore, Java's Loom, Valhalla and Amber, and each time it was intersting and insightful. Our industry is all about tradeoffs between change and stability, and those projects are an example of that.
That has always been Swift's main goal it is even stated on both sites.
> Swift is intended as a replacement for C-based languages (C, C++, and Objective-C).
-- https://www.swift.org/about/
> Swift is a successor to both the C and Objective-C languages. It includes low-level primitives such as types, flow control, and operators. It also provides object-oriented features such as classes, protocols, and generics, giving Cocoa and Cocoa Touch developers the performance and power they demand.
-- https://developer.apple.com/swift/
So no wonder why they are doing this.
Rust code would be much easier to read and maintain if it had this...
Move by default works great in Rust, and IMHO it's the better default. You want to move every time you possibly can, and copy only as little as possible. It's only odd if you're already used to a language like Swift or C++ where implicit copy is the normal behavior. I don't like the implicit copy default, because it either makes unexpected overheads creep in, or leads to paranoia about the invisible behavior, and causes busywork of manually placing `move` everywhere it's applicable.
With move by default you know noting expensive is accidentally copied, and things that really semantically need to be copied have an explicit `.clone()` call. Being able to read where the copies are happening is a massive improvement in readability.
Readable Swift syntax corresponds to the slow version:
init(values: [String]) {
self.values = values;
self.values.sort()
}
fn init(&mut self, values: &[String]) {
self.values = values.to_owned();
self.values.sort();
}
Efficient Swift syntax adds syntactic noise: init(values: consuming [String]) {
self.values = move(values)
self.values.sort()
}
While the same improvement in Rust removes a call: fn init(&mut self, values: Vec<String>) {
self.values = values;
self.values.sort();
}There is no memory model, really, from the POV of a Swift programmer.
There are no guarantees about the cost of abstractions.
The threading model is awful. Almost useless. I works well for simple cases (which are simple!) and not at all for complex cases. There must be a way for threads to communicate and synchronise other than a semaphore, but I have not found it. (Do not need it - keeping it simple and on one thread).
The compiler is very slow. You thought the Rust compiler was slow? Try Swift!
Not Swift, but the IDE provided by Apple cannot deal well with programmes when they approach ~100k lines. It gets very slow and its tools become unreliable.
The learning curve of Rust makes it unsuitable for general purpose computing, and there is nothing hard about learning Swift. It has a lot of modern features (c/f C, my first love!) - map, reduce, optionals, result types, generics....
I do not think it is a threat to Rust for system programming outside of Apple (Dog knows what madness they will try). I think it's main competitor is Go. Not in systems programming but in general purpose computing.
OTOH the way Swift proposes to add ownership-related syntax is obviously a retrofit, and looks verbose. Rust had a syntax designed for ownership from the start. Swift needs extra syntax to first undo the ARC defaults, and then syntax to control the ownership. In this regard, Swift looks noisier.
Swift's `@nonescaping String` is `&str` in Rust. Swift's `arg: consuming Foo` is simply `arg: Foo` in Rust. Swift's `x = move(y)` is `x = y` in Rust.
From the point of view of semantics and functionality, it's all good. Swift's interaction with C was dangerous due to unobvious implicit rules of ARC. Having ability to get compiler-checked guarantees for lifetimes is very helpful.
High level constructs for being productive without stepping too much, while offering the language features to go downlevel as much as required, when it is time to actually do it.
Naturally this matters mostly to those invested into the Apple's ecosystem.
That's surprising, I remember that one of the specificities of Pascal and its descendants are its very fast compilation time. Swift seems to be at the exact opposite end of that spectrum. I'm not sure if it's the type inference, the frontend, LLVM or something else though.
But swift have a lot of "magic". The major advantage of Rust, the biggest one for a system language, is how explicit is about almost everything.
Is incredible how much you can know just looking at the code at hand.