What is the future of Swift in the server side? What are the advantages of Swift?

There are numerous reasons that are pretty convincing to me personally. As a consultant I also list similar reasons to my clients when we discuss languages to use for their code:

  • Swift can be as fast as C or C++ code, and also allows calling C code directly if needed. Compare this to Java, which requires JNI wrappers or Node.js/Python, which require binary wrappers for any interaction with C. Swift is also a much higher level language than C or C++ with safe memory access by default, while still allowing to go lower level to work with pointers when needed (including interactions with C libraries).
  • Compared to all of these widely used languages, Swift's type system is much more advanced and is more on par with Scala or Rust. At the same time Swift has a strong focus on the progressive disclosure principle: you don't have to learn the advanced features and you can still be quite productive on many levels without going too deep into generics and associated types etc.
  • Swift has efficient memory management without the overhead of garbage collection. Swift's memory management is predictable and deterministic. Compare this to Java/JVM and any other garbage-collected language in general, in which the runtime might initiate a garbage collection pause at the most inconvenient moment and freeze everything when you're serving a customer request.
  • If you already build iOS apps in Swift, you don't need to learn a different language or ecosystem. In my personal experience, full-stack development is a great time saver when it's available. Even when separate Swift developers are working on the mobile/desktop app and server code, you can share a lot of the code, usually related to the model layer.
  • Similarly, if your backend already utilizes TensorFlow or Python, you might be interested in Swift for TensorFlow or Swift's interop with Python for data engineering and data science tasks. While there might be less code sharing, there are a lot of benefits in using a strongly typed language for these tasks and catch many of the possible errors in compile time as compared to run time.

Swift is also available on other platforms such as Android, and Windows port is becoming more mature. I'm looking forward to using Swift for whatever I need to implement on any of the platforms. It has a very good balance in terms of the learning curve and performance of the generated code, the best balance of all widely available languages, in my opinion. While developer tools for some of the platforms can be improved, using Swift on other platforms is definitely worth checking out, especially the server-side as it had the most time to develop since the moment that Swift was open-sourced.

12 Likes

Has any company already put Swift into production on the server side? Like Google, Apple, Amazon or other companies? @Max_Desiatov

Yes, Apple is using Swift in production for services. I mentioned this a few months back when talking about Swift 5 on John Sundell's podcast (jump to 39 minutes):

7 Likes

From my understanding, Swift is used in some capacity on the server side by all of these companies, but it's obviously up to these companies to disclose the details. I'm glad that @tkremenek confirmed this for Apple, but I would be surprised if Google, Amazon or IBM don't use server side Swift in production, given the resources that were invested into their frameworks and tools. Just to name a few: Swift for TensorFlow, Swift-Jupyter, Smoke Framework, Kitura and other supporting libraries developed in Swift by them.

As for smaller companies, we could expect that major sponsors of Vapor are its most active users: Nodes and Skelpo. Given that those sponsors are consulting companies, we could expect their clients to be using server side Swift in production for quite some time. When I attended VaporLondon meetup I had a quick chat with a few people, who used Vapor in production. Again, I have no connection whatsoever with these companies, I'm only relaying my observations. I hope someone with firsthand knowledge could clarify the situation.

5 Likes

These various point of view are interesting, but the problem remains.
Why choose Swift for server side development and deployment and production?
Who already has significative production experience? how to have access to information
about deployment, performance, reliability, liability ?
How to get regular and liable information about it?

I want to push Swift/Vapor solution for a significative solution
Consisting of a set of API/Rest application server and reliable backend database
The risk is badly considered by people from tender side in front of a simple classic obfuscated but proven java/javascript or other! development effort, time, team..

I assume many people or emerging organisations have the same problem, how to join our effort and arguments, with credible references?

Other point is that we (my company) will not invest and go over simple test deployment like POC until we get some real and very positive references.

In the meantime, I have to consider that people who know don't tell!
or may be, advantages are not so clear...
Does Swift remains a hobby or a research area ? or not.

@Corbilo

What arguments to customers ?

You can try the following:

  • Cheaper to run. You can deploy a Swift microservice with only a few MBs of memory, which should lower your infrastructure bills. In my case, I have an app serving about 100 users with only 20-30MB of memory. And that's a full app that talks to an external service, fetches and parses large XML documents, renders HTML server-side, and so on... with zero optimisation work.
  • Increased developer productivity (and happiness). I come from a Java background and find Swift much easier (and a lot more fun) to use. Sure, it doesn't have the ecosystem that Java does, but there's also a lot less complexity involved and you can get a lot done in little time.
  • Increased reliability. Swift is a very safe language. I've had one crash on day one, due to an external service sending me garbage I wasn't prepared for, but other than that, I haven't had a single crash (on my end) in two years. For about 6000 lines of code, that's saying a lot about the language.

Who already has significative production experience?

Ask the Kitura and Vapor teams. They will share what they're allowed to share about their customers. You can also attend the https://www.serversideswift.info conference and talk to everyone in person. Last year, there were several companies present to talk about how they're using server-side Swift in production.

How to have access to information about deployment, performance, reliability, liability ? How to get regular and liable information about it?

