Tuesday, June 4, 2024

Swift at 10

Basic Apple Guy:

10 Years Ago: Apple Announced Swift

Brian Webster:

10 year anniversary of Swift being announced at WWDC.

Chris Lattner:

Wow that’s right. This was a big day and Swift has come a long way in the intervening decade: Congrats to everyone who has driven it forward to support such an amazing tech platform! 🍎🐣

Jim Rea:

Interesting to go back and watch this presentation and see how Swift was originally promoted ten years ago. I would certainly say that Swift has been a huge success. On the other hand, I’m personally still 100% programming in Objective-C and that continues to be an excellent development environment for building a sophisticated Mac app.

My high-level take is that I generally like programming in Swift. I’m rewriting all my apps in it. But I’m not sure it was the right thing to build. It’s been such an immense effort both within Apple and for the community. This has been a distraction from apps, frameworks, architecture, and documentation. So much mindshare has been taken up by the language itself, which should be just a tool for building the things that actually matter for our customers. It’s come a long way, but the “end” is not yet in sight, as, even 10 years in, essential pieces are still being designed.

I think it’s quite possible that most of the parts that I, as an app developer, care about could have been had—sooner, and with greater tools speed and reliability—with a less ambitious project that actually tried to be Objective-C without the C, rather than a more static mega language that tries to replace C, C++, Objective-C, and Rust. The question is not how Swift 5.10 compares with Objective-C 2 but how it would compare with the hypothetical Objective-C n or Objective-Mojo that we could have had instead.

It all comes down to the big vision of world domination and having a single language from the bottom of the stack to the top. That would never have happened with a more pragmatic evolution of Objective-C. If that eventually pans out, and Swift ends up being good at all levels of the stack, that would be a triumph. But, here in 2024, it still seems like a very long way away. In another 10 years, I suspect that XNU and WebKit will still be mostly C and C++, and the app frameworks will still have large amounts of Objective-C (or C++ in the case of SwiftUI).

Now let’s look at some specifics. The good:

The bad:

Previously:

Update (2024-06-05): See also: Hacker News.

Der Teilweise:

I’d say what I like most about Swift is Optional. It is simple to use (especially since we got if let x {}) but gives one a warm feeling of not missing a nil.

I 100% agree with each and every point in the bad list.

Thinking of integer index for string, I’d add a “Stubbornness of the language guardians” (phrased as “Strict adherence to a clean design.”) but I do not disagree with any of the points that are on the list.

Damien Petrilli:

I agree with Michael’s take but to me the jury is still out on performance. It’s clearly not competitive against C++.

Update (2024-06-06): See also: this Swift roast and Nathan Manceaux-Panot.

Francisco Tolmasky:

Swift is 10. I think at 7 or so I asked whether it felt it was as mature as ObjC/Cocoa were at that age. I have a different question now. Where do we think Swift will be in 10 years? Will SwiftUI actually be capable of making a real Mac app? Or will we have a new language and/or framework by then (20 years after Swift). Or will the Mac maybe just no longer exist by then, making this question moot?

Kyle Howells:

There’s 2 separate worlds of software development.

Building apps and user facing features.

Infrastructure and low level language design.

Swift concurrency (and a lot of Swift actually) just looks to me like evidence the language people being given far too much power, to run away with architecture astronauting projects.

Sarah Reichelt:

Apple banning employees from developing their own apps has many negative effects and this is one of them.

Alex Grebenyuk:

The parts of Swift Concurrency that make me more productive when building apps are Async/Await and maybe MainActor. Everything else is more work for little benefit, making it impractical.

Update (2024-06-07): See also: Reddit and Lobsters.

Steve Streza:

  • The language delivered on core promises of better architecture, reduced crashes, more semantic types
  • The compiler is simply not adequate, it is barely functional and Apple has failed to invest in it sufficiently
  • Initiatives like WASM, server-side are exciting but hamstrung by the BDFL problem making it difficult to widen the ecosystem like in Rust, JavaScript, etc
  • Swift is still just “the language for Apple dev”, not a true C-level player like Rust

Update (2024-06-19): Andy Finnell:

After 10 years of Swift, I still get compiler crashes on the regular. Xcode should at least make them actionable.

The compiler logs give instructions on how to file a bug report. It should just be a button I can press.

The compiler logs give zero indication of what’s causing the crash. Xcode should have a command that runs a bisect over the file causing the crash until it’s identified the offending lines. i.e. automate what a human would do by commenting out code.

Daniel Hooper (via Hacker News):

