Swift AWS Lambda Runtime
swift.org
swift.org
At the broadest level, I wonder what the footprint of Swift at runtime is, both in terms of CPU and RAM. I've been really enjoying Kotlin as a server-side language - it's a massive step up in productivity from TypeScript - but the overhead of the JVM certainly is notable, even in small personal projects (my small Javalin app uses four times the RAM at rest as my Express app did). Swift is really interesting to me because it is very similar in practice to Kotlin, but with some very cool and powerful additional language features. So, if server-side Swift has a smaller footprint at runtime and equal or better performance than Kotlin on the JVM[1], that'd be a really compelling language for me.
[1] yes, I know GraalVM/native options exist for Kotlin, but every time I've tried to investigate ecosystem compatibility, it leads to me glancing at pages long-articles about "how to configure X framework for GraalVM" that make it not seem worth the effort yet
* TypeScript's lack of runtime types and stable reflection APIs make it hard to have any guarantees of type soundness without either code generation (e.g. schemats) or complex type programming to convert a runtime representation of a type to a static type (e.g. io-ts). I find this very frustrating when doing web backend programming, where you are constantly doing i/o with external services (whether HTTP APIs, or input from client requests, or database interaction).
This is particularly maddening because there's no de facto standards (seriously, there are a lot of these libraries: https://github.com/moltar/typescript-runtime-type-benchmarks), so it's not easy to e.g. find a DB library that will let you define an io-ts schema that a query should match without re-wrapping things yourself.
Basically: if TypeScript had runtime types, and an `as` cast threw an exception when a value doesn't match the specified type, I'd be much more inclined to keep using it. I genuinely think that's table stakes for a type safe language.
(and lest you think this has to be how TS works given the nature of how it's compiled to vanilla JS, I suggest you take a peek at Sorbet, which knew this was necessary: https://sorbet.org/docs/runtime)
* The TS ecosystem is generally underwhelming. I don't think any HTTP framework for it is particularly good, nor any ORM/query builder. I think there are a lot of really neat experiments still happening in this space, and it seems like every day GitHub's little "explore repositories" sidebar shows me another cool library someone's built for TS trying to solve some of these problems, but it's all early stage stuff with a bus factor of 1 and a long todo list.
To be fair, _Kotlin's_ ecosystem actually has a lot of these problems; the semi-official Jetbrains-maintained Kotlin web framework and DB access library both have a ton of untriaged issues and seemingly little production use. The good news is, at least on the server, you can completely ignore the "Kotlin" ecosystem in favor of the Java ecosystem, and this is _shockingly_ effective. Just about every JVM framework I've seen has some kind of officially-maintained Kotlin adapter, presumedly because it's not hard to sell Java developers on "what if you could keep using the exact same tools with a nicer language." These adapters aren't even needed, mind you, they just provide nicer APIs that can use Kotlin language features. Javalin + JDBI is infinitely nicer out of the box than trying to turn Express and Knex into a production-ready API with anything approaching type safety.
* This isn't a make-or-break thing, but Kotlin is just generally _nicer_ than JS or TS in a lot of ways, while still having a very similar programming style. For example, the collection types are far more robust than something like Lodash (let alone the absolute joke that is the ES6 Map/Set API).
* Agreed with the problem, although I've found io-ts to be great. For incoming client requests: GraphQL is helpful if you're using that, but it's also relatively trivial to create an io-ts middleware for express that will get you similar guarantees. For database interaction, assuming you're talking about relational data stores, this is a challenge. Personally, I'm using Mikro ORM and it has been great so far. The one blessing here is that you're probably not dealing with unknown data types when talking to a data store, so it hasn't felt like as much of a concerning surface area for me personally. HTTP is valid, but I actually like io-ts as an approach here possibly more than using Jackson with static types due to its failure model - but again I acknowledge this is a personal choice.
* I guess it depends on your needs here, but base express can be great for simple apps, and NestJS is fantastic for more complex ones. You're 100% on point with ORMs, though, where I've been incredibly dissatisfied generally. As mentioned above, I've recently stumbled on Mikro ORM which takes a unit of work pattern similar to Hibernate, without the painful startup time. You can tell it's not perfect, and certainly not as feature rich as Hibernate, but also feels safe enough. I imagine if you tried to do everything through the ORM it could get painful, but most of my apps are structured as multiple modules where each module only controls the entities within that module. It keeps the reach of the ORM limited and abstracted behind "services" (in the modular monolith sense, not remote services).
* Yeah I see both ends of this one. Historically been a JVM user and have a ton of appreciation for it, but also like TS's approach more than Kotlin in several ways. You're right about collections though, ES6 is a joke there.
[0] - https://www.timc.dev/posts/future-of-server-side-swift
Fast.ai and the likes have been investigating Swift too, so there's some momentum/ desire to switch to Swift.
Even Java and .NET have better support for CUDA than Swift ever will.
Are you looking at used heap space or just the amount of memory used by the Java process? I have a few small Java services using vert.x and they hover around 7-15 MB of used heap space. For small services I usually just restrict the maximum heap space size because the default is unnecessarily large.
I truly love Swift, like god-damn is it my cup of tea, but I can't really bring myself to write it anymore. I've written over 10,000+ lines , shipped and maintained a few different production apps, but anymore I just have no urge to write it.
And the biggest reason why? I think it being open source is a joke until Apple, and I mean Apple themselves, implements some sort of cross-platform UI framework with it. Like, most of what is written in Swift is fucking UI code that's totally useless on other platforms.
I think it's pretty laughable I can run Swift on AWS but I can't do a simple GUI app on Linux or Windows using the OOB Swift SDK. Apple, you're a fucking trillion dollar organization, for fucks sake stop being so damn stingy with portability.
When I can write cross-platform GUI apps with Swift, maybe I'll give a fuck 'bout running it on a server. Just my two very bitter, hurt, and sad two cents...
I don’t think it’s going to happen.
Maybe WASM will lead to browser-side Swift and then you can do Electron-style cross platform apps using web technologies. (Not that I think Apple would put resources to that either.)
As a Swift programmer, I find this particular project to be useless. I can't imagine why I ever would want to do this. But: they make it clear that it was a community effort, and even singled out the non-Apple-employee who did the legwork to make it happen.
At the end of the announcement, they reiterated that the source code and process are both open, and provided links to the Swift forums and issue tracker, and called for more people to get involved.
I agree that Apple doesn't seem to be improving Swift in the ways I want it improved, but this is not a good example of that. This is the story of someone (not at Apple or Amazon) who saw something they wanted to do (use Apple's tools with Amazon's services), and made it happen. Good for Fabian! I'm not going to criticize Apple for offering some help and writing a blog post about it.
I also feel similarily strongly about the language itself, I find myself really productive in it. But for the kind of work I do I do need more portability that what it currently offers. I have my eye on Rust but it looks just a little too low level for what I want, general purpose-do everything language, focus on saftey, reasonable performance.
what i would LOVE however is a way to share business logic code and network code coded in swift between ios and android easily. I believe it should be straightforward using android ndk and clang, but for some reason i have never seen someone successfully implement it.
And of course, being able to call this same code from an electron app on windows would be a great thing..
App sends an event, Lambda sorts it into queue(s) for processing
App wants to know if its data is stale, asks Lambda
I think there is a niche for small, quick processing. Why write it in Node or whatever if your devs already know Swift?
Whether you think that's crazy or not, pure server Swift is a thing, personally I love it. https://vapor.codes
> "My goal for Swift has always been, and still is, total world domination," Chris Lattner, the creator of Swift, said onstage at Apple's Worldwide Developers Conference in 2017. https://www.businessinsider.com/developers-love-swift-apple-...
I'm having trouble finding the specific bit about "default language for computer science," might have been his interview on the ATP podcast. anyway
Had he stayed at Apple overseeing the language design I would agree.
So there doesn’t need to be a direct connection to iOS to decide to use Swift for serverless function. A developer might just decide to use Swift for serverless functions.
(I can see the benefit to sharing certain kinds of code between client and server, but a lot of things have to line of for this to make sense, so I’m not sure if that’s a significant driver.)
But really, I've been struggling learning swift... I became the iOS developer with little to no experience.
Currently develop a very popular iOS/macOS app in Swift which talks to an AWS Lambda backend written in Node.js. This has required some model code to have dual Swift and Node versions. If the Swift AWS Lambda Runtime was available previously this wouldn't be necessary.
I'd say a lot of developers in the Apple eco-system would be in a similar situation and this runtime can help to streamline a lot of client-server approaches.
- wakes up on for a request(few seconds delay on request),
- stays awake (requests are fast here),
- goes back to sleeping if idle for sometime (15mins?)
This is what keeps the costs low (or free). Same is true for Heroku, Lambda, Vercel, Azure Functions, etc.
Last time I checked I wasn’t renting a server, it was supposed to be a service that’s fast at any scale.
A 5$ DO instance would provide much better experience. They should give an option to keep it awake albeit at a cost.
But I would recommend using Cloud Run instead.
Cloudflare Workers are probably the best option in terms of cold starts and latency but are much more limited than other services.
This gives user low latency if the service is being used
If I've to launch DO server in 10 region, it will cost me $50 even if I am receiving a few request per day.
Will my soul brother, the great chrome dome Werner Vogels, be joining the flamboyant users of the most advanced hair care products ever invented on stage this year during WWDC to announce new support of Apple? macOS instances that can be spun up and down from Screen\ Sharing.app? Xcode compile farms that work seamlessly with a new iPad Pro edition of Xcode? Apple-subsidized (so free) access to all AWS for developers? (oh, I can dream)
If not, then there's nooo way I would use Swift outside of The "ecosystem" (first time I've read that expression used inside of Apple's own documentation, albeit on a GitHub project), though I might use SwiftNIO back ported to iOS to do something cool with Multipeer and ARKit.
I've only used JavaScript but I'm guessing a compiled binary (eg: Go) would have better cold starts, no?
Essential all major modern languages have collection sorting functions built into the base collection types that accept “by” (or similar) arguments... which is quite intuitive to even Jr. programmers.
func lambdaHandler(event: Event, context: Context) { // your lambda handler logic... }
What’s wrong with this approach, which is how lambda handlers are written in every other language with the exception of JavaScript - let’s not pretend that JavaScript is a good language design reference.
Look at this Go example In comparison... simple, readable, intuitive:
package main
import ( "fmt" "context" "github.com/aws/aws-lambda-go/lambda" )
type MyEvent struct { Name string `json:"name"` }
func HandleRequest(ctx context.Context, name MyEvent) (string, error) { return fmt.Sprintf("Hello %s!", name.Name ), nil }
func main() { lambda.Start(HandleRequest) }
Functions and closures-that-don't-reference-their-environment are exactly equivalent in both languages, from a quick look? It's your choice as a developer which to use.
This particular pattern in the case of Lambda is specifically for providing a closure which is called later and repeatedly - it's not waiting for a request and then calling the closure once and then returning.