Hacker News new | ask | show | jobs
by soulnothing 2131 days ago
I've been using Kotlin for a long time for backend/server dev personally and professionally. I've been feeling this more and more recently. I've said a couple times to my colleagues I've backed the wrong horse.

I had been making strong use of multi platform features. The end goal had been to easily move a piece over to a native image for server less if need be. Or output SDKs for Java script libraries. As an example I'm working on a multi platform micro-orm. But due to lack of cohesive reflection. I have to store the class package name in a map to reflect the type on all three platforms.

As to the note about inline types and Valhalla. Or loom for that matter. I have a feeling that will be buried as a compiler option. That needs to be amended in a build file. I have had to do this with JS, native, and a JVM

I'm finding that multi platform out side of mobile and JVM. Are not well polished. Additionally you're carrying a lot of baggage over from the JVM. In regards to it's type limitations and memory management. At the same time it's very impressive to easily target all three platforms. But it's a very difficult task.

Combine this with the few back-end places I've seen using Kotlin for the back end. Limit the features that can be used. To the end that the next Java version can primarily satisfy their needs. I've seen more effort coercing developers not to use sealed classes, null coalescing, co-routines etc. That could just be avoided by staying on Java.

I think it's a good language. It feels like a commonality of a number of the best practices. I've been able to migrate python, ruby, and typescript devs to a ktor setup and have them productive in a week or two. Gradle for all it's warts, I think is a pretty good build system. There is a rich eco-system of existing libraries. It has good performance, easy type semantics to grasp without getting in the user's ways. I feel like it's Typescript with a better build system (opinionated), and light pattern matching. The biggest API stability issue I've had is Gradle. I've carried projects from 0.11 to 1.4 with just nominal code base changes, but big build file changes.

The biggest focus is mobile, followed by Spring back-end. I have been very critical of Spring in my prior posts. There is a road map of Ktor, their in house web frame work coming soon. I'm curious to see where the language goes next. I'm finishing up one project in Kotlin but am eyeing Rust as a possible replacement

2 comments

I share many of your feelings toward Kotlin as a language. I've said a few times that Kotlin is the best JVM language, but that's it. Even if the Native and JS "ports" or whatever were well-polished, it's still exporting the limitations of Java with it. That's... not awesome.

But are there any other options for multiplatform besides JavaScript?

Also, for what it's worth, I love Rust. The lack of garbage collector is overkill for web backends, but I don't care. I spent years doing C++, so it doesn't bother me to think about some of those things. Even if it feels slower to develop in, it's a really great language IMO, and I love the feeling of "if it compiles, it probably works".

They tried addressing some of the limitations of the JVM with native and co-routines. Making multi thread objects mutable, to not allow for race conditions. From a recent conference they backed off because they couldn't express immutability as a good idea.

I started multi platform with F#, Xamarin, and Fable. That worked, but F# doesn't have a wide community. The few F# teams I had been on we spent more time discussing mathematical proofs than delivering business value. I'm also getting to this point now, where I'm trying to build a simple SPA. I'm spending more time wrangling the tooling than delivering features. So that leads too.

I don't think there are good multi platform languages, besides JS. But I think we have a set number of transport means. Websocket, HTTP, HTTP2 to client, with various protocol, and content types. Back end say TCP, Kafka, MQTT, STOMP, etc.

I've been pivoting my focus from mp to schemas. JSON schema, backs async api, open api, and a number of others (aws cloud formation, github, gitlab, etc). With that schema you can now know the transport mean, and the object to be communicated. Additionally with the possible error responses.

The disconnect though is how are those schemas produced, and verified. Having a web framework generate usually results in badly titled methods, or a lot of additional cruft. I usually go contract first. But there are very few frameworks that take in and validate a schema. This leads to a disconnect, I've seen, where the server just doesn't match the schema. I had written a pojo generator for spring, that consumed a schema via gradle and output the response classes, and strongly typed the url paths. But it was met with a ton of resistance, namely because it wasn't maven.

If your back end consumes a schema, and starts the server. Then you know it adheres to the schema. This also allows for asynchronous development. Once the schema is finalized. Mobile, web, and back-end can all work on the same feature. As there are a number of stub container services, that spin up a service container used for integration testing, and generating out client SDKs. The few times I've been able to execute like this, it worked great.

Rust is a really great language. Having come from ocaml, it feels like a natural extension. My hesitation is two fold. One I have been using Kotlin + Intellij for ten years or so. I'd have to relearn a lot of my workflow, and port a lot of helper libs I wrote. Two I can never see using it professionally. All the Rust interviews I attended were white boards of algorithm, and calculus questions. I'm not a math person so that's not really feasible. I do want to take it for a spin in the future. Actix looks darn impressive.

I like your take on Kotlin being Typescript with a better build system. I often show our Kotlin devs our Typescript apps and say, "see, it's very close... we just add semicolons". Many of them are former Java devs, so they're used to blindly believing, "JavaScript == bad". (yes, everyone can see what I did there) I like showing that it can actually be quite good in some ways. For high performance db crunching, I strongly prefer Kotlin. But for pure network services, REST request to sending files via SFTP, Typescript is really nice.
That said, there's still a lot to be desired in JS's ecosystem. The difference between JS libraries and Java libraries is huge.

The package manager (npm) also has a lot of room for improvements. I have a small SPA with like 15 files and a couple of dependencies, where updating one dependency has broken my environment and I had to reinstall another underlying dependency (typically a typings package). I just miss Maven.

To say that TS is like Kotlin is true superficially, but I must say I have faced many more "wtf" moments with TS because of weird glitches of the tooling, or packages, or something similar.

I really want to love TS and JS, but the more I develop in it, the less likely I am to reach for it in my next project.

This sort of echoes what I meant by in my opinion the build system is better on Kotlin, if not more complex. My opinion of course.

Using a library from a big tech vendor I found a number of issues with the definition files. That led to me tossing in ts ignore all over the place, and asking if I could file bug reports on company time. Lerna is the closest for a good multi module project. But that has a number of quirks.

As an aside I keep harping on multi module. But I find they really help with service boundaries, and flow of the application. Allowing dependencies to flow from bottom to top like a pyramid.

The other day I was working on a new proof of concept tool. I started with type script because that's what the team was using. But after cloning the demo from the vendor, it didn't minimize into proper java script. It seemed to be a known bug. I redid it in Kotlin in an hour. Because of the syntactic similarity, the team was able to pick it up. Worked on the first try. Now we just need to fix the TS build.

Incidentally these tooling issues are the bigger plague of the js multi platform. Dukat while great is only as good as the type definitions. There are also so many incongruities with the output. I've come to if I just output js I'm fine. But don't try consuming js. This also was the issue with rescript/reasonml to me.

I can output common websocket/http clients via ktor. Data classes, and other elements. But we have async api, open api, graphql, etc. The core of the multi platform driving business logic is being eaten by good automated tools. What's old is new.