The Swift compiler can take an absurdly long time to compile expressions due to how types are inferred. Here’s an explanation by the creator of Swift, Chris Lattner (from from his Mojo talk [Hacker News] and edited for clarity):

My experience with Swift is we tried to make a really fancy bi-directional Hindley-Milner type checker and it’s really great because you can have very beautiful minimal syntax but the problem is that A) compile times are really bad (particularly if you have complicated expressions) and B) the error messages are awful because now you have a global constraint system and when something goes wrong you have to infer what happened and the user can’t know that something over there made it so something over here can’t type check. In my experience it sounds great but it doesn’t work super well.

[…]

Swift 6 spends 42 seconds on these 12 lines on an M1 Pro, only to spit out the notorious error: the compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions. In the same amount of time, Clang can perform a clean build of my 59,000 line C project 38 times. The Swift standard library has 17 overloads of + and 9 types adopting the ExpressibleByStringLiteral Protocol. This leads to an exponential combination of types and operators for the constraint solver to try.

Even very short snippets of code can trigger that error message, and compilation is also slow even for code that doesn’t trigger it.

Steve Troughton-Smith:

People seem to be blissfully unaware of just how many resources go into making yearly OS updates happen. An anecdatapoint I’ve heard thrown around is that the introduction of Swift into Apple’s codebases more than doubled the time it takes to build all of Apple’s OSes every night across their build farms, to the point where it now takes a day and a half to run a ‘nightly’ build.

Marcel Weiher:

Scrub a little earlier for more details on the problems with unpredictable performance.

Ben Cohen:

In May 2015 (so still in the Swift 1 days) I wrote a version of Peter Norvig’s simple spelling correction generator. I happened to think of it again and thought I’d try updating it to use all the improvements to Swift that have happened since then.

See also: Reddit, The Talk Show.

Update (2024-06-25): See also: Hacker News.

christophilus:

Ocaml is really fast to compile when I play with toy projects. It’s a fairly simple type system compared to, say, TypeScript (I’m not familiar enough with Swift to know how it compares to Ocaml in terms of type system complexity). I’d prefer the simpler language if it means faster compilation.

Helge Heß:

My protobuf schema now needs ~30 seconds to compile on the Swift side.⏳

Update (2024-07-15): Chris Lattner discusses progressive disclosure and Swift’s complexity (via Hacker News):

Swift, the original idea was factor complexity (…) massively failed, in my opinion (…) Swift has turned into a gigantic, super complicated bag of special cases, special syntax, special stuff

[…]

instead of fixing the core, what the team did, both when I was there, so partially my fault, but also subsequently, is they started adding all these special cases (…) a lot of this stuff got added under extreme time pressure to enable a feature like SwiftUI. And there’s a bunch of stuff that feeds into that, as well as just the language gets more and more and more and more complicated.

Update (2024-09-23): Chris Lattner:

Great to dive into PL with Richard, a legit language implementer! We explored a wide range of topics, incl lessons learned Swift=>Mojo, how the structure of integer types + overflow is more complex than it might look, approaches to safety, acceleration of novel HW with Mojo etc.

He talks about design decisions that led to Swift’s type checking being slow and its error messages being unhelpful, and how Mojo avoids these problems. Mojo also has much more limited support for custom operators because the fancy system developed for Swift ended up not getting much use to justify the complexity.

Sebastián Benítez:

After using Swift for more than 5 years I can confidently say that it’s getting worse with each addition, very similar to how C++ ended up being the monster it is. In comparison, Objective-C is simpler, somewhat minimalistic, and yet it did a great job for many Mac developers for a long time. I’ve heard that Swift code leads to less crashes and better performance, but that’s not what I’ve experienced. Well written Objective-C code can be easy to understand as much as well written Swift code. But overly complex Swift code is much more difficult to maintain and understand than similar Objective-C code.

16 Comments RSS · Twitter · Mastodon



Jim Rea: "I would certainly say that Swift has been a huge success."

I would, on the contrary, say that Swift is a complete failure based on what the message was at the time.

---

"Overall, it’s very ergonomic."

IMHO, it's as ergonomic as the System Settings.app application in macOS.

---

In 10 years, I still haven't seen any application on iOS or macOS that would make me say: OK, this is really an awesome language and what was done could not have been done in another existing language. What I've only seen so far has been projects that have failed miserably or where there was no point in switching to this language compared to just rewriting/updating the existing Objective-C code.


This came across my RSS feed as I happened to be converting an Objective-C class to Swift. It's actualy my second go at this ~400 line class, because the last time I tried, about half a year ago, the Swift compiler core dumped when compiling it.

