I can’t read all of this now, mainly because I’m on mobile with limited time and it’s hard to squint at. But I was surprised that what I did read and search through the document makes only one mention of polymorphism (rank 2 polymorphism, which was a new term to me; a quick search seems to suggest this is the type system equivalent of closing over a type parameter, eg to create local generic function whose generic constraints are first constrained by their outer scope). And makes no direct mention of monomorphization in the code specialization section, but it does seem to hint in that direction. I’m probably looking for terminology but would be satisfied with the prose when I read through more.
What surprised me most so far, again having only read a portion so far, is the caveats around crossing module boundaries for analysis. I’ve been, frankly, surprised at how much this is expressed as a difficulty in far more dynamic environments like JS ESM, but where the module boundaries not always totally static but in practice almost always are. I’d expect that a much more static and controlled environment like Swift would not have so many challenges in that area. But maybe this is a misconception of how static Swift actually is? Probably so!
Adding this comment with more ignorance than insight mostly in hopes I come back to see more knowledgeable discussion when I return.
The whole thing is about polymorphism, but Swift calls that generics. Similarly “function specialization” is Swift lingo for monomorphization.
The part about module boundaries is what allows separately-compiled and updated shared libraries to work (like the frameworks in the OS). There’s an @inlinable attribute to publish a function’s body to clients, but then if you update the library it won’t be picked up until clients are recompiled (which might be fine, for example a lot of standard library collection algorithms and so on are inlinable).
Swift's generics have some unique properties at module boundaries to allow for a stable ABI while enabling library evolution.
To get additional background, you might be interested in this[0] conference talk (the paper's author is one of the co-presenters). Also, this post[1] by a Rust and Swift compiler engineer talks about what Swift does differently than other languages, and the tradeoffs that are involved.
Hey Slava, this looks to be an incredible resource and I very much look forward to reading it. A question I have: is there any hope to specialize generics exported by shared libraries? Perhaps with help from bitcode or dyld?
As you know so many of Apple's frameworks are packaged as shared libraries, and enabling them to export generic definitions which operate on concrete representations would be killer.
I can't comment on Apple frameworks but there's a @_specialize attribute which allows you to export a fixed set of pre-specialized entry points from your own frameworks, without exposing the entire function body as serialized SIL the way that @inlinable does, but it's still experimental and subject to breakage and change: https://github.com/apple/swift/blob/main/docs/Generics.rst#s...
The big problem with Swift for DSLs is that SwiftUI is essentially a special case in the language. Yes, you can build other DSLs with the facilities, but result builders are designed for SwiftUI’s needs specifically, where a more general hygenic-macro-based solution would be of more value generally. (Swift does not have macros of any sort).
The main issue with Swift as a general language is that the standard library is not broadly enough designed, and the language is very tied to the standard library. It’s hard to see Swift being used to write an OS kernel, or even a Linux kernel module, for example. Swift is an application language for Apple platforms, and it will remain so until someone puts effort into making it otherwise.
That said, the new regex facilities in Swift 6 make it a real contender for scripting tasks where you might otherwise consider using Ruby / Perl / Python. So there is progress.
I'm surprised to hear you call it "terse," in trying to learn Swift I've found it painfully verbose for the most part (function calls with required keyword arguments by default, function definitions with external and internal names, overriding final fileprivate etc), and only the odd syntax around (esp trailing) closures weirdly terse and, for me, difficult to get used to.
Hopefully I'll get used to it. It does seem like all this serves a purpose, perhaps more readable as a result, but it seems to take more writing than I'm used to in python / go / rust.
It doesn't matter how good the language itself already is.
It's a niche language because the marketing of it to non-Apple-platform developers over the years has totally bombed, and it has close to zero mindshare amongst them.
(People who were already Apple-platform developers playing around with hosting a webapp on a Linux box don't count)
I agree, it's a beautifully expressive and safe language. Being tied so closely to iOS, thus limiting its impact for eg backend work, really is a pity. I know you technically can use it for backend work but the ecosystem just isn't there, I think people just consider it ios-only unfortunately. To workaround the small ecosystem, you can bridge to existing C libraries but the impedance mismatch makes it very difficult (eg UnsafeMutableBufferPointer<T>).
I do worry about its future however: dual-native mobile apps are less and less popular with product owners with every passing year, the market seems to be moving to flutter. Which is a pity! It's such a great language.
Honestly that's a very real concern. From what I hear, the Android team does not speak glowingly of the Flutter team at IO. Also there appears to be a power struggle between the Flutter and Jetpack Compose teams to become the next 'official' way of developing Android apps, in parallel to Apple bringing out SwiftUI. Time will tell.
Given what we've all been reading lately about Google's LPA cycle (launch, get promoted, abandon) it seems likely that flutter will end up like React Native: kinda usable, but never really polished enough, it seems they just stopped most work on it before the finish line.
Also agree. That's what I meant about the leaky abstraction. The fact that some chainable things are a one way street... e.g. need a specific order... yikes.
But considering the DSL is fully statically typed, wow.
Out of many sources, it was only the Stanford iphone course that demystified the terseness of the Swiftui dsl. The lecturer pointed out all the optional parentheses and optional arguments that could be omitted to make the declarations clean. Up until then i thought i was looking at weird structs. This is one problem i have with swift’s terseness.
What surprised me most so far, again having only read a portion so far, is the caveats around crossing module boundaries for analysis. I’ve been, frankly, surprised at how much this is expressed as a difficulty in far more dynamic environments like JS ESM, but where the module boundaries not always totally static but in practice almost always are. I’d expect that a much more static and controlled environment like Swift would not have so many challenges in that area. But maybe this is a misconception of how static Swift actually is? Probably so!
Adding this comment with more ignorance than insight mostly in hopes I come back to see more knowledgeable discussion when I return.