Swift can open doors to the world of coding. In fact, it was designed to be anyone’s first programming language...
The doc also promotes Swift Playgrounds and a free curriculum for teaching kids.
This is all charming, and I really want to buy into it. I love Swift, we homeschool and my son wants to learn coding. It'd be cool if I could teach him my favorite language.
However, being frank about my own experience, I found Swift large and complicated. It does reward the commitment, but still requires a lot of time to learn. Swift 6 adds strict concurrency checking (albeit temporarily opt-in) which raises the bar even further.
I'm happy to confess I was a script wizard when I started with Swift. I had about twelve years experience, but the majority of it was with dynamically typed, interpreted languages, so I had a lot to learn. Still, we're talking about kids using Swift as their first programming language.
Is Swift 6 still a good language for kids to learn programming with?
We aspire for Swift to continue to be a great first language, yes. Swift Playgrounds is a perfect example of this, with tutorials that are simple enough for use at the elementary level, educational materials that are designed for the classroom, and a forgiving user interface that supports structured learning:
Swift also supports more complex features, but we try to hide them from beginners with progressive disclosure as developers become more advanced in their knowledge. And yes, it will take a long time to build mastery in Swift, but that's because it is a language that is also designed for building industrial-class highly-scalable software.
It's a rare language where you can see a six year old in an Apple Store writing in the same language that is used by engineers building one of the most sophisticated cloud AI services on the planet. Hopefully your son has a great experience with some of the tools above, and he goes on to build some amazing apps with it!
I would like to see how well progressive disclosure works in practice. It's not as valuable to a professional user (they generally want to grok the languages they adopt), but for a kid learning to program from scratch (who doesn't need to maintain other people's code), progressive disclosure could work well.
Moderator note: There was originally a discussion in this thread about the affordability of various kinds of Swift-capable hardware, and several of those posts were pretty heated. I decided to remove all of that from this thread because (1) it was getting out of hand and (2) it was overwhelming the more technical topics that I believe @7ombie was trying to talk about in the original post.
To make it specific, I'm concerned that mandating strict concurrency checking in future versions of Swift will undermine progressive complexity, making simple programs too conceptually advanced for new programmers, especially kids.
To explore this a little, I created a new command line program in Xcode, and added a top-level variable to the (only) source file:
var x = 0
Xcode was fine with this. Presumably, Swift is able to establish that there is only one thread in such a simple case. However, in larger programs, top-level variables are problematic. In any case, the following program is incorrect:
Due to the static variable on Line 2, Xcode complains that static property count is not concurrency-safe because it is non-isolated global shared mutable state.
Xcode offers three fixes:
Convert count to a let constant to make Sendable shared state immutable.
Annotate count with @MainActor if property should only be accessed from the main actor.
Disable concurrency-safety checks if accesses are protected by an external synchronization mechanism.
In practice, you cannot develop a substantial Swift 6 application without running into this message (unless you consistently preempt it, obviously), so you'll need a sound grasp of concurrency generally and Swift Concurrency specifically to use Swift 6 at all.
Yeah, it’s easy to start with global variables and top-level expressions, but you quickly hit a complexity cliff. I think as soon as data types are taught, they should be used for all state instead of global variables.
I'm not sure nesting variables inside other types buys you anything, as the variable properties still need to be variable, which isn't the case when instances of that type are assigned to constants (assuming value semantics):
struct Datatype { var count = 0 }
let data = Datatype() // now `data.count` is immutable
With this example and that other thread where folks wondered about 'disabling' concurrency, it could be worth exploring whether there's some area between print("Hello, world!") and, say, the Weather app where Swift can deterministically know (not just by heuristically guessing) that we're in an "everything-on-MainActor" situation.
It isn't aimed at kids (it targets higher education), but starts from scratch and relies on global variables in the first parts (before custom types are introduced). After Swift 6 is released, I'll check all the examples for concurrency warnings. That should give us a lot of insight in just how much strict concurrency checking affects new learners, and what workarounds are available.
Progressive disclosure has served me really well so far and I agree that beginners should not be exposed to terms like "concurrency-safe" or "non-isolated" before they're ready to learn about what that means.
It probably isn't, but you will also have to explain to them why not (use globals).
Simple flat programs with global variables are the remnants of the single-core era of the 1990s and partly 2000s. Most of the mainstream languages today are the "children of the 1990s" (Python, JavaScript, etc), it's why their tutorial examples are full of this simple non-concurrency friendly code, let alone that many of these languages themselves are single-threaded by design.
Swift is absolutely right in requiring the learner to be aware of concurrency, but the benefits of it are harder to explain, especially when there are older languages lying around that don't impose this knowledge.
I once suggested somewhere else that the compiler could have a command line option for assuming MainActor for everything top-level. Not 100% sure it's a clever idea but worth discussing at least?
I think it would be better to change the question to "Is Swift still a good first language after Swift 6 update?"
TLDR: Swift is a good first language, Swift 6 is just a new version of Swift that has added more features. A good first language is not only determined by the complexity/scale of the programming language.
Complete Version Below:
Per my understanding, a "good first" language should fit the below criteria:
Syntax Simplicity: This determines the difficulty for beginners to start a language. Most programming languages popular nowadays (e.g. Python, Javascript) are good to start with, and they are included in different school's curriculums, globally. Definitely Swift has simple syntax.
Practical Application: The language is widely and commonly used. Swift is commonly used in developing apps in Apple Ecosystems, and Vapor/
& Hummingbird are very good HTTP web frameworks written in Swift. Apart from that, Embedded Swift also shows potential in Embedded Systems.
Learning Resources: There is already an official tutorial/cookbook for Swift, and tons of tutorials, and its application.
Community Support: We have a forum here, at least, and many people are discussing different use cases on the internet.
Therefore, Swift is definitely a good first language.
The point is, that concurrency or thread-related topics are NOT beginner-friendly.
I didn't expect someone, who has zero knowledge in programming, would know the principles of concurrency, how Swift concurrency works and its implementation(how to use actors, when you should create Tasks, how to implement AsyncSequences, when you should create custom global actors...etc.), within a short period of time.
Yes, eventually they will reach that moment if they continue to learn: oh, it is time to learn concurrency! But when they reach that moment, I think it is already beyond the consideration of a good first language.
When’s the last time you helped beginners learn Java? All of the public class MyProgram and public static void main() is just boilerplate that people memorize to sandwich around their code.
Swift’s top level code support was an explicit reaction to that ceremony. It seems like giving up to say beginners can’t use it.
Any (almost) language can be a good first language. About a decade and a half back (not a long time) we have had no LSP and autocomplete in general was a luck, looking up function signatures in documentation until remembered (well, at least that's my experience starting out), and many didn't stay away because it made hard to learn. So IMO it is more a question of a motivation at first, rather then language complexity, especially if we talk about kids. With any language there will be some concept, that might be not so clear from the beginning, but inevitable to use: pointers, magic __main__, class per file, etc. (I'm not talking about JS and its fantastic type conversions that will be a complete nonsense if you starting out!).
As for Swift, I agree with the take that you don't need globals and statics. For instance, I'm not even sure I was understanding usability of statics when I was learning my first languages – recalling that for a long time I just couldn't find where to use them in my code. But even if we take that you have to deal with them anyway, compiler gives you a meaningful error, that you can read, ask, and for start just accept that things work this way, without any need to dive into concurrency. Again, with any language we took something as "things have to be this way" until we could understand them – like arguments passing in C (was a total mystery for me starting out), or static main in Java.
There are much more complicated topics, that actually deserve more attention and won't go away – what are the classes? What's the difference between reference and value semantics? Protocols, finally. Like you can't take this complexity from the, well, virtually any modern language, and so far it has been put aside due to a few errors, that you can read and understand.
I don't want to sound like gatekeeping, but trying to take language to the extreme simplicity isn't the solution as well, there should be a "challenge" to learn, because that's not something everybody can get in a day. Swift still handles this much better than most of the languages with progressive complexity disclosure as part of design: other languages just throw you into a pile of various concepts and APIs you have to navigate, it is just getting less obvious once you have experience.