Suffice to say, I found myself agreeing almost completely. We're writing new code in Swift, and we're converting some old code to Swift when we need to refactor it, but all the cons you listed are are spot on, and I agree with the general premise that, as third-party developers, we would have been better served with an evolution rather than revolution in programming languages at Apple, both in terms of the technology and in terms of so much mental enerfy being put into the language side of things instead of the app development side of things.

That said, I know people who work on the language, and they're very smart people, so I suspect that there were benefits to Apple doing it this way instead of Objective-C without the C.

The documentation getting steadily worse since the introduction of Swift and as the language got more complicated is possibly the most impactful con to me personally, but I can't say for sure that Swift is entirely to blame. As great as some of the tutorial documentation has been recently, Apple's written technical documentation has taken hit after hit, with some bounces back, as the company seems to be convinced that WWDC videos should make up the bulk of developer documentation. The reference docs aren't in as quite a sad state as they were a few years ago, but in terms of new APIs introduced since 2014, I'd say we still have a long way to go to get back to how complete the documentation was before Swift came along.

SwiftUI is a tough one, because I think, in a lot of ways, it's a better programming model, and a better way to write apps. But it's always been buggier and slower than AppKit or UIKit. The implementation just isn't there. It's not just that more of Apple's focus is on other OSs than the Mac. It was a hard road on iOS as well.

And less capible too. I think that's a very unfortunate pattern we're seeing in Swift. The Predicate macro is less powerful than NSPredicate. SwiftData is less powerful than CoreData. SwiftUI is lacking view types from UIKit and AppKit. And it's not just that these are some obscure features that developers don't really need. They're missing core functionality in a way that affects almost every app that isn't just a simple tech demo.

One additional pro I'd put though, is that Swift on Windows works better for me than any of the various means of running Objective-C on Windows ever did.


@someone I agree about not seeing a Swift killer app, but that seems like a very high and probably unreasonable bar for a language to meet to avoid being a “complete failure.” Certainly there are developers who say they would not have built their app if not for Swift.

@Michael My hunch is that the compiler is more crashy with mixed codebases. Yes, I think Swift-the-revolution is more what Apple wanted for itself and what it took to sell the project inside than what would have been best for us. But, like I said, it’s not clear to me that it will end up throughout the stack inside, either. The Swift developers are surely very smart (and good at interacting with the community), though I imagine most of them were hired after the strategy was set. Some of the design issues may not be fixable. And, of course, Lattner and Abrahams left. I’m not sure what’s going on with the new frameworks. I don’t think the problems are due to anything inherent with Swift, but the execution has not been good.


Old Unix Geek

It seems to me that a larger language is a big negative.

Similarly, I'd prefer to be tripped up by my own bugs than by other people's bugs, so fewer errors at the micro level but more at the macro level is also a strong negative.

I don't remember being stymied by Objective-C's speed. At worse I could drop back into C++/C/assembly. Much harder with Swift's interop. I ended up just going the the C way anyway, but what a pain.

I also don't like large binaries, or crashy compilers, but perhaps that comes from writing z80 machine code in Hex because the Assembler was too buggy to trust.

Ultimately though, I don't see the benefit of Swift. Unless something is a lot better, why go through all the pain of switching? Objective-C was a lot better than C/C++ in its domain, so it made sense. Haskell is a lot better in its domain. Python's also good in its domain, and I'm sure APL would be if I ever learned it. Even Forth. But I don't really see anywhere Swift shines in a way that makes it better, except perhaps as Michael said, of all things, Windows support.

Honestly, I don't think having "very smart people working on it" really means very much. Very smart people came up with x86, and for a while there it really was horrible to code in. It only really got bearable with x86-64... Most solutions are constrained by the incentives around the problem they are solving, and being smart only means you do a less bad job than you could have.


Great post.

> I’m not sure what’s going on with the new frameworks. I don’t think the problems are due to anything inherent with Swift, but the execution has not been good.

I think the maintainers of ObjC under Jobs were more focused and accomplished more than the Swift team has thus far.

ObjC frameworks were designed for creating apps while Swift is very self involved; I think all the compiler people working on it are self involved too and made the language over complicated with features that have little use at least from the perspective of app developers.

And to add another unpopular opinion I like header files. Documentation for Swift sucks they dump an entire framework’s public API in a gigantic generated header file. I like having public API in a separate file and I hate having to “generate an interface” in Swift to make the private API of a Swift class disappear.


@ObjC4Life I dislike headers within my own project, but I really miss them as documentation for the public frameworks. It’s hard to find stuff within the gigantic generated header, especially with each type split into so many extensions. With Objective-C, I have a LaunchBar action to instantly open any header by name, and I have a BBEdit search preset to search all the headers at once.


@ObjC4Life

You summarized the mentality problem so well.

“ObjC frameworks were designed for creating apps while Swift is very self involved; I think all the compiler people working on it are self involved too and made the language over complicated with features that have little use at least from the perspective of app developers.”


@Michael "I agree about not seeing a Swift killer app"

To be honest, I haven't seen an Objective-C or Electron killer app either since the arrival of Swift. Probably because the introduction of Swift killed application innovation.

"but that seems like a very high and probably unreasonable bar for a language to meet to avoid being a “complete failure.”"

The complete failure is related to the Apple's messages at the time Swift was announce (not the lack of a killer app):
- it was supposed to be simple to learn. That proved totally wrong as the syntax was not stable during the first years; as soon as you start writing something that is not a Hello World binary it becomes non intuitive; most Swift code that can be found on the Internet is less legible than in other languages and too much Swift sample code available on the Net is just not working anymore.
- it was supposed to be faster than Objective-C from the beginning. Which it was not in almost all cases and is still not 10 years later in a lot of cases.
- it was strongly suggested that it was supposed to be supported outside the Apple platforms or at least for everything: Desktop, Mobile, Server. etc. We're still not there and even though Chris L. tried to be the Jonnhy Appleseed of Swift by visiting multiple companies after his tenure at Apple, we're still not there.

"Certainly there are developers who say they would not have built their app if not for Swift."

It would be interesting to ask them if they would still have built their app if they had known how annoying it was to rewrite part of their code each year when a backward incompatible version of Swift was released.


For me the biggest turn off is the syntax. I do not like it (func, var vs let yuck!). I love the Objective-C syntax, and I love the verbosity. So easy to read. I get those are personal preferences though.

I do like the what-if though- what if Apple didn't waste time switching languages and instead made Obj-C better? I think we'd be better off, personally. I don't believe Swift added enough to make it worthwhile with those tradeoffs.


The lack of interest in Swift from experienced developers who weren't already involved with developing for Apple platforms is truly epic. Compare with the level of enthusiasm that Rust has built up in the wider developer population.


One language for the entire stack always struck me as an over exuberant move. The fact that Apple have created Pkl seems like an implicit acknowledgment that languages designed for specific use cases is a better approach. My overarching criticism of Swift is that it seems driven by dogmatism rather than pragmatism. I remember learning about why the caraet was used for Objective-C closures and realising how the constraints forced them to be pragmatic.


Swift gave me a newfound appreciation for Go.


> I dislike headers within my own project, but I really miss them as documentation for the public frameworks. It’s hard to find stuff within the gigantic generated header, especially with each type split into so many extensions. With Objective-C, I have a LaunchBar action to instantly open any header by name, and I have a BBEdit search preset to search all the headers at once.

@Michael Tsai More people seem to agree with you about headers. Posts I’ve read from other devs suggest I’m in the minority but I like that ObjC forces you to document your code. I usually add comments in my own headers for my future self but even if you don’t do that you still have your public interface clearly defined in a separate file. I don’t need third party apps like Dash etc.

To me mixing the public API and the documentation comments with the private API and the implementation all in the same file would be like having the table of contents of a book and an entire chapter all on a gigantic physical page. It feels more orderly to me with headers. I have the .h opened in one window and the .m opened in another.

>I love the Objective-C syntax, and I love the verbosity. So easy to read. I get those are personal preferences though.

@Matt B Same here. All the stuff I hear people complain about as it relates to ObjC I tend to like. I guess we’re weird.


Mike Oldham

I feel like the biggest impact Swift has had is getting Apple and most 3rd party devs to rewrite their apps in a new language often with regressions. The entire Apple ecosystem has felt stagnant for the last 10 years. Things feel more buggy not less. Its possible I'm getting less crashes than I did 10 years ago and maybe I can credit Swift for that but it hasn't been notable. Much crappier software has been noticeable. I've never been happy to hear an app has moved to SwiftUI from AppKit.


On a positive note, Swift 6 looks like a smooth transition, thus far.
A fairly big project, ca 300k lines(ca 70 % Swift), Swift, C++, MSL, Objective-C,
a game with a custom in-house Metal based render engine, completed a smooth transition based on all tests so far.
A few moths ago I enabled “Complete” concurrency checking, and bit the bullet. That was a wise decision.
The Metal API, though, does not play well with Swift 6 concurrency at this stage, so it still needs some serious manual domain isolation strategies.

Leave a Comment