The server-side Swift community is very open and very available to help you out where needed. I've received a lot of help just by asking a question on Slack or opening an issue on GitHub or JIRA. I don't imagine you can get this sort of one-on-one help in other ecosystems without spending $$$.

5 Likes

Amazon is using Swift on the server https://github.com/amzn/smoke-framework

1 Like

I see your point, but there're some errors in details.

  • Swift type system is not at same level with Rust. Swift cannot provide static uniqueness and data-race-free guarantee. For multi-threaded programs, Swift type system is way behind of Rust, and data race safety is nothing better than C/C++.

  • Swift requires using ref-types to manage resource lifetimes, and using ref-types involves big overhead in both of space and time. Ref-counting itself is a form of GC and not free. Therefore incomparable to C++/Rust's true zero-overhead automatic resource management. Swift code cannot be fast like C/C++/Rust without abandoning automatic resource management. Also as Swift ref-types are shared by default, tracking actual lifetime needs programmer effort.

It's true that Swift has some advantages, but for two above points, it's hard to claim them as Swift's advantages.

4 Likes

We are serving a few thousand users with our Swift backend (based on Vapor).

The major advantage for us as a team of 2 is code reusability, which in turn saves us a ton of time. We not only share models, but also resource descriptors so we only have to describe an endpoint once and in turn that can be imported and used anywhere (iOS app/tooling/other services). We have a micro-service architecture so inter-service communication is much easier when you can pick up a resource descriptor to make a request from one service to another.

We use AWS and MongoCloud for our infrastructure, and run everything using docker etc. you know, the standard these days.

It's not all sparkles and rainbows though, we have had a number of hard to track down issues when running on linux in the past which didn't exist on macOS. But these seem to be behind us for the most part.

2 Likes

I'll offer a different view than most people here.
We're running Swift on the server and I wish we didn't.

Now, as anyone here knows, Swift is a modern language and has a number of big advantages over something more traditional like e.g. Java or Ruby: operator overloading, null- and (reasonably) memory-safe, expressive type system (it has holes, but far fewer than many traditional languages), good support for functional constructs. The language has some warts, but which language doesn't?

But it also has some serious drawbacks:

  • The community is extremely small. You won't find libraries for a lot of things. If you find them, there's no guarantee they're supported on Linux; even if they are, they might not have a SPM manifesto, or it might not be up to date for Swift 5.
  • There are still serious unresolved compiler bugs for Swift on Linux (like compilation taking an excessive amount of memory) or things where Linux behaves differently than macOS
  • There is no good solution for fault recovery when your program crashes; this works fine for apps but for a server application it's less than ideal
  • The tooling situation is bad; XCode is almost the only IDE that has full support (there is CLion, it's better in some respects and worse in others), the testing framework is very underpowered and the LinuxMain situation is also an issue, SPM doesn't have an awful lot of features and some serious rough edges compared to more popular tools like bundler, gradle, etc., there are few static analysis tools for Swift (like code climate, or tools to check dependencies for vulnerabilities, etc.), etc. Also, updating Swift versions on a mac is horrible in the way it's almost completely tied to XCode (yes, you can use swiftenv, but it's not obvious how to integrate that well with IDEs). Also stuff like NewRelic etc. obviously has much better integration for more common languages.
  • relatedly, there is no common build tool; SPM is not enough for more complicated tasks, so you have to use some other tool, like Make, and those tools obviously don't know anything about Swift, so they're much harder to set up
  • there is not a good answer to modularity concerns for big apps. Splitting up code into modules is both too broad (I would like more fine-grained control about who gets to see what, and also things like qualified imports, imports with renaming - if you have two packages that export the same type - etc.) and it also can incur runtime overhead
  • also, on big projects, the compiler is slow

and so on. I think Swift on the server is just not there yet. Generally it works, yes, but there's just too many pieces missing.

8 Likes

@Chris_Bailey answered most of these questions today during the server-side Swift SOTU:

1 Like

go off,, this is probably the single most annoying thing about the language out of everything you said (and i agree with everything above). part of this is probably because swift doesn't have or aim to include a macro system, so any decently sized project is going to have .gyb files to do codegen, and since i'm regenerating these (large) swift sources every time in my build script, it means they all have to get recompiled every time.

Why not generate the files in /tmp and only overwrite if there's a difference? Sure, there's overhead in performing the diff, but probably much less so than recompiling. At least for now.

i found if i kept the generated .swift files around i would accidentally edit them instead of the original .swift.gyb files, so i just had the build script delete them all after the build ran.

that being said i just remembered all source file names in a swift project have to be unique, so maybe stashing them in a /generated directory might work...

We have some .stencil files instead of .gyb, but I don't think this is the huge bottleneck in our project. I think it's mostly type-checking.

I watched it, and it really doesn't adress "most of these questions" at all. The only ones it seems to address are:

Community/ecosystem:

  • number of packages is a really bad metric (for example, Javascript famously has a very small stdlib, compared to e.g. Java).
  • to say that "Swift has about the same number of packages as Node did at the same time" may be true, but the fact that node.js exploded in popularity doesn't say anything about what's going to happen to Swift, or specifically Swift on the server side (maybe a lot of SwiftPM packages will be created, but they'll mostly be SwiftUI extensions). This is not a valid extrapolation to make.
  • node.js having too many packages to do the same thing is a good problem to have. To introduce standardisation before there are even solutions is to me like putting the cart before the horse. In any case, the argument that "we have the SSWG now, so the ecosystem will thrive" doesn't convince me at all. A lot of successful software wasn't designed by a committee.

Tooling:

  • The LSP is probably a good thing, yes. And I admit that I haven't played around with VSCode and Swift yet (although I suspect that if it were really an amazing experience, somebody would have said so). So yes, let's hope that there's going to be progress in this area.
  • Citing SwiftStudio, which is an early access beta at this point (and also looks exactly like XCode), is a bit silly. For all we know, it might be vaporware. I mean, I wish the project the best of luck, but who knows where it's going to end up.
  • All the other relevant points about tooling weren't addressed at all.
1 Like

I'm pretty sure it is type-checking, and quite probably also the dependency resolution overhead. After working for a bit on implementing Swift type checker from scratch in Swift itself and studying related talks/articles, I'm not quite sure if some of the early stage language design decisions were worth it.

There seems to be a consensus that existence of function overloads can blow up type checking time exponentially. There can be specialized solutions for cases, where arguments and return values in chained calls of overloaded operators are all the same. Say, 1 + 2 + 3 + 4 + 5 + 7 + 8 really shouldn't blow up, despite + having a ton of overloads, just need some smart detection of these cases. But in real world, the use of function and operator overloads is much more tricky and the complexity is NP-hard. Overall, I think operator and function overloading is more of a cosmetic feature with too big impact on the speed of the type checker. I like how Haskell's and PureScript's type checkers feel much more responsive, despite these languages having more advanced and powerful type systems: they just don't allow overloads in the same way that Swift does.

The other thing I didn't expect is that multi-file modules with no explicit intra-module imports also have impact on the incremental compilation speed. Check out the docs on Swift's dependency analysis:

The golden rule of dependency analysis is to be conservative. Rebuilding a file when you don't have to is annoying. Not rebuilding a file when you do have to is tantamount to a debug-time miscompile!

and

A file's "provides" set may be different before and after it is compiled -- declarations can be both added and removed, and other files may depend on the declarations that were added and the declarations that were removed. This means the dependency graph has to be updated after each file during compilation. (This is also why reusing build products is hard.)

The dependency analysis step wouldn't be needed at all if only we had to specify intra-module imports explicitly in every file. I understand that the initial motivation was to avoid header files altogether, but again, it was probably a step too far. I really like how top of the Swift file only needs to list external module imports, but now I also know that we pay a price for it. A minor change in a single file in a module can trigger an unexpected cascading rebuild of the whole module, especially as the existing dependency resolver tries to be conservative.

Obviously, it's too late to change any of these fundamental features, but I really hope that dev tools can become more advanced to show the impact of existing function overloads on the compilation time. Same with the dependency resolution, maybe we need to pay more attention to this area and improve the resolution algorithm, or at least get some debug tools that warn about cascading rebuilds.

It's interesting that llbuild can already provide some build process debug information, but I don't think this feature is available in SwiftPM or Xcode. As I continue working on Swift dev tools in my spare time, I'd be happy to get more input and suggestions and what else could be improved in this area.

2 Likes

I wonder if we could move to this world by introducing the possibility of intra-module imports, and then tying them together with namespaces to use the carrot, rather than the stick (builds fail). I know namespaces have been discussed ad nauseam on the forum, but if they had to be imported from day one by importing the implementation file, that would encourage developers to help the compiler minimize their build times as a reward for using namespaces.

/pure_speculation

1 Like

Although we can't flat-out drop existing features anymore, we can certain evolve best practices, and introduce more robust features while deprecating and discouraging use of misfeatures over time. This isn't ideal, since getting from deprecation to actually dropping support takes a long time, and in the meantime the possibility of someone relying on features that negatively impact the usability of the language still lingers, but it can still steer the community forward. I for one would love to see a more Haskell- or Python-ish import model, along with the IDE support to automatically groom explicit import lists; @codafi had pitched this before on the old swift-evolution mailing list.

7 Likes

Just to mention that it's not the SSWG's mission to design software by committee. As per the SSWG charter everybody can pitch a library to the SSWG, existing, or new. Assuming it has been proposed, whether a piece of software is listed as 'SSWG approved' is determined by whether if fulfils the minimum requirements. The SSWG explicitly allows duplication and competition.

What the SSWG tries to achieve is to give you certain guarantees about liveliness (e.g. a project will get security fixes) and compatibility (it should work with the vast majority other Swift and for sure other SSWG packages) of a project.

The initial reason for the SSWG reboot was that we essentially had three larger ecosystems in the web frameworks (Vapor, Kitura, and Perfect) with very little sharing. The parties involved however all liked to have more sharing alongside to reduce duplication of efforts. But we also needed some reassurances that a certain packages has certain code quality, compatibility, and complies with other ecosystem standards.

9 Likes