15 ms·
> It is obvious that Swift has outgrown my influence, and some of the design premises I care about (e.g. "simple things that compose") As someone who was heavi
by skohan 5y ago
> It is obvious that Swift has outgrown my influence, and some of the design premises I care about (e.g. "simple things that compose")
As someone who was heavily invested in Swift, and an active member of the community from around 2015-2019, I'm a bit sad to see the direction the language is taking.
From the time I started experimenting with Swift, I absolutely loved the philosophy of the language. It seemed to really prioritize having a set of well-factored systems, each with their own very rationally designed interfaces, which could be composed to do really powerful things. It was an incredibly expressive language which allowed for writing code with an incredible level of clarity - when writing Swift code I always felt I was writing at the level of the problem domain, not writing syntax. At the same time it offered really nice features for ensuring safety and correctness, like ADT's and best-in-class nullability syntax.
It was a language which sometimes seemed to move at a glacial pace, but the implicit tradeoff was that when a feature landed, it was for the most part very well thought out, and would add to the language with minimal negative impact.
A few years ago that seemed to start to change. From my perspective, some of the features added to the language to support SwiftUI - specifically property wrappers and function builders - very much felt rushed and forced into the language based on external deadlines. And imo they have a largely negative impact on the language: it used to be the case that you could look at a piece of Swift code and roughly understand how it would compile to assembly pretty easily, but with these new features there's a ton of compiler magic going on behind the scenes.
- Grustaf 5y ago> And imo they have a largely negative impact on the language: it used to be the case that you could look at a piece of Swift code and roughly understand how it would compile to assembly pretty easily, but with these new features there's a ton of compiler magic going on behind the scenes. What do you think the ratio between people who want to understand what the assembly will look like, to people who want a simple and powerful way to write apps? I think it's very close to 0.
- silvestrov 5y ago> used to [..] you could look at a piece of Swift code and roughly understand For all the critique of java, I think this is the one thing java got correct. It is (no matter how verbose or clunky) still easy to read and understand.
- Apocryphon 5y agoDitto for Objective-C, which by convention handles verbosity in a more elegant way than Java imo.
- skohan 5y agoObjective-C is a neat little language. Don't get me wrong - I would never go back to it, largely because of runtime errors due to duck-typing - but there were definitely things to like about it. The best part was the perfect C/C++ interop. When I was working on iOS apps in Objective C, I found myself writing a lot of pure functional code using C and it was pretty neat to be able to integrate that with the OO stuff from Obj C so easily and with a clear dividing line.
- ragnese 5y agoNot in the real world, though. And for similar reasons, too. Most real Java projects I end up working on/with are littered with annotations that do God-knows-what.
- azth 5y agoIt's trivial to look up the docs to see what they do. It's not unlike looking up what a function call does.
- ragnese 5y agoIn my experience, it's much more of a momentum killer and context switch to research an annotation than a function call. First of all, in most IDEs, it's very quick to jump to a function's actual definition to investigate such questions as "What if both of the arguments are < 0?" or "Is null an acceptable argument?". With annotations, you'll often go-to-definition and be staring at an almost empty class that hopefully has a docstring. This is because the annotations, themselves, don't actually do anything- you have to go find the code that actually checks for the annotation and does stuff. In my experience, the docs are often not good enough when I run into a problem. I was wrestling with some strange behavior with JacksonXML some time ago, and I had a very hard time figuring out what went wrong because Jackson has so many options and they don't actually all compose well, so it's not even about figuring out what one option/annotation does- it's about figuring out what happens when I set OptX=1 and OptY=4 at the same time. Unfortunately, the docs only tell me what is supposed to happen when OptX=1 and what's supposed to happen with OptY=4, but nobody has decided to document every single combination of every single setting in the library.
- ragnese 5y ago> A few years ago that seemed to start to change. From my perspective, some of the features added to the language to support SwiftUI - specifically property wrappers and function builders - very much felt rushed and forced into the language based on external deadlines. Yep. If anyone had doubts that the language was no longer the one Lattner designed, SwiftUI should've put the nail in that coffin. Swift is an imperative, statement-oriented, language. In fact, I get kind of frustrated when writing Swift after spending some time with Rust: I just love writing `let x = if foo { 1 } else { 2 }` or `let x = match foo { ... }`, and it's ugly as hell to try to assign a variable from a switch statement in Swift, etc. BUT, that's okay- I'm almost sure that zero programming languages were written with my opinion in mind, and Swift is Swift. But, SwiftUI is declarative, which just doesn't work with literally the entire rest of the language. So they added result builders and these weird, magical, annotations just so we can have a UI DSL. Error handling is now inconsistent and annoying, too. The original approach was to use this quasi-checked-exception syntax where you mark a function as `throws`, and all callers are forced to handle the possibility of failure. The difference between this and Java's checked exceptions is that the specific error type is not part of the signature and therefore the caller only knows that they might get an Error, but not what specific type of Error. They even have a mechanism for higher-order functions to indicate that they don't throw any of their own errors, but will re-throw errors thrown by function arguments. Clever. Okay, fine. Pros and cons to that approach, some like it, some don't, etc, whatever. Except then they realized that this approach falls flat in some scenarios (async/promises), so we really just need to go back to returning error values. So they stabilized a Result type. So, now we need to figure out when we're writing a function if we want to return a Result or make it throw. And, even more annoyingly, Result has a specifically-typed error variant! It's actually a Result<T, E>. Which is it, Swift team? Should immediate callers care about specific error types or not? Just recently, they landed the async and Actors stuff. Async is fine and great, and is consistent with the imperative syntax and semantics of the language, and it even supports `throws`, IIRC. But Actors? What the hell is that? That's totally out of left field for the rest of the language. I used to really enjoy Swift in the 2.x to 3.y days, but it really seems like it doesn't even know what it wants to be as a language anymore, which is a real shame- it had a real shot to take the wind out of Rust's sails, IMO (The number one "scary" part of Rust is lifetimes and borrow checker. Swift has CoW structs and auto-ref-counted classes, instead, which can be seen as more appropriate for higher level tasks than writing system libs, etc).
- yodsanklai 5y agoIsn't it the fate of all programming languages? they start on clean foundation, only to evolve in a bazaar of features.
- mccorrinall 5y agoExcuse Me Sir, Do You Have a Moment to Talk About O̶u̶r̶ ̶L̶o̶r̶d̶ ̶a̶n̶d̶ ̶S̶a̶v̶i̶o̶r̶ Lua?
- skohan 5y agoC seems ok no?
- eropple 5y agoYMMV, but to me, C is a great example of a language that absolutely could stand for a few more features. I would almost never write C++ (in the context of low level and performance-relevant code; I write a lot of things for a lot of stuff) if the type system was a touch more rigorous (why can't I specify, and have the compiler yell at me if I don't properly handle, "this pointer may never be null"? TypeScript can do this kind of type narrowing in its sleep!) and if error handling/lifecycle cleanup wasn't hazardous (I'm not even saying exceptions and try-catch, just make it easier to guarantee that a cleanup clause gets called when leaving scope, like Ruby's def-ensure-end). As it is, whenever I finally hit the breaking point with C++ (which I write mostly from inertia because I know it pretty well) it's probably Rust for me.
- tlb 5y agoLanguages not ruled by a BDFL are subject to every team member wanting to get their pet feature in, motivated by ego, fame, and career. This happens with all corporate software, as people compete to (for instance) foist their new videoconference system into your calendar flow. That's sort of tolerable for end-user software, but horrible for programming languages where feature-feature interactions grow as N^2.
- rob74 5y agoIn the special case of Swift, with it being the language of choice for iOS development, I imagine a lot of people at Apple also want to have a word to say about the direction of development. One notable remaining exception to this trend is Go. They are committed to the "simplicity" mantra and so far they have stuck to carefully weighing and discussing any feature added to the language. I know that some consider it too simple and the "glacial" pace of development not exciting enough, but I personally appreciate it...
- caycep 5y agoGo has Rob Pike as a sort of BDFL within google, no? Apple it seems does well w/ a Scott Forstal or a Bertrand Serlet running cover for their engineers. maybe not so much if there's a giant committtee....
- why_only_15 5y agoRob Pike is retiring, or perhaps already retired.
- rob74 5y agoThe idea and most of the initial development was by Pike, Ken Thompson and Robert Griesemer, and their explanation for the simplicity of the language was that no feature was included unless all three of them could agree it was necessary. Thompson has since retired, others have joined the "core team", and Pike doesn't seem to be that active anymore in terms of actual commits - however he may still have an active role in guiding the development, I'm not following the development that closely, so I can't tell. But the way I understand it, it's more of a team effort than a BDFL situation...
- nsonha 5y agoSwift seems to me very similar to Rust in the sense that it's a language that try to do everything, to be both low and high level. Rust is leaning on the lower end and Swift is higher end. The different is Rust has a selling point, which is the borrow checker. Swift's selling point is... made by Apple? In that sense Swift might be closer to C#.
- skohan 5y agoTo be fair, I think Swift does have a reasonable selling point in that it's an easy-to-write language with ADT's, named function parameters and excellent nullability handling. It really can be quite nice to work with. But I think it's over-sold as a systems/low-level language. Relying on ARC for all reference types creates a significant floor in terms of performance which makes it unsuitable for a lot of systems programming applications - unless you resort to unsafe Swift, in which case you're not really writing Swift.
- GeekyBear 5y agoLike Rust, Swift offers the performance of a compiled language with memory safety.
- nicoburns 5y agoCome and join us in the Rust community! It's a bit more fiddly than Swift, but it's incredibly well designed, still has that slow and steady mentality, and has a lot of the same nice quality of life features that Swift has.
- saagarjha 5y agoRust has some very nice things going for it, but it really lacks the kind of design polish that a Swift programmer is talking about. To put a crude analogy in it, it’s kind of like comparing macOS with Ubuntu.
- deleted 5y ago[deleted]
- jamil7 5y agoThe problem is there are very few jobs currently.
- hinkley 5y agoThere’s a concept from compiler optimization called Local Reasoning that I have stolen because I think the name applies at least as well to ergonomics/DevEx concerns. A good deal of bad code design comes down to not being able to predict what a bit of code is going to do without stopping everything, unrolling whatever built up state you had in your mind (from the thing you were actually trying to do) and sit and become one with the code for a time. But at least when you’re unsure what the code is doing you have a suspicion that is the case. The worse sin by far is misdirecting you into thinking it does one thing when it does something else, or even the opposite. We like to complain about extroverted business people interrupting us, but we seem to have very little guilt about doing it to each other by leaving these sorts of time bombs in our code.