Ownership in Swift: Manifesto and meta-proposal (2017)
github.com
github.com
Anybody familiar with Swift development have updates on whether it went anywhere and what the current state is? As someone not in this particular loop, not immediately clear to me why a 6-year-old proposal was linked here.
https://github.com/apple/swift-evolution/blob/main/proposals...
as well as a way to explicitly move types:
https://github.com/apple/swift-evolution/blob/main/proposals...
I haven’t read either in-depth, though!
It’s been the focus for a while especially after the concurrency work. It’s probably the final major feature before Swift 6
https://github.com/apple/swift-evolution/blob/main/proposals...
https://github.com/apple/swift-evolution/blob/main/proposals...
https://github.com/apple/swift-evolution/blob/main/proposals...
The first is explicitly marked as “Implementation: Swift 5.9, without no-implicit-copy constraint”, but it seems the others also ¿partly? are in.
Also, Swift had tremendous work to implement ABI stability[1], which really allows it to be used as an OS API, which Rust can't do.
Then I thought that what we really need is a Swift-like language with the ability to remove costly abstractions when you don't want to pay the cost, but that default to ergonomically solving the problems that the majority of programs need to solve. You should opt-in to more semantic complexity, not be encumbered by it by default. Rust's obsession with performance above all else confuses me. But I also guess it's nice to have a safe space for performance sensitive programmers. But like how can a systems language not have a stable ABI? Very mixed messages.
Ultimately this "Rust with better ergonomics" language could be Swift. I do think it is more usable across platforms than people give it credit for. But it's also missing the "let me dip down into lower level but more complicated semantics when I need to" option. Having a stable ABI is awesome, though. I really can't wait for the day where I can start a portable project in Swift without a second thought.
It's kind of a requirement if they hope to replace C/C++ as a systems language, as those remain the goto answer for "I need maximum control", short of assembly.
And they want to replace C/C++ to fix all their safety problems.
I work in embedded systems, where C remains a holdout, with all its problems. Rust's performance-oriented direction makes it a viable consideration for us.
My understanding of zero cost abstractions is that they predominantly happen at compile time (and thus commonly appear in language semantics or the type system) and literally cost nothing at runtime. This has other costs like semantic complexity, but almost never performance.
Regardless, I don't buy that Rust couldn’t present a more opinionated and complete programming experience without allowing the same performance characteristics that it has today. The whole async situation is awful. Lifetimes are a stupid leaky abstraction 99% of the time. My point is that there’s almost never a scenario where you e.g. need to bother with passing around a struct with a reference with a lifetime. 99% of the time you just take ownership of the data or use an Arc<Box<T>> and 99% of the time that’s not a performance problem. What I think is stupid is that Rust elevates and enshrines the 1% use cases and makes the 99% experience worse off for it. I love Rust. But it could do a better job of solving the 99% cases nicely while allowing a “zero cost escape hatch” where you could say “actually I do want a stack allocated reference without atomic reference counting” and pay the semantic price 1% of the time rather than 99% of the time, similar to Swift’s approach.
Obviously my experience had been shaped by the projects I’ve worked on. But I also think Swift is an entirely more ergonomic and practical language. If you think Rust is a viable option then, unless you’re anti-Apple, Swift with ownership semantics most certainly is too. Seriously.
- you only pay for what you use
- if you use it, you couldn't implement it better yourself
There's no such thing as literally zero cost, obviously.
Graydon was saying that even this fairly reasonable pair of conditions got in the way of some nicer abstractions.
One of the important aspects of a stable ABI is the ability for clients to continue to work even after the size of a remote type changes… for instance, if Foo is a type defined in Foo.dll, and I link to it, and my code does `Foo *f = new Foo()`, the compiler will emit code that malloc’s `sizeof(Foo)` bytes on the heap. If later on, Foo gets a new member variable “m”, it will increase in size, and now code in Foo.dll will segfault if it tries to access `this->m`, if a client allocated it.
COM solves this by basically not letting you do `new Foo`, but instead you have to ask COM itself to allocate and return an instance for you, with something like `CoCreateInstance`. This allows .dll’s to evolve even if the size of the object changes, by abstracting away things like size information so that clients don’t care about it. ObjC solves this similarly with `[SomeClass alloc]`, where clients just ask the class to alloc itself and returns a pointer (which is delayed until runtime, not in the emitted code), and Swift solves it with value witness tables which delay the lookup of size/stride information until runtime.
I don’t understand how, you can write .dll’s with not only a stable ABI, but the ability to actually evolve your types, in plain vanilla C++… I think the language itself has painted itself into a corner that prevents things like this.
You get .NET metadata, IInspectable, and an improved type system, basically .NET CLS.
It doesn't expose everything C++ can do, but enough C with classes, OOP ABI and generics.
https://learn.microsoft.com/en-us/uwp/winrt-cref/winmd-files
Basically what COM vNext was going to be, if it wasn't for .NET pivot (see Ext-VOS).
However the tooling is as clunky as using ATL.
One example where this shows up is [[no_unique_address]].
I think that's a massive simplification
It’s not just disk space either, but the ability for an OS as a platform to swap out implementations of their API’s with new ones, without requiring every app to be recompiled. It’s the reason macOS is able to implement things like dark mode, or a new UI theme, or any other “horizontal” feature that works across all apps; you need dynamic linking for that to be possible.
Yeah, the operator overloading design makes it too easy to construct an exponential search space.
> For instance, Swift doesn't have the orphan rule, so it's possible that 2 packages implement the same protocol for the same type, and when this happens currently there are no solutions;
There's now a warning about this: https://github.com/apple/swift-evolution/blob/main/proposals.... What other solutions can there be other than making it a hard error? It seems like an inherent drawback of typeclasses over first-class modules.
> there is this strange design decision that classes and structs should be different things and each have their own set of random limitations
structs in Swift are the same as structs in Rust, and a class is a heap-allocated reference counted box, like an Arc<Box<T>>. What are the random limitations? As far as I'm aware the behavioral differences between structs and classes are entirely explainable by the above.
> and there is SwiftUI, which hacks on the syntax itself, making statements no longer mean what they are supposed to mean
Result builders are a language feature and not part of SwiftUI: https://github.com/apple/swift-evolution/blob/main/proposals...
Yeah, and by representing the differences this way, Rust allows you to easily decide whether an object is used directly or is wrapped in a rc box when its used, instead of when it's defined, often not by you, and when you change your mind you don't need to change all methods or functions than mutates it and all their call sites.
> Result builders are a language feature and not part of SwiftUI
I admit that this is the first time I see the term result builders. This is never mentioned in any SwiftUI documentation I've seen, so I guess I should extend my complaint to include quality of docs :p. Whatever this is called you seem to agree that the syntax is hacked and it can get hard to understand what something means
Changing a value type into a reference type is a pretty fundamental transformation because your local mutations now become non-local. Its not clear the Rust approach makes this any easier either, since you’d still have to update all call sites that perform mutation if suddenly one of your value types was now always wrapped in a box.
> Whatever this is called you seem to agree that the syntax is hacked and it can get hard to understand what something means
Result builders are just a way to build data types from the results of top-level expressions (hence their name). It’s not just a SwiftUI thing, they’re also used for regular expressions for example: https://github.com/apple/swift-evolution/blob/main/proposals...
But I have to agree, from a novice eye at least, result builders look to be a feature added to support SwiftUI and limited other use cases. Have you seen many examples of third party libraries successfully using them?
And while we're here, do the introduction of macros in Swift 5.9 allow room for replacing result builders with something more uniformly useful?
A quick search in the package index also finds things like these:
- https://swiftpackageindex.com/davidcaddy/DCSettings
- https://swiftpackageindex.com/tdeleon/relax/2.1.0/documentat...
- https://swiftpackageindex.com/mkj-is/PathBuilder
- https://swiftpackageindex.com/Saelyria/Artemis
- https://swiftpackageindex.com/FluidGroup/MondrianLayout
etc.
Go, by comparison, can be learned in a couple of days, and it’s trivial to build a useful CLI with it.
So from my perspective, the barriers to entry for Swift are much higher, but it’s mostly due to the domain rather than the sponsor.
As an example. I have been dabbling with controlling my Roku from a watchOS app. Roku devices respond to a call on 239.255.255.250:1900 with a SSDP packet over UDP. Try finding good and recent tutorial on doing UDP programming and it is non-existent.
So yeah I had a similar experience. And Go is much more aligned with my use cases so hints are everywhere.
To be clear I still want to learn Swift. But the time investment is much, much greater.
I’m pretty sure they have extra stuff on top at the moment to help them write ultra-strong/safe code that the released language doesn’t support directly yet.
But they are moving in that direction. Just because most people use Swift as a language where they don’t have to worry about memory allocation and with the large standard library doesn’t mean that’s all it can do.
Apple doesn't care about what outsiders think, they own the platform.
You forgot Windows, Linux, WASM in browser, WASI envs
Note Swift's interoperability story with C/C++ is also getting much better.
The key to success is to know what libraries are supported.
- subgroup: https://www.swift.org/server/
- getting started: https://www.swift.org/server/guides/
- wwdc 22 video: https://developer.apple.com/videos/play/wwdc2022/110360/)
- forums: https://forums.swift.org/c/server/43)
I find Swift runs faster on a Linux guest of MacOS than on MacOS itself (but that could be my setup).
How were building the ARC windows all with Swift - https://youtu.be/Xa_fNuaSE_I
I haven't toyed with Swift under Windows, but the devs behind Arc Browser have been hiring people to work on improving Windows tooling and writing a Swift wrapper for WinUI 3.
This is a good-faith, non-trolling question. Rust is way out of my wheelhouse, but it’s obviously gained enough momentum that even I’m aware of it. Is there some language or community issue?
In any case, Rust is unlikely to fail because it is the only viable option in its niche (safe systems programming language that can replace C++ everywhere), and has gotten a large amount of investment from major corporations.
One potentially relevant highlight:
> To date, there have been zero memory safety vulnerabilities discovered in Android’s Rust code.
> Historical vulnerability density is greater than 1/kLOC (1 vulnerability per thousand lines of code) in many of Android’s C/C++ components (e.g. media, Bluetooth, NFC, etc). Based on this historical vulnerability density, it’s likely that using Rust has already prevented hundreds of vulnerabilities from reaching production.
The post has more details, and I think the entire thing is worth a read.
[0]: https://security.googleblog.com/2022/12/memory-safe-language...
IMO Rust is long past the point (in terms of real world usage, commercial backing, etc) where it might “kick the bucket”.
There is a lot of drama in the project leadership (and has been since the beginning), but that's mostly irrelevant to people just using the language. This latest flareup is about a conference keynote speaker, not something relevant to the language itself.
If the project becomes dysfunctional enough, it can always be forked, as it is fully OSS.
Sorry, what?
https://docs.modular.com/mojo/programming-manual.html#argume...
(same creator as Swift)