Swift's Evolution
carpeaqua.com
carpeaqua.com
I get that if you're shipping Swift in production you want to refactor as little as possible, but it is pretty hard to come up with the ideal design straight out of the gate. Swift can stop evolving, but it will be THEN when it loses the reason to exist. If Swift is just going to be ObjC with a nicer syntax, (or the features that YOU personally find desirable), then why bother with it at all? Swift is trying to get its design right and that takes time, at the same time I wouldn't want to be stuck with a poorly designed language for the next 30 years, so it's worth the current turbulence for me.
(Rust was the same way 2011-2015 to a MUCH bigger degree and it did in fact eventually stabilize as promised.)
If it's that much of a problem, ObjC isn't going anywhere, it's your choice.
EDIT: Fixed a typo.
I think the issue is that for the last year or two all of the tutorial websites and the third party library ecosystem have moved from Objective-C to Swift in a big way. If you are new to iOS development this might lead you to have a false sense of security with regard to the overall stability/quality of the language.
Swift is a lot of fun when it works. I hope this year's WWDC will mark a big turning point for the language. Last year it was pretty painful, especially if you needed to use third party Swift libraries.
I do think the Swift developers are getting better about that, fortunately, but a lot of developer goodwill has been burned in the meantime.
I get what you're saying, but a 'prototype' is perhaps a bit far. Rust was far from being called a prototype years before being declared stable, however I do agree that branding Swift 1.0 in 2014 was a mistake. Personal theory is that if you want to release something at Apple to the public, and Chris wanted to get feedback, you have to brand it 1.0
> just saying "we warned you there were going to be breaking changes :shrug:" drips with contempt
Ouch, that's going a bit too far, Chris Lattner definitely doesn't strike me as someone who has contempt for developers. He gave us LLVM, (which BTW Rust uses as its backend) and by all signs he worked very hard in the background to get Swift open-sourced. Now they're taking a lot of feedback from the community via their Swift Evolution process and the Swift community wants the language to continue to evolve, so it does, not sure what could've they done better in this regard.
But I'm happy that people are playing with it and the language is being refined so that I can start using it in a few years.
Obviously because "production" is not some monolithic reality.
What's "production" standards for NASA or Google, might not be for some small team making an iOS app or an one-person indie shop.
They might prefer to experiment with the language in their app, and get a leg up on learning it starting from the initial release, even if there's gonna be pain.
Even for actual commercial code, the supposed "pain" this article mentions is really nothing to write home about.
Having to spend a week doing manual code changes because APIs were renamed is no biggie at all in the grand scheme of things.
Contrast with whole full blown languages and libraries used in production change completely or get deprecated/abandoned. Things from Microsoft inventing new stacks and deprecating others every few years, to J2EE dropping the crappy EJBs that tons of programmers had based their code on, to React Router being redone in a new style every year, to GTK/QT N to GTL/QT N+1 transitions, ...
I agree, but I suppose these kinds of shops wouldn't then write blog posts complaining about this, I think the OP meant shops that do it anyway and then complain...
Admittedly I'm basing my opinion on Swift as it was about 12 months ago so hopefully someone can tell me how wrong I am and that the frequent IDE crashes and compiler bugs are fixed, refactoring is now available, autocomplete works really well, compile times have improved, and the language has no more breaking changes, etc.
It's just that I have work to do and Objective C is still solid and dependable. Playing with Swift was fun but I kept running into too many yak-shaving diversions to get even basic things done.
So is it time for me to switch?
Lots of projects more important and substantial than anything you and I have worked on have been shipped with Swift. So that argument doesn't really fly. Apps redone/adopting Swift include Twitter, Pandora, Groupon, Fitbit, etc.
(Heck, major billion-dollar companies had built parts of their production infrastructure on Node when the thing was just on very early stages).
https://www.youtube.com/watch?v=X9waDi787uo (14:15-15:30, 39:26-40:37)
That is, precisely what we are trying to access.
I never have the IDE crash and haven't for the last year+, never have problems with compiler bugs. Autocomplete is fine, compile times are ok, and the changes for each version have almost always been automatically converted for me.
Refactoring would be nice. A faster compiler would be very nice, but there are build settings (see Uber lead engineers recent blog) that can massively improve build times in large apps.
I look forward to the magical bug free future when I switch to Swift.
Swift is far more readable and a bit more concise than objective c, that makes it more maintainable. The bigger win is of course optionals, which, (if you embrace them properly), can mean your app will never have a dangling pointer or runtime crash from a nil pointer.
I spent nearly 20 years writing object oriented C and Objective C apps for personal computers and phones, and dangling pointer crashes were the biggest possible sinkhole of time, and worse degradation of product quality.
I can't imagine ever going back to objective c.
ABI stability is the only real issue I can see now.
You can put up with these, and I think it's worth the tradeoff, but you should definitely consider them carefully before putting a lot of effort into build a real-world Swift code base.
Ironically this forced me to start using Swift Package Manager more and to split my projects into frameworks.
Now I do admit the build times were awful and I had a couple puzzling crashers that were only cleaned up by Swift 1.2 (thankfully didn't ship till after 1.2 was final), but the transition was worth it.
You can take Objective-C code written three years ago, open it up in Xcode today, and compile it. The same cannot be said for Swift. So saying Swift 1.0 was "far superior" in terms of maintainability is a bit of a stretch, in my opinion.
It would also be really challenging for Swift code written 3 years ago to compile, because Swift wasn't released yet.
I don't think the "maybe objc is still relevant for new project" trend we've been seeing the last few months on HN is going anywhere. I'm currently in the process of converting a large codebase from objc to swift, and there is absolutely no doubt that the language is WAY better, and brings a lot of safety enhancements as well.
The only big remaining pain point now is clearly in the tooling, but now that they're stabilized the language a bit more, it's probably going to get better fast.
I'd be interested in further information about this, if you can share some link here.
"Async/await are effectively proven at this point and would fit well with the Swift type system and structure, we should probably just do it.
Erlang/Akka have proven actor models. Swift providing syntax yields a declarative model which enables programmers to reason about what mutable state goes with each task. Each actor is effectively a DispatchQueue + state it manages + operations that act on it.
Actor approach also generalizes well to future. It could be a great way for handling heterogenous compute (e.g. GPU tasks), distributed compute, etc since each async “call” to an actor really is a message send (thus could be DMA or IPC)."
I don't think a video of that talk is available online. https://researcher.watson.ibm.com/researcher/view_group_subp... doesn't mention it.
Wouldn't it also need to be cross-platform in that case?
It's sad that Kotlin and Swift are so similar but not similar enough.
(Although I'd prefer a dynamic language to be the "next big language" - it seems the pendulum is currently swinging back towards static typing...)
Swift is absolutely cross-platform. I've used it a lot on Linux. I think I even prefer it to Rust for things like server applications.
I think Swift may even be available on Windows now. But it's definitely available and rapidly maturing on Linux.
And having struggled with large code bases in dynamic languages for years, I'm very happy that statically-typed languages are resurgent now.
Quite a good move on their part if it is successful. If kids start learning Swift at school, they get exposed to Apple devices (not necessarily but this is where the teaching resources are aiming), and they've got developers in their arena from an early age.
Yeah, Swift needs ABI stability, but I also understand that they don't want to screw it up by adding it too soon. Because the goal of Swift seems more long term oriented, short term ABI stability isn't worth risking a 10 year goal for.
I haven't used it, nor do I work in education, but what I have read of it, it at least is successful in the sense that those who use Apple's Swift training material find it to have good quality.
For example, http://www.speirs.org/blog/2017/6/1/a-year-of-teaching-swift:
"In times past the experience was that, if you were an able student in Computing, you would get your programs working. If you were not an able student, your experience would be almost insurmountable challenges to get anything working. Working or not-working was the differentiator in the class.
In the Learn to Code curriculum, I found that everyone got something working. The difference between the stronger students and the weaker students then was more to do with evaluations of the complexity of their solution, the understandability and style of their solutions or other factors like memory and time efficiency.
I have never really had these kinds of conversations in classes at this level before. It has been an incredibly satisfying year to get the opportunity to debate which of three possible solutions is the 'best' for a given problem and, further, what definition of 'best' we should accept."
It also is good to see that Apple expands its offering. https://www.apple.com/newsroom/2017/06/swift-playgrounds-exp...:
"Apple is working with leading device makers to make it easy to connect to Bluetooth-enabled robots within the Swift Playgrounds app, allowing kids to program and control popular devices, including LEGO MINDSTORMS Education EV3, the Sphero SPRK+, Parrot drones and more. The Swift Playgrounds 1.5 update will be available as a free download on the App Store beginning Monday, June 5."
var someId: Int!
...
let urlString = "\(baseUrl)/\(route)/\(someId)"
Result in Swift 2: "http://ac.me/products/123"
result in Swift 3: "http://ac.me/products/Optional(123)"
Happy hunting! Some of this ended up in production :(They've changed it to a warning in later versions of Xcode 8 at least. But that was too late for me.
Apart from that it's a big step forward, less wordy than Objective-C yet it's still "readable language" instead of a bunch of almost random generic English words.
I'm not sure about async / await. Whenever I deal with it in .Net languages I never find it that intuitive compared to blocks. But you know every programmer suffers from Stockholm Syndrome at least a bit so it could just be my mind warped to not only accepting but even glorifying the flaws in a language.
There are people out there that genuinely like JavaScript for instance!
The networking libraries I've worked with just use string interpolation:
Xcode build tool is the worst. Compiler time is the most hurt. Very slow. Android, react and xamarin already support hot swap compile.
Migration tool is not working. I'm not sure this year xcode able to refactoring rename method
ps: Well, maybe pure objc is not the best choice, since it's on its way out, but it's a long way to its end.
There are none. Don't transition an existing, stable ObjC project. I don't understand why this is a thought anyone would entertain, especially since ObjC itself isn't going anywhere.
If you are starting a new project in Swift and it will be pure Swift, that's fine. Go for it. Do not attempt to migrate existing ObjC projects or use Swift in them.
Why does make treat tabs and spaces differently? Because Feldman's original version had that bugs and he didn't want to disrupt the <10 users and their <100 makefiles. That was the wrong decision, though he didn't know it at the time.
However many users Swift has today, tomorrow there will be more. However many lines of code are written in it, tomorrow there will be more. The pain of making a change will only increase.
Apple was up front with everyone about Swift 1: there will be source-breaking changes in the future. Swift 3 was targeting source stability so it was the last chance to make such large changes.
In contrast, Swift 3.2 and Swift 4.0 are compiled by the same compiler and can be linked together. That means you can upgrade each module separately and don't have to wait for dependencies to upgrade. That's a huge win.
Swift 4 also brings Codable which will shave a massive amount of boilerplate from many codebases. The String overhaul is great too, along with generics improvements. These all affect the standard library and thus ABI stability.
The Law of Exclusivity is in, which is the core of the upcoming memory ownership model, which itself will enable async and other concurrency paradigms. This also affects ABI.
Once ABI stability lands the pace of standard library changes will necessarily slow dramatically. It is important to take the time to get things right, rather than rushing and locking bad or insufficient designs into stone.
For all of these reasons, at least: https://github.com/apple/swift-evolution/blob/master/proposa...
C style for loops come pretty early in most programming tutorials, but I wonder how much non-C programming does actually use them nowadays (from the Community Responses, it seems not much Swift courtesy of other options). Usually, a C style for would be to loop over an array, and a safer way to do that probably could have stopped countless vulnerabilities & bugs occurring over the years.
Meh. Many languages don't have c-style for loops in the first place. Neither Python nor Ruby do for instance. I don't think Rust ever had them either[0].
[0] https://www.reddit.com/r/rust/comments/2957fg/can_i_request_...
for thing in collection: process(thing)
and very easy to move from that to a functional style: map(collection, process)
or collection.map(process)
The number of times I also need a integer counter is fairly small. for (index, element) in collection.enumerated()
There are some cases where the C style for loop is the most natural way to express something. For example, looping over NULL-terminated array of pointers is nicely expressed with one (Swift 2-ish pseudocode): for var cursor = ptr; cursor.pointee != nil; cursor += 1
But these situations are really rare, and when you do encounter them, it's not a big deal to transform them into a while loop: var cursor = ptr
while cursor.pointee != nil {
defer { cursor += 1 }
...do stuff...
} result := collection collect:[ :a | a process ].
result := collection collect process.
collection do process.
1 to: 10 do: [ :i | stdout println:i ].
stdout do println: (1 to: 10).
All just plain messages and plain message syntax, no special control structures needed.So, the question should be whether Apple should have prioritized new users of the language over their existing language users. I think they made the right call, more so because they pre-announced it. Not only didn't they claim the language was frozen, the specifically said it would see changes.
The sheer amount of churn in Swift between v1 and v3 was what has kept me on the sidelines. It was only that Apple plainly stated last summer that they were done radically changing the language that I was willing to get into Swift at all.
Also swift and kotlin are very similar. The folks from kickstarter gave a great presentation about their android/iOS app being written in Swift/Kotlin at a conference I spoke at (UIkonf). Their whole mobile team writes/reviews for both platforms.
In 3-5 years Kotlin might be where Swift is now, but there's nothing guaranteed, just coming up with a GC solution alone is a gigantic engineering effort -- Kotlin, like Scala, Clojure, etc. all benefit from world class GCs, just by being hosted on the JVM. With LLVM you essentially start from scratch, same for porting Java libraries, there's a ton of work involved.
tl;dr; for now it's separate languages for iOS and Android unless you cut some corners with React Native to avoid writing the same app twice.
Practically, though, any solution like that is going to be a second-class citizen in a world where Apple jumps and you ask how high. Xamarin's a great example here, even if Kotlin might be sexier as a language: there are certainly teams building good native iOS apps using Xamarin / C#, but it's hard to see it ever being anything more than a niche tool.
I agree that Swift has seemed to been infected with the disease so many open source projects get; focusing on over polishing instead of big picture and innovation but it's still my favorite new language.
Edit: I missed the author mentioning the utility sucked. Sorry!
Yes, but in the article he writes, "The migration tool caused more issues than it automatically resolved, leaving a manual migration as the only sane path forward."
I'm all for progress and modern ideas in a programming language, just don't break my old code!
I prefer the Swift way, and had to move 2ish to 3ish code myself and it didnt suck that bad.
I doubt that they want to, but it is really hard to redesign something you didn't get right the first time in a programming language, without breaking some code. The choice is then to leave the bad design as is, but be stuck with it for the next few decades, (which would be kind of terrible, given Swift was meant to eventually replace ObjC precisely because of this), or you can suffer the pain now, while relatively early, to not have to suffer latter.
I think they made the right choice, in terms of prioritising long-term benefit over short-term gain. ObjC is still fully supported for those who want it and in the meantime, we can get a more perfect Swift.
That's the key take-away for me.
Of course Swift has an easier time with some syntactic issues than Objective-C, which is two languages crashed into each other. And yes, Objective-C was way, way overdue for a better replacement. Heck, just dropping the "C" part from the language syntax and reducing it to type annotations in a nice typed Smalltalk (see Strongtalk, or TS) would have fit the bill.
It's not as if there aren't lots of problems (and your list will almost certainly be different). For example, applications are no longer just code, non-code resources are just as important, but support for them is at best rudimentary. So with pluggable scheme handlers and polymorphic identifiers, we could write
checkBoxImage := img:checkbox.
And have the "img" scheme handler statically check resource availability against a list automatically imported from Xcode's resources (pluggable, see F# type providers). Of course, the internet also happened, so shoppingPage := http://amazon.com/
should also work, because why should obtaining resources outside your machine have so much extra ceremony. Abstracting should of course also work: scheme:amazon := ref:http://amazon.com asScheme
shoppingPage := amazon:/
And of course you can compose scheme handlers, so you add JSON or XML decoding and then use the resulting scheme handlers as if the original data sourceThen there is keeping UI and model in sync. There were bindings, but these were hacky, somewhat unreliably, undebuggable etc. Much better to generalize and integrate a constraint mechanism into the language:
-<void>setupTemperatureConverter
{
ivar:f |= (9.0/5.0) * ivar:c + 32 .
ivar:c |= (ivar:f - 32) * (5.0/9.0).
ivar:k |= ivar:c + 273.
ivar:c |= ivar:k - 273.
ivar:c =|= ivar:celsiusTextField/intValue.
ivar:f =|= ivar:fahrenheitTextField/intValue.
ivar:k =|= ivar:kelvinTextField/intValue.
}
That's actual code for a temperature converter app, setting up relationships that get automatically maintained. And if you make constraint handling support pluggable as you should, you also have a proper syntax for writing autolayout constraints. And Makefiles.Together with composable scheme handlers (see above), this gets rid of the vast majority of your view controller code.
Then there's the nib vs code dance. Or storyboards. All semi-solutions to problems that are largely (but not entirely) architectural in nature. All can be aided tremendously by good linguistic support, putting to rest many of the recurring problems we have with these technologies (or conversely with not adopting them).
Swift does nothing for any of this.