Swift’s focus on progressive disclosure means most Swift users won’t need to worry about this.
Swift’s focus on progressive disclosure means most Swift users won’t need to worry about this.
Unfortunately for me, it's not aligned with my preferences. I like small languages and frameworks that I can master and build upon. Tough luck for me, of course, who cares.
But I'm not convinced Swift is also aligned with what should be the language's main purpose: build great iOS and Mac apps.
8 years later, it's safe to say it's not the language of choice for the new kernel or driver code, not the one for the hot new web framework and it's not replacing Python.
The only thing it's got going for it is that it's the only officially supported choice for making iOS apps going forward. Ultimately, no one uses Swift voluntarily, and that's a bad sign.
I write all of this with sorrow, I was cheering with joy when Swift was released.
Sounds like D.
I would use it in more places if I could, it's a language I feel extremely productive in. Apple however has shown zero interest in helping popularise it anywhere outside of their ecosystem and left it up to the community.
They also dedicated some time on the state of the frameworks session, to put it clearly out there that Objective-C is done and it is time to move on.
It took about 20 years for C++ to take over some key areas to C, and even there it wasn't a success in POSIX and embedded, where C still rules.
8 years isn't nothing.
Is that the "Platforms State of the Union" session from the first day of WWDC 2022? I'm looking in the Developer app right now and can't find the "frameworks" one you're talking about.
Around 4 minutes into it.
> But designs evolve, hardware advances, and what was once cutting edge becomes the expected baseline. The Objective-C language, AppKit & UIKit frameworks, and Interface Builder have empowered generations of developers. These technologies were built for each other, and will continue to serve us well for a long time to come, but over time new abstractions become necessary.
https://developer.apple.com/videos/play/wwdc2022/102/
It gets worse from there, for Objective-C. The speaker goes on to basically say that the new triumvirate of "integrated language, frameworks, and tools" is Swift, SwiftUI, and Xcode Previews, and that these will be evolving together, and influencing one another's evolution, as Objective-C, the "kits," and IB once did for one another.
I love coding in Objective-C, and did so for work for almost 5 years. (I've within the last year switched to a front-end developer job.) Swift, to me, whatever its upside, feels like it was written by someone who hates Objective-C. That makes me sad.
But, putting aside my editorializing, I read what Apple is saying as basically this. Objective-C, etc., is all but deprecated. At long last, it's being left behind. You may get away writing CRUD apps for a good while longer, but all the new stuff will be Swift-only, and at some point any UI written in Objective-C is going to start to look dated, once the inevitable innovations come.
I write Go for work and my all-time favorite language is probably still Rust, but I find that a ton of really thoughtful and smart choices have gone into Swift-the-language as well as how it’s used to build apps.
Happy to expand more on what I like about using Swift if you’re curious.
[1] which you can now write as the same codebase using SwiftUI
I like that. I'm stealing it :)
> Happy to expand more on what I like about using Swift if you’re curious.
Please! I was very excited with it at the beginning, but the few times I dipped my toe it was frustrating and slow.
You led me to finally track down the name of this feature in Bash: "brace expansion"! I often wish my non-techie friends recognized this syntax, along with sed replacement syntax for fixing typos.
> I was very excited with it at the beginning, but the few times I dipped my toe it was frustrating and slow.
Okay, it definitely can be slow to compile, especially with large blocks of type-inferencing ResultBuilder DSLs like SwiftUI or RegexBuilder. I find this mostly occurs when there's a type error within the DSL, and it often takes forever for the compiler to stop trying to do inference and give up with "Type of expression is ambiguous without more context" or simply "The compiler is unable to type-check this expression in reasonable time". But in practice I rarely run into this issue unless I'm creating a massive hierarchy that should be split into smaller components anyway. And I haven't really run into issues with runtime performance yet, though I haven't made anything too performance-critical with it. In any case, Swift makes it decently easy to call out to C/C++/Objective-C if you had a performance-critical routine.
What I like about the language:
It gives me the satisfaction of languages like Rust that let me express types and logic in a way that feels "correct". I rarely feel like I'm hacking stuff in due to deficiencies in the language. Swift encourages a standard approach of record types with polymorphism but still supports legacy NSObject-based stuff in a logical way, so I never feel like I have to jump through too many hoops if I need to touch dusty old frameworks.
I like the type inference, even if it's not perfect category-theoretic Hindley-Milner magic and gets stuck sometimes as mentioned previously.
I like the `guard` statement as someone who's done a lot of Go programming and always instinctively used early returns even when my CS professors told me it was a bad practice ;)
SwiftUI is really nice to use and is the only UI framework that I've ever enjoyed using (and am hoping to write it for my job soon)--it sometimes feels more like a UI prototyping tool to me because it's so straightforward, except that at some point while prototyping, you realize you've already made the finished UI without writing a dreadful mountain of glue code and interface files!
I really like the syntax in general, though I also appreciate Rust's terse symbol-based approach, I think the English-like labels actually work really well despite being a bit verbose. It definitely benefits from an editor with autocompletion, but I wouldn't say it's strictly necessary.
I appreciate the strict Unicode-correctness of the language that makes it harder to do bad stuff with strings.
I think the ARC-based approach to memory management is a good balance between Go's GC and Rust's borrow checker that makes Swift feel like a very pragmatic choice for lots of different problems (though UI was obviously first in mind).
I really like the ArgumentParser and RegexBuilder frameworks, and I think they're the best implementations of each in any language I've used.
In general, Swift just feels good to write and easy to read while being extremely powerful in what you can create with it, and coupled with the ease of use and fast feedback of SwiftUI, feels like a very complete approach to creating many different sorts of software, for my own use or to sell.
Not true for me, I've used it successfully for server side work. Being able to use the same language is nice since I can pull in the same routines/data structures and not re-implement them.
Sorry but this can't be more wrong. I love Swift so much that I can tolerate and forgive its compiler's sluggishness.
Swift is now available on Linux (has been for a while) and there's Apple's server framework called SwiftNIO. It's designed for fast and efficient multithreaded server-side code. I voluntarily picked it for my next backend project and am very happy so far.
On the Linux front, there's Apple's SwiftNIO which is a generic lower-level framework that itself is not an out-of-the-box web or API framework. You need another extra layer above it, which is for example this community-driven project called Vapor [2]
You can, in principle, build a e.g. JSON API based on barebones SwiftNIO and you will save a lot of 3rd party dependencies in this case, but this path is a bit masochistic, you really need to know what you are doing in this case. Vapor is much easier to jumpstart any kind of server project with.
I admit that I last worked with it in early 2020, but at the time there were numerous annoying open bugs with the Swift compiler on Linux (such as the installer messing with the Python path), and then there was the issue of divergence between Foundation (which is closed-source) and its Linux replacement. Meanwhile, the stack size for secondary threads was ridiculously low and there was no good story for fault recovery (because you don't want to crash your server if you accidentally access an invalid array index).
Maybe things have improved, but I'm doubtful.
Rust has become all that, and for a change, I am happy to observe that we're stuck with a pretty good language.
I sense a lot of Rust envy among Swift people. Just my impression, of course. They have much in common, but I think Rust has more merits on its own, particularly in memory management.
Basically, a timid but interesting step to get Swift to move toward ownership semantics, on top of its current Arc based memory management.
With the features which were released alongside SwiftUI, it seems like that went out the window, and Swift pivoted towards being a DSL for iPhone apps.
I’m just afraid that the language can’t be properly maintained from the insane matrix of all these features (I once got a type inference timed out error..)
I used to work on a large Swift program. "Type inference timed out" was an incredibly common error that we would encounter (we used a lot of operator overloading and generics and that had something to do with it). I have never encountered any other language where this was such a regular problem.
Rust has its macros, Swift has its result-builders.
The latter wins a nice way to declaratively-describe UI widgets, but if that's not what I'm doing I don't need to think about it.
And due to the governance of the language, the "community" priorities will always take a back seat to Apple's product priorities, so it feels a bit funny to invest too heavily in the language for that reason alone.
It would be nice to have variadic generics, though.
The difference is that Rust macros are general — they're useful for everybody, and they can be used to implement nearly any kind of custom syntax or code generation.
There was talk on swift-evolution going back to the Swift 2-3 days about how Swift was eventually going to get “hygienic macros” that looked something like Rust’s proc-macros. But this was a very long-term goal; everyone knew it would take years to design and implement such a system that had the flexibility, safety, and expressivity we all wanted.
In the meantime though, Apple started to add a lot of complicated features using compiler magic. This started with Codable, which added language support for serializing and deserializing objects to formats like JSON. This was awesome, and became one of Swift’s best features IMO. But the implementation bothered me a little: it’s a protocol where the compiler will synthesize a default boilerplate implementation if you don’t implement it manually. But this is exactly the kind of thing that a real hygienic macro system would be better for; e.g. Rust's serde does the same thing as Codable, but it's way more powerful and more flexible. IIRC some people pointed this out on the forums, but this was dismissed with “we want to ship this now, and macros are years down the road.” Oh well, don’t let perfect be the enemy of good, right?
But the Swift 5 release had even more compiler magic — a bunch more protocols gained automatic compiler synthesis, and then “result builders” happened. Again: a feature that’s helpful in isolation, and solves a real problem, but greatly increases the language surface area. And since these features are implemented using compiler magic, only the compiler team can add new features, and it takes a long time. So in practice, the only magic features that get implemented are those that Apple needs for their libraries. Whereas if they had spent that time and effort working on a hygienic macro system, they could have achieved Codable, result builders, and every other use case library authors can imagine. Chris Lattner has indicated that this sort of thing was part of the reason he left the core team: "It is obvious that Swift has outgrown my influence, and some of the design premises I care about (e.g. "simple things that compose") don't seem in vogue any more." [0]
It became clear (partly through this, but also because of a LOT of other stuff) that the evolution of the Swift language was being driven by Apple's internal schedules, and not the other way around. Controversial or half-baked features were frequently rushed through review in order to be ready in time for WWDC -- or even worse, shown off in surprise reveals at WWDC, with the core team saying things like "yeah we know this is a bad design, but we showed it in the WWDC keynote so we can't change it now" [1].
At this point, I started to experiment with Rust because Swift's memory-management overhead was causing me too many performance headaches. It felt like a breath of fresh air: the language feels like it evolves at a snails' pace compared to Swift, but every feature that makes it into stable is extremely polished and very well-thought-out, especially with regard to how it fits with the rest of the language, and how it works in "weird" situations like embedded environments.
[0]: https://forums.swift.org/t/core-team-to-form-language-workgr...
[1]: https://forums.swift.org/t/se-0258-property-wrappers-second-...
Instead we got Swift, which ironically, given its uptake by external devs, I think was aimed at complaints from internal Apple users. Internal users at Apple were frustrated by how easy it was for external devs to introspect and modify private ObjC framework code. They also wanted performance features like value types and method inlining.
I don’t think many external app devs cared about those things, or to the extent they did C++ was an attractive option because a stable ABI doesn’t really matter internal to application code.
I continue to use ObjC for Mac and iOS dev because it’s a much simpler language than Swift, the system APIs I interact with are still implemented in ObjC, and C++ interop is easier via ObjC++. I suppose the day will come where I need something that is only accessible from Swift, and I’ll write Swift then, but for now Swift doesn’t solve any problems that I have.
Swift apps are not crashing randomly, you don't have nils running rampant because of type safety.
You can create types that nicely convey reality using rich enums and you don't have to define objects with 18 fields that are mostly always nil, but when propertyA == 16, then this field has some value.
Swift also is not an official superset of C, like Objective-C, so you don't have all the footguns of C language, like integer promotions and assignment being an expression.
You just have so much improvements over objective-C if you want to ship an app to hundreds of thousands of users and be sure that it works correctly and that unhandled edge cases won't blow up.
Maybe it is more complex to write a compilable piece of swift, that a compilable piece of Objective-C, but I am happy that this is the case, because it means that the compiler has my back and finds bugs and issues for me.
Right now, I have a research project using Swift Charts and it definately "crashes randomly" partially because Charts expects a subset of type-safe values and does not communicate which subset except by chucking EXC_BAD_ACCESS with no usable error.
Sure, that's example of a beta framework. However, SwiftUI is the proposed Swift-y replacement to Objective-C's UIKit and is loaded with examples of "the type system we moved to should catch this but can't" followed by the even more common "the type system will catch this error in 11,000 years when it's finished failing to compile code on an M1".
It has been on Swift documentation from day one.
But read/listen to what Lattner says and you get a different take.
>...the goal was really to build something that you could write firmware in or that you could do scripting in, that you could write mobile apps or server apps or low-level systems code, and have it be great at all of those, not just some terrible compromise.
Taken from https://oleb.net/2019/chris-lattner-swift-origins/ to save listing to the whole interview
Feel free to actually listen to the episode as well, and also read/listen the sections on how Swift is a complete Objective-C replacement without the bad C parts.
I wish there are more languages that focused on happiness of the compiler authors so that they can write efficient and small compilers with well-thought language features that intentionally limits how much they need to write in the compiler. Today we have such a huge compiler maintenance burden and as a result, you saw inconsistencies everywhere with these languages, and it is after many hundreds of person-year spent.
(Yeah, Go is probably one of the language that focused on compiler authors' happiness)