I came across this tweet from Craig Hockenberry:
Again, discussion is the key point here. I’d like to see more backend folks talking about what they need from Swift.
Since I’ve been predominantly a backend developer for the last several years, and I’d really like to start writing web services in Swift, I figured I’d chime in.
This one is obvious, but still needs saying. It’s basically impossible to write a web service in Swift today because there are no frameworks to enable it. I’d argue that for a language to be a good fit for building web services, it needs at a minimum:
- A comprehensive standard library
- An efficient IO framework (for HTTP, memcache, redis, etc.)
- Database drivers
Swift 2.2 has none of these. Swift 3 should have the standard library part covered with Foundation and libdispatch being ported to Linux. However, the other items on the list will likely not be solved anytime soon.
There are several projects that are attempting to solve the IO problem, but this isn’t a simple problem. Take a look at Netty if you want to understand how hard it is to get this right.
I haven’t yet seen any significant efforts to solve the database problem - if you have, I’d love to hear about it (SQLite does not count).
Bottom line is, I think it’s still way too early, and we need to give it more time to see what shakes out.
There are a couple of language features that I can think of that would make writing web services in Swift a lot nicer.
The first, is built in support for concurrency and parallelism. This is absolutely critical for web services (much more so than for iOS/Mac apps). libdispatch is really nice, but we can do better. Something like C#’s async/await would significantly change (for the better) how concurrent code is written.
The second is annotations, combined with reflection. Java’s implementation is useful, but I believe C#’s version is better. I haven’t thought about this very much, but I think Swift could do even better with this concept. Annotations, combined with something like ServiceLoader, annotation processors, and reflection enable some really cool things. It might be possible to do this in Swift already, but if it is, I don’t know how.
There are definitely a lot of things that you can’t do in Swift today that languages like Python and Ruby allow (and frameworks like Flask, Django, and Rails use). I’m not going to get into the static vs dynamic debate, but I can tell you that it is entirely possible to have a great experience building large scale web services without most of those abilities. Even if you’re not willing to take my word for it, Twitter, Netflix, Google, Apple, LinkedIn, etc. have built superb web services on the JVM, in Java and Scala, which do not support a lot of dynamic features that Python and Ruby do.
Swift is currently lacking a proper build and dependency management system. No build system is without problems, but gradle is orders of magnitude better that what Swift offers now 1. Fortunately, it looks like SwiftPM is on the right track to deal with this, though.
There’s an important question here of why anyone would want to write a back end in Swift given the plethora of options available in other languages. The obvious answer is sharing code, and the argument for being able to switch between server and client development easily. I don’t really buy either of these answers (I’ll get into why another time).
I do however think Swift has one huge differentiator from all the other popular languages used to build web services: ARC. Just about every other language that is used to build web services is garbage collected. Garbage collection is one of the main reasons why these languages got so popular in the first place. However, it comes with a huge downside. If you run into a memory problem with a garbage collected language, you’re in deep trouble. It is extremely hard to figure out if you have a memory leak (you’re hanging on to references longer than you need to), a garbage problem (you’re creating and destroying too many objects), or a garbage collector problem (you’re using the wrong GC algorithm, or using suboptimal parameters for the GC algorithm). This isn’t to say that figuring out memory problems is easy with ARC, but it is easier. Swift, and Rust are in a unique place because they guarantee memory safety, without garbage collection. This is a huge win, in my opinion. Netty, for instance, goes to ridiculous lengths to work around JVM garbage collection.
Swift is already very close to being a great language to write server code in. It just needs a bit of time to mature, and for stable frameworks to get written. I’m optimistic about the future of Swift on the server, and can’t wait for that future to arrive.
This is a handy interview question. If you ask someone for a build system they think is great, and they give you an answer, you know they haven’t really used it 😀. ↩