My impression is that when working with Swift your first tool of choice should be a value type, so a strict or an enum. Actors would only be desirable when you need class-like behaviors and need concurrency. Maybe I’m missing something, but I suspect many of us will never use actors directly at all. I certainly don’t see any parts of my code which demand this kind of structure.
But concurrency is a really interesting case. Concurrency solutions are highly specific. I think we'd all agree there is no "answer" for concurrency, which puts it square in the library category. And there are consequences to getting your language's concurrency solution wrong. For example, I'd point to Clojure's built-in STM as a huge swing-and-a-miss. Otoh Erlang is the poster child for why doing concurrency right really does require language-level support.
What's the way out? Imo either build your language around concurrency from day 1, ie Erlang, Go, Pony, or accept that concurrency will always be a best effort good-enough solution in your language.
Precisely. "Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp." https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule
Ugh. I agree. I haven't actually used SwiftUI in anger yet, so I try to reserve my judgement, but the whole thing seems like a lot of magic and complexity to me (not to mention reports of some performance issues/gotchas).
Didn't they also add some weird dynamic JavaScripty property getters or something?
How so? Rust has an equivalent feature (impl Trait) for example. It solves a legitimate problem.
I totally agree. It's actually a big part of the reason I pulled back from Swift development for personal projects, since it appears that the core team has no problem shoe-horning in half-baked features if it's required to make the necessary impact at the keynote of WWDC.
However I think that example (along with property wrappers) shouldn't be used to impugn the language design decisions as a whole. Protocol-oriented programming is extremely powerful in Swift, and since I have switched to mostly using Rust over the past year for personal projects, there are a lot of things about Swift I really miss.
To be fair, that 'shoe-horning' took nearly a year and a half. Apple was willing to ship the feature but took their time and got lots of community feedback before a version of it became officially part of the language. I believe SwiftUI has already migrated over to the standardized version of it.
SwiftUI is in some ways amazing - because you (rightfully) get this feeling that they had several ridiculously-overqualified compiler experts working in tandem with UX experts and low-level framework engineers on it.
But the flip side is that you don't have a lot of parallels to draw experience from when using it - you must gain experience by working with SwiftUI itself.
So let me tell you, as someone who was a very active member of the community when these features were announced, this is not what that felt like. I, like the rest of the community, found out about function builders by noticing code presented on a slide at WWDC which would not compile under the then-current version of Swift. There was then a large debate within the community, where members of the core team presented post-hoc rationalizations about how "Swift was always intended as a language which would support DSL's and declarative programming". But the message was clear - this feature was going into the language, with zero prior community review or input, because it was required for the business goals of Apple.
The thing that made this particularly jarring for many in the community is that it was so far out of character for the general language evolution process. If anything Swift had been known for being slow at adopting new features. Every addition or change had to meet a very high standard of 1. feeling cohesive with the language, 2. not limiting the future design space, and 3. not presenting risks with respect to the ABI.
Highly necessary features like variadic generics with obvious utility languished for years, cross-platform support and tooling remained in this grey zone of working in some select cases but not others, and here were radical changes to the language being made which were not known to the community at all. For me and a lot of others it clarified things about the direction and governance philosophy of the language.
> But the flip side is that you don't have a lot of parallels to draw experience from when using it - you must gain experience by working with SwiftUI itself.
What would be the big differences you would see with other hot-reloading FRP-style frameworks like React and Flutter?
Yes, and this is one of the reasons that having well defined walls (and having names for those) is really important for commercially-backed open source projects.
It is perhaps clearer to say there is Swift, the language and open source implementation which has an open process for contributing changes. Then there is Apple iSwift, a vendor fork of that language, still open source, that Apple uses to leverage Swift for their platforms. This is similar to the relationship Apple has with clang and used to have with gcc (writing their own precompiled headers and blocks features back in the day, plus objective C itself at one time).
Function Builders were added to iSwift, and then Apple spent over a year getting it into the Swift language proper. Changes which affected the syntax of a mainline Swift feature were not off the table, although it would have affected the timeline of Apple being able to migrate developers to it.
As much as I actually do enjoy working with Swift (real type classes!!), there are some parts that are a big WTF.
This is exactly what the new async/await feature solves though. Actors are built on top of that.
They weren’t under any pressure at all to have any other ‘async’ story early on and so intentionally chose to focus on other fundamentals and take their time to build something that would be well designed and additive.
The early versions of Swift didn't even have a standard Result type, IIRC.
So even today, you will see some Swift functions that have `throws` in the signature and some that return `Result<T>`.
It was always awkward.
I agree that they are not idiomatic, which is the point I’m making.
There was a perfectly working solution that had no barriers to its use with swift, so it made sense not to rush the replacement.
Maybe it was the right call in the end (I'm of the opinion that it literally doesn't matter. Apple could ask us to develop in COBOL or even something as crazy as Objective-C and we'd all still do it), but I still think it's fair to say it was weird/surprising to have awkward/difficult async tools for an official mobile OS language.
I guess in relation to your original statement, I am refuting it.
They had a strong solution which was pretty easy to use, and as good as the language they were replacing, and well integrated with the platform.
The idea that they ‘didn’t have a strong solution’ doesn’t really hold from my point of view.
It was strong, and working which gave them the luxury of time to develop an idiomatic solution as the language matured.
If there really hadn’t been a strong solution in place, I would have agreed with you.
It is frustrating, but it seems like they are finally getting there. It’s frustrating since a language like Go had a good concurrency model almost from the start. But Go had different constraints and arguably has less surface area to cover.
Go is twice as old (since initial public release) and still doesn't have decent support for generalized algorithms, for example. They have struggled just as long to come up with a more usable error model.