Kotlin for JavaScript
kotlinlang.org
kotlinlang.org
Apparently they refuse to support the most popular web IDE because Kotlin for JS is really about selling IDEA licenses. Fair enough, but it means I don't suggest Kotlin for anything except as a Java alternative and Android.
There's better options from companies that are less adversarial to their community.
It seems pretty reasonable to me for them to not pay employee salaries to build a plugin for a competing product, especially when they already provide a comprehensive IDE solution available for free (in both senses). What other companies are doing that? I don't mean that as a challenge. I'd love to know what the better options are.
What you said would make sense, except they do build a plugin for Eclipse.
Better options would be any language where the stewards are not trying to extract money from you by forcing your IDE choice. Or where they view fostering community good will as being in their best interest. Ex. MS offers an official LS rather than saying "we don't support other IDEs because Visual Studio licenses."
There's lots of choices here for compile to JS languages: https://github.com/jashkenas/coffeescript/wiki/List-of-langu...
I don't know a single person who used Eclipse after 2020. Don't you think that supporting Eclipse might be a viable marketing strategy to get people who are stuck in the past on board with newer tech, as if anything, they will probably move on to IDEA?
> Ex. MS offers an official LS rather than saying "we don't support other IDEs because Visual Studio licenses."
MS is a bad example because they recently literally took away a feature from dotnet to push it into VS and drive sales, which was met a HUGE backlash from the community. Dotnet IS the driving force behind Visual Studio. JetBrains actually came in and took a piece of that from them(thankfully, because I personally hate vs/vscode). Like other answer to your comment said, JetBrains doesn't owe anything to anyone. If there is already a Language Server for Kotlin, great, I don't see how a product-based company could benefit from making something that drives people away from their (already free) product...
So your circle of acquaintances doesn't include anyone who used an IDE in the past year, and you extrapolate your personal anecdote how far?
> Don't you think that supporting Eclipse might be a viable marketing strategy to get people who are stuck in the past (...)
Can we spend a minute discussing how idiotic is this fad-drive development belief? I mean, why is anyone expected to be perceived as smart if they drop something that works in favour of an unproven tool just because it's new?
The same baseless assertion can be made regarding Eclipse, and it would be less doubtful given Eclipse's FLOSS nature.
Again, can we spend a minute discussing how idiotic is this fad-drive development belief? It's weird how, unlike in any engineering field, there's this cargo cult faith that new and untested is automatically better than old and reliable,and anyone who hasn't mindlessly jumped into a bandwagon is somehow the fool in the story.
What happened in 2020? Did I miss the end of the world?
In my bubble, Eclipse : IDEA is about 50:50, and luckily it doesn't matter because of Maven. I am one of those Eclipse users, and I am still waiting for someone to show me a feature that IDEA has and Eclipse doesn't. From my perspective it seems like the same thing, with different aesthetics (e.g. whether you can open multiple projects in the same window, or you need different windows) and keyboard shortcuts (which can be redefined on either side).
So I wouldn't try to convert people to Eclipse, but I also see no reason to convert to IDEA. I have a tool that works and does everything I need, and that makes me happy. Show me a functionality I am missing, and I may change my mind (some people already tried, and then it turned out that Eclipse had that, too); otherwise I am not interested in novelty for novelty's sake.
Uhm, I am not developing for Android. There, I imagine the situation may be quite different.
They need users to pay for IDEA to survive, so being open about not wanting to spend developer time to make it easier for people not to use IDEA that could be used to make IDEA better seems sensible from a business perspective. Seems like the community stepped up regardless.
I personally just use emacs.
Pylance is for sure, but it's built on the open source Pyright they provide, which is still pretty decent.
I think there's other things too but I don't recall the comprehensive list.
Honestly happens with python devs too when you open their project or code in a "real" IDE that checks for all these things.
I use both vscose and intellij, and I must say that even though vscode can sometimes feel snappier without any plugin running, it's missing a whole lot of features even with dedicated Microsoft plugins running, to the point it feels half-baked. I'm talking about things like basic refactoring support and even symbol recognition.
IDEs like intellij and Clion may have slightly longer startup times, but that doesn't really matter as you're only going to start the app a few times throughout the day.
Ultimately vscode is nice if all you want to do is open text files and Run regex searches, but the minute you want to run the most basic refactoring steps then it's faster and less frustrating to just start intellij, refactor, save files, and quit the app.
But Java/Kotlin is not native. Before electron, we hated Java apps because native apps are much faster
I develop in Pascal and Kotlin. When I had a laptop without SSD, Jetbrains IDE would take almost 30 minutes to start, while the Pascal native IDE could start in 30 seconds.
Instead of Microsoft's C/C++ extension use clangd.
Remote SSH and Remote Containers have alternatives as well but nothing as good.
Google and Red Hat's extensions work out of the box along with several thousand other extensions.
Didn’t know about this one, thanks.
> This would not only be beneficial to developers using this editor, but could drag a lot of developers to IDEA when seeking out for a full-blown IDE eventually.
In this context, the JetBrains employee was not saying "it won't sell licenses and therefore we won't do it", they were saying "this won't do what you think it will do".
JetBrains is a company, and like any other company their focus will tend to lean toward where the money is. But my experience with Kotlin over the last several years is that JetBrains is very responsive to the community and their needs.
> The next thing is also fairly straightforward: we expect Kotlin to drive the sales of IntelliJ IDEA
https://blog.jetbrains.com/kotlin/2011/08/why-jetbrains-need...
C# was created to be the systems language of .NET, although the CLR supports other languages from day one.
I don't understand what Borland's history has to do with JetBrains' decision to invest their resources on adding support for a programming language to a third-party text editor.
Sounds like a non-sequitur of an unwarranted cheap shot that adds nothing to the discussion besides noise.
Its effectivly the same thing, even though Microsofts goal wasn't selling visual studio, because they've got a much more lucrative cash cow: an operating system
.NET was going to use Java, when it was still codenamed as Ext-VOS.
It was the lawsuit against J++ that made C# a reality.
The motivation behind c# was keeping people in the Microsoft ecosystem. Wherever they attempted to use a rebranded jvm before that is entirely besides the point
A line that might become amusing when you read the whole account:
> Thus began a long line of sporadic interjections by Bill [Joy| where he was right. He usually is.
[1]: http://www.blinkenlights.com/classiccmp/javaorigin.html
It also looks like you're forgetting that Java has been for years (decades) owned by Oracle, which is renowned for taking very public legal fights to milk Java to the extreme.
https://en.wikipedia.org/wiki/Google_LLC_v._Oracle_America,_....
Java has been owned by Sun, and then Oracle, and it was more closed source during Sun's stewardship than Oracle's.
The first lawsuit was done by Sun against Microsoft, and they only missed the one against Google, because they were out of money by them.
Unfortunately Google got away with screwing up Sun, not happy with that, they keep using they flavoured Android Java when selling Kotlin's push into the ecosystem.
Still in all these years, Java was never used to sell Netbeans commercial licenses, regardless of how you to try to change the music.
But that's completely irrelevant, isn't it? Cherry-picking aside, don't you understand how loss leaders work, and how companies use that strategy to push the sale of their cash cows?
IMO this Microsoft stupidity to not open source .Net and FUD the open source alternatives costed them and the entire dev community a lot, we would have a good alternative for cross platform high level languages with a big framework (as alternative to JS+node+electron+npm+framewoks)
I personally was a big fan of C# and I can't forgive MS stupidity , because of the Windows Team a good language and platform was sabotaged, as I said it could have been a worthy competitor to JS/node especially in the past when JS was shit and even now where npm is filled with leftPads and colorRed packages.
I don't think we've heard the last word yet.
Btw, i did not implied anything about node or npm quality, someone that worked with both seriously in recent years might add their thoughts (so I am not a node fan just a C# lower disappointed on MS behavior).
What if I want to continue using Emacs?
There's literally no reason for not having full IDE experience in Emacs.
Kotlin the entire language is about selling IDEA licenses.
Ever tried to read Kotlin in plaintext? It's terrible. The language makes you need the IDEA hints they give you to read it.
If it wasn't for Google giving wind to their sails, the Kotlin ship wouldn't have gone anywhere.
In 2019, 41% of Kotlin devs claimed to work on web back-ends. In 2020 it was 47%. In 2021 the survey changed wording but "server-side development" had increased to 52% of Kotlin devs.
Nice play there with the Java version numbers, it is still Java.
I disagree. While the Google announcement to officially support Kotlin surely gave it a big boost, Kotlin was already in widespread use for Android development well before Google announced their support for it in May 2017. Additionally, it was also gaining traction for server side development since before the Google announcement. I had been evaluating Kotlin closely during this time, and made the decision to start using Kotlin in our (primarily Java and entirely server-side) company codebase in late 2016 because I was already convinced Kotlin had a bright future. We weren't the only ones who thought this, I was tracking multiple other companies in our space (financial tech) that were evaluating and/or already moving to it too.
https://talkingkotlin.com/the-first-kotlin-commit-in-android...
It certainly would. Like so many other JVM languages. Android is what makes kotlin stand out from that crowd.
Arguably "particularly well supported by IntelliJ" is another thing that makes kotlin stand out from the crowd, but that's a two-edged sword. I'd expect the average JVM person to see that as roughly a tie between a quality and a cost (more lock-in).
You can code Kotlin on any device, using any IDE, anywhere, at any time, thanks to the fact that Kotlin source code is stored in plain text files and not in a proprietary binary format. You do have a language server for that. The language server happens to be not developed by JetBrains, but it doesn’t actually restrict you from being able to use it in any way.
In my book, “lock-in” means “you have to pay a single vendor or you can’t use the tool”. You seem to be defining it as “you have pay the vendor or live with maybe slightly worse code completion and no refactorings, until someone else supports these features in a free tool”. I don’t believe your definition to be justified.
Groovy has no Netbeans support anymore. Who is to blame. Groovy? Groovy is better as a PL than Kotlin. But Kotlin is no match in terms of performance and pragmatism. I use both instead of Java and I never looked back.
However, the actual experience is full of sharp corners. Get ready for nonexistent documentation, hacky plugins, poor debugging support, lack of proper native libraries and head spinning errors.
In general, it feels like doing carpentry using your plumber’s tools.
[1]: https://marketplace.visualstudio.com/items?itemName=fwcd.kot...
I also love to see the quickly evolving Jetpack Compose which would enable to write natively executed UI code on most major platforms. (iOS is not there yet and likely depends on new memory model which is currently being developed.)
We use the Fritz2 ui framework which has been built from the ground up with Kotlin-js. It's a reactive framework desigbed around Kotlin features like co-routines and flows. It comes with a nice component framework, great documentation, and has been rock solid for us. Worth a look if you are looking for something different.
We took some risk by betting on this admittedly risky setup one and a half years ago when I had a few junior Android developers that knew Kotlin and we needed a webapp in a hurry. I ran this as an experiment for a few weeks and then realized that I had nothing to worry about: it's fine. We were hitting all our goals. By now we are super productive with this setup and we are adding lots of features, ui polish, etc. every week. Maybe we'll have to switch at some point but so far we're good on not ending up with the usual mess of technical debt that I've come to associate with javascript projects.
Jetpack Compose looks promising. Once IOS support lands, it will be a strong competitor to Flutter and React Native. If you can do without IOS support, it's usable right now. I'm guessing IOS support would be at least another one or two years out.
Multiplatform is great and getting more usable with every release. We have an API client and some other functionality that we use across JVM on our server and kotlin-js. It should just work for kotlin native, IOS, and android as well but we have not used that so far. I'm kind of looking forward to the web assembly compiler becoming usable as well.
I’d just use Clojurescript.
We use it in production and saves us quite some time sharing code with the backend.
I can imagine Kotlin JS takes some effort since it improved a lot but also changed quite a bit throughout the years. Kotlin Slack helped me a lot through this phase.
To be fair, I think he was fighting not just Kotlin JS but using React within it and his own lack of web technology experience being predominantly an Android dev.
Quite honestly though, I don’t see null as that big of a deal. I haven’t struggled with it since I began programming 10 years ago.
Getting started with node is a matter of downloading a single binary, writing one js file, and executing it with said binary.
Upgrading that to Typescript is a matter of downloading another binary, and running the two in sequence.
Conversely, Java feels like I have to develop a whole program just to get my program to run.
From there add a dependency by editing build.gradle.kts and you will be doing OK in no time.
1. Enable the Kotlin Plugin
2. Set the package metadata (group and version)
3. Add Maven Central as a repository (equivalent of say npmjs.com)
4. Add the Kotlin Stdlib as a dependency.
You may have accidentally enabled extra stuff through the new project wizard which is admittedly more complex than it should be (especially if you are using IDEA Ultimate with many plugins enabled).
I suggest the following flow:
New Project -> Select Gradle on the side panel -> Check the Kotlin Build Script box -> Select only Kotlin/JVM.
This should set you up with a very minimal project with exactly 3 files (build.gradle.kts, gradle.properties, settings.gradle.kts).
From here you can either create a package i.e go for the src/main/kotlin/com/example/main.kt route or just create main.kt in the top level without a package.
There are a few things that you would have to pay up for that might be worth the money depending on what you are doing. I think their C/C++ IDE (CLion) costs money for example and they have an alternative to XCode called AppCode that does not have a community edition. And they have a few other things that might be worth the cash.
But simple Kotlin development works great without that. Everything you need comes with the community edition. You do need a fast computer to run it. It's a resource hog.
2. Compile it to bytecode (.class file): `javac HelloWorld.java`.
3. Run it: `java HelloWorld.class`.
If you want to use other libraries, add `-cp` parameter ("cp" stands for "classpath").
If you want to package your code as a library, run `jar HelloWorld.class` (.jar is basically .zip renamed).
Also note that `java HelloWorld` looks for classes, so if you are in the same directory as the classfile, .class is not required.
I think we can conclude that if you have so prior knowledge, getting it working is much easier.
Is this about the "pom.xml" files? In the simplest case, they just contain the name and version of the program, the version of Java you want to use, and the names and versions of the libraries you want to use. You would need to specify this somewhere in any language. And yes, sometimes it gets more complicated, if people want to do more complicated things. It's either this, or having a dialog somewhere in IDE that does the same.
People often overcomplicate things, but it usually doesn't need to be so. As an example of a simple Java code, see this: https://gitlab.com/kittenlord/image
Granted if you are talking frontend browser code then sure webpack, but that tool has been around and stable for many years now.
Added bonus too is browser adoption is way better than ever so you don't really need a transpile either, typescript being the exception.
Nah, Gradle is a fucking mess no matter what. If you don't absolutely understand the gradle life cycle, how to avoid task configuration, keeping everything lazy, avoid cross configuration, understand that buildSrc is shit, gradle will be hell.
Gradle feels to me like trying to set up a webpack project. Loads of magic configuration no one dares to touch after it happens to somewhat work correctly.
The only problem I find is the API updates between major versions. Still, I’m never going back to Maven. Love Gradle.
Building embedded server apps, many sub projects, single Java/Kotlin codebase.
Once you apply that same strategy to Maven, it actually tends to beat Gradle in performance too. See Maven Daemon: https://github.com/apache/maven-mvnd
Mvnd seems somewhat recent compared to Gradle’s daemon feature. Are there any measurements that confirm this statement? I don’t find any in the repo?
But I do agree that the dsl is quite cryptic.
I'd take that build system over Java's dog slow build systems any day. Just a shame about the JS ecosystem itself. Too many badly written libraries not written in Typescript (inexcusable these days) with a gazillion dependencies.
Java literally compiles as fast as it gets, while npm chews through the same files multiple passes, and goddamn barely does anything yet takes eons of time.
Loving FP and admiring `fp-ts`'s work, I can't help but think our communities would be better off doing FP in FP languages instead of writing unergonomic and idiomatic code to much of the splintered TypeScript community. Yet, we'll writing things this way because it feels like the correct way to do software, meanwhile a bootcamper would find it incomprehensible; this same person would find an FP language more approachable because there's only one way to code it.
And then to upgrade to the latest I had to manually go figure out what the latest was, and manually change the line number to the latest version. I did see there's a separate plugin you can install to now add it though, built by a third party, but still.
Decades.
But this:
> And then to upgrade to the latest I had to manually go figure out what the latest was
Yeah, in the java world you write code against specific known dependency versions. That's why when you try to build it again in a couple months, it still works. I sure wish the JS community would learn this old trick.
I wish the Java community (which I'm actually also a part of) would stop rejecting everything that's not "the Java/enterprise way" and be humbled by exploring better alternatives, or alternatives with different tradeoffs for once.
It's also a common practice to use npm ci in all build scripts to never update packages even if they declared a version range in package.json, and package.lock not being able to satisfy package.json won't cause lock to get overwritten.
[0] Yes, that's right. npm doesn't allow to to install incrementally respecting the lockfile. You can install incrementally with npm i and roll the dice, or install from scratch with npm ci to respect the lockfile. Basically the npm authors took the rm -rf node_modules/ workaround and productized it.
If you run npm i against that package.json and package-lock.json, the latter will never be updated, even if the package.json would be happy with newer versions.
If you manually edit your package.json to have different ranges and run npm i and those ranges aren't compatible with your package-lock.json then the latter will be updated with version that are compatible with your package.json. Further runs of npm i will be as with 2 above.
But of course you may think this behavior is a joke, I do not.
How? Why? What's your use-case?
1) For local development, I’m seeking a command I can use after pulling, to safely and quickly install any needed dependencies that have been added by others. Currently I use npm ci but it’s absurdly overkill (and therefore very slow).
2) For CI itself. I cache node_modules/ across builds, which significantly speeds up my builds. Currently I npm i, and check if lockfile changed, and if it did, checkout lockfile and npm ci.
I shouldn’t need to npm ci ever unless my node_modules/ became corrupt for some reason. Because npm ci ALWAYS blows away node_modules/, it’s not a reasonable piece of everyday functionality, it’s just a semantically ambiguous way to rm -rf node_modules/ && npm i -—respect-lockfile (made up flag I wish existed). The obvious explanation is that the npm developers couldn’t figure out how to reliably reconcile node_modules/ with the lockfile, so just gave up and shipped npm ci.
Or if the rm -rf node_modules/ isn’t strictly necessary for npm ci, then give me npm ci —-skip-drop-node-modules, that would be equivalent and fine for my purposes.
btw ci is super fast (caching) unless you have one of those modules that download the whole effing chromium after install (brain dead behavior).
What do you mean ci is super fast? Is it intended to be caching the packages somewhere other than node_modules?
There's been some bugs in the implementation but never had anything in the last few years, other than some people accidentally committing unapplied package.json changes, and built a precommit hook and a server-side check for that in many projects.
> What do you mean ci is super fast? Is it intended to be caching the packages somewhere other than node_modules?
Yes: https://docs.npmjs.com/cli/v6/commands/npm-cache#configurati... . If you want a more Java-like (to be more accurate, artifactory-like) experience, you can also opt-in for Verdaccio: https://verdaccio.org/ You can also use the artifactory itself: https://www.jfrog.com/confluence/display/RTF/Npm+Registry
I had more success with verdaccio though.
Quality of the packages has been discussed to death, say about that anything you like, but npm has been rock-solid for me in the last few years. Definitely not a joke IMHO.
I've been writing JS with npm locked to specific, exact versions of dependencies since 2014, IIRC.
Not everyone does this, obviously, but the tooling has been able to at least do a decent approximation of this for a long time (and I was and am very far from being a bleeding-edge adopter).
Pray tell me where the dependency comes from then? When I add a ‘This package requires dependency x at version y’ to my gradle/maven file, it doesn’t magically appear on my system.
Or rather, I think it does magically appear on my system, which is incredibly confusing.
Should it display ads instead and put random executables to my path? Or create a 1000000 file directory everywhere on which windows god damn chokes to open?
If you enable the general maven repository (the maven() you see at the top of many gradle build scripts), you'll get the code from maven. If you also add your personal repositories (which most people probably don't have), you'll get packages from there as well. I'm not sure how you add a second repository to node package managers, but I assume it's possible in some way without specifying the http download url.
The biggest difference between the two ways of package management in my opinion is that node packages are just a word or two and Java packages are a full com.example.product.service.package name. That's a lot better in my opinion as it distinguishes between projects much more easily. I thought node-ipc was related to the nodejs project, for example. Some nodejs packages use namespaces, but most don't.
Another difference is that nodejs has tons of tiny packages (I'll never get over how silly it is that is-odd and is-even appeared in my node folder by transitive dependencies) whereas the Java world generally uses huge packages almost exclusively. This leads to more boilerplate code (actually having to write simple functions like that yourself), but also to less dependencies that can break.
Once you do that in Node, the package lock will specify what version you've downloaded, to make it a repeatable build. You can tweak it to indicate you want to pin the version at a given levels, as well; that's done in one place, and separately from the package-lock file that gets generated, that tells you what -actually- is being used.
My follow up point is that when that version eventually goes stale, it's as simple as 'npm outdated' to determine if there's something more recent, and 'npm update' to update everything (based on whether you've pinned to a major/minor in your dependency list). You can also update specific packages with 'npm update (package name)'. I sure wish the Java community would learn this obvious 'trick' that every OS package manager enables. I know I want Jackson, say, I should be able to say "gradle install jackson" or whatever, and it would tell me all the options in the repo with jackson in the name. Then 'gradle install jackson com.fasterxml.jackson.core' and it would add that to my gradle file, with the most recent stable version. And 'gradle update jackson' would seek to update that dependency to the latest stable (with some syntax to pin the release, major, and maybe the full version, to enable 'gradle update' to update everything within a particularly defined scope).
1.1) Gradle is a build system. As such it doesn't care where you are getting your dependencies. You can skip all public package repositories and only use your own private one or mix and match. Adding repositories is literally as easy as doing the following to your build.gradle file:
buildscript { repositories { google() mavenCentral() maven("your private repo url") }
1.2) As has been mentioned in previous comments, you add dependencies to the project rather than install them in the system. Gradle then has various cache folders where these dependencies recide and will fetch those that it doesn't find locally (new libraries, new versions etc). This is akin to how most software defines its dependencies. Python's pip & requirements.txt, Flutter's pupspec.yaml etc.
1.3) Complaining about having to use a full resource identifier ('com.google.guava:guava:31.1-jre') for the dependency rather than just an alias ('guava:31.1-jre') for the package name simply sounds like complaining for the sake of it. What if a fork exists of guava ('my.forks:guava:31.1-jre'), how would that get used along side the original if dependencies are only defined by their project name?
2.1) In my books, package updating should be methodical processes where each and every update is made in isolation, thoroughly tested and then merged in. In that respect I find it very nice that the build system isn't constantly telling me about a new library version everytime it runs, as it pushes naive developers to upping all libraries to their latest versions immediatly and then scratch their heads when unexpected behaviour starts popping up all over the place.
2.2) Various IDE's have mechanisms for notifying visually about when a package has a new version available to them. There are also various tools available to check for package version statuses, such as the 'Gradle Version Plugin' just to name one. I use this plugin extensively to get information on stable dependency updates.
2.3) If you want to always use the latest version of a dependency, you have various mechanisms available to you. It is easy to declare if you want to always go for the latest major, minor og patch versions automatically. See 'https://docs.gradle.org/current/userguide/single_versions.ht...' for details. I'd hate to work an a project that had not clear version definition though as that would just signal very naive developers and/or sloppy practices (automatically going for latest patch versions is fine in my books).
At its core, gradle as a task runner is pretty neat. But the layers of abstraction built upon it often make things superhard when you need to deviate from the setup offered by the starters.
While the official docs have started to show examples in both, almost always a stackoverflow answer or online blog post you find while googling is in the other dsl and converting between them is non-trivial.
Gradle certainly isn't great but it's crappiness is overblown especially when comparing it to stuff like npm + webpack.
Gradle however, is a dsl in a language almost no java devs use. All gradle files are different, so copying an example from somewhere else probably won't work in your context etc.
Gradle with Groovy sometimes gets kinda hard to comprehend
Gradle with Kotlin is entirely different experience, largely due to proper typing.
[1] https://kotlinlang.org/docs/maven.html#attributes-specific-t...
If you go the gradle route, of course use the Kotlin Script variety. Gradle is a bit complex and having your build logic written in Kotlin seems like it is the right thing to do.
Yes, in the abstract it does, but the but way Gradle actually does that (evaluating different parts of the program in different special and magical ways) is extremely confusing. And I don't understand how it could possible require the vast amounts of memory it does.
Maven is horrifically verbose, but at least its model makes sense after learning a few key concepts and the IDE can help you work with that model without setting fire to the CPU.
I have plenty of experience with maven and with ant before that. No project I've touched in the last six years used either of those other than a few conservative and, frankly, clueless/hopeless customers that I've helped out in some of my freelancing projects.
I don't get pedantic about persuading customers that maven is dead as a door nail but there is a pattern of behavior of mostly elderly (i.e. my age) slightly out of their depth CTOs insisting that maven is the way to do things because that's all they know.
I'm experienced enough to not fix what ain't broken. A build system either works or it doesn't. And it's not worth my hourly rate arguing against it. Anyway, it's not that hard to get them working regardless of what you use. I'm old enough to remember DOS batch files being an acceptable solution. Actually wasn't that hard to do either. I love bash shell scripts for the same reason.
People get hung up on build systems performing magic that they don't understand. Maven is mostly just a really convoluted way to compile Java code which isn't even all that hard when you understand what it does. Having done that with batch files I both appreciate what maven. gradle, etc. do and recognize that it doesn't matter much at all. Gradle does most of the same things as maven with less fuss. I'm still well capable doing the same with just bash and a compiler. But it's not worth my time. These days, I spend more time on figuring out github actions than on gradle. The stuff that gradle does is only a tiny part of the business of doing CI/CD these days. Gradle is the easy part.
The primary implementation is running on the JVM, but almost all code is also reusable in the web version.
It's all open source so anyone that is curious about how this looks like in an actual project is freelance to have a look here. https://kapdemo.dhsdevelopments.com
> Kotlin's design goals are now contradictory. It seeks to be a low-overhead language, i.e. provide abstractions that don't add overhead over the target platform, give access to all platform capabilities, and at the same time target multiple platforms -- Java, Android, LLVM and JS -- over none of which does Kotlin exert much influence (maybe a bit on Android).
I agree with pron. I don’t see the longevity of the language outside of Android. Too much of drive to use Kotlin focuses on developer experience hype, which is great for starting projects but pretty bad for maintaining them a decade later.
As long as it keeps doing that, even at the cost of a larger API surface area (or occasional backward incompatibility), I (and I suspect many others) will be quite happy to use it.
"Catch up" as in making sure that it's compatible with -- and ideally leverages -- those new platform features.
> Blocking kotlin code should benefit immediately.
I'd be remiss if I downplayed the value of that; however, Kotlin Coroutines won't benefit immediately, which is what many people who've invested in the Kotlin ecosystem use for structure concurrency. There's a uncertainty amongst the community whether Loom will complement coroutines or conflict/supersede it.
https://old.reddit.com/r/Kotlin/comments/il9u7o/how_will_kot...
https://discuss.kotlinlang.org/t/kotlin-coroutines-and-upcom...
https://discuss.kotlinlang.org/t/how-does-kotlin-plan-to-int...
Unfortunately, that's still in preview in Java 17. Also, Java's decision to only check switch expressions but not switch statements for exhaustiveness still makes their usage error prone.
In Kotlin, sum types (sealed classes) are properly supported today.
But meanwhile, I think there are enough people who don't mind the occasional backwards incompatibility if it means finding better ways to write code now.
I don't think these criticisms really hold water to be honest, though Ron may have a stronger take on this because he works on the Java team on Loom, and Loom is one of the few areas where big JVM upgrades can actually drastically simplify the programming model. Most of the other things Java has been doing are just catching up. The needs of stability and their general culture prevents them moving as fast as the Jetbrains guys did when designing Kotlin.
My criticism is within the context of pron's quote:
>> It seeks to be a low-overhead language, i.e. provide abstractions that don't add overhead over the target platform, give access to all platform capabilities, and at the same time target multiple platforms... over none of which does Kotlin exert much influence
By "catch up" I'm referring to the effort required to maintain interoperability and feature-parity with the target platforms. Although Java may be behind Kotlin's sheer number of features, when Java adds one of those features (like Sealed Classes or Records) it often comes with changes to the JVM itself. JetBrains has a choice to either update their feature to match or be compatible with the JVM implementation (e.g., adding the @JvmRecord annotation), or risk breaking their goal of interoperability.
What about when a platform adds net-new features, like Java is planning to do with Pattern Matching? Discussions relating to pattern matching in Kotlin have had little activity in recent years[0] and it isn't clear whether they're planning to implement it or not. Even if the plan is to wait until JVM pattern matching is stable, they'll still need to implement it for other platforms; and if they don't implement it, there will be a feature gap that may lure some devs back to Java.
For many years Kotlin didn't even use invokedynamic for lambdas. Did anyone care? No. The benefits of indy for lambdas turned out to be minor and sometimes theoretical, the benefits of better language level features were significant and immediate. The Java guys keep doing this: they add JVM changes for every new language feature even when it's of questionable value, which means lots of users just never adopt them because it'd wall out Android users or people who can't upgrade their whole JVM for backwards compatibility reasons. Meanwhile Kotlin has the same feature for years already, and if you want the JVM features for some reason then the compiler just starts using them eventually when support is widespread enough. In practice, it works. The "not a native platform" argument is well overblown.
Now like I said, there are rare exceptions. Coroutines is one. I stay away from them when possible. I'd rather wait for Loom and stay tied to one platform because coroutines are just very complicated and have a big effect on the user model. Nonetheless, I'm in a minority on that one. For people who want async/coroutines today, Kotlin has an offering and Java does not. Coroutines are widely adopted so clearly, in this space something is better than nothing.
My argument isn't that Kotlin is bad because it isn't a native platform, it's that because Kotlin isn't a native platform AND their goal is to provide a bunch of features that are fully interoperable with multiple platforms, the time required to accomplish that will eat into the development of Kotlin itself. Let's not forget that interoperability is something JetBrains proudly promotes -- if that breaks, isn't reliable, or important features from $PLATFORM aren't available with Kotlin, then fewer people will want to use it.
And to be perfectly clear: I love Kotlin and have been a proponent of it since at least 2018. I think we ought to be critical of the things we enjoy and not just give them a free pass.
> For people who want async/coroutines today, Kotlin has an offering and Java does not. Coroutines are widely adopted so clearly, in this space something is better than nothing.
Coroutines are exceptional -- especially compared to alternatives like Reactor or RxJava -- but development seems to have lost steam after 2020. Many things are still marked as `DeprecatedCoroutinesApi` or `ExperimentalCoroutineApi` with no obvious roadmap; Flows seem to have lots of open issues and unanswered questions for basic use cases.
(I am not criticizing them for taking a slow and precautions approach, just remarking that things noticeably slowed down while things like Kotlin Multiplatform ramped up.)
I don't perceive interop as being a particularly big drain on their time, in contrast. It has boiled down to a few annotations or compiler flags here and there. If anything the biggest overhead comes from the demand to use the new JVM features, even when it's not entirely clear why.
The sprawling, highly abstract and often experimental/opt-in nature of the coroutines API is one of the reasons I try to avoid it indeed. The tiny extension to the threading API Loom provides feels far more right, to me. I already understand threads. I don't want to have to grapple with the large set of new concepts and APIs coros have introduced to Kotlin. Value types are another area where they shouldn't have bothered, IMO, it's not something you can do properly independent of the runtime and Java's approach is superior there. But then there are also many counter-examples where Java's approach has massively slowed them down. How many years are Loom, Valhalla and Panama running now?
You see this in any platform, not only Java.
On Android there are some Google folks that pushed for it at the expense of updating Android Java to more modern versions, knowingly comparing Kotlin with their pseudo Java.
Actually I am quite surprised that Android 13 is actually going to support a Java 11 LTS (subset of course). Which although commendable that they are finally doing something, flies in the face of the latest version being Java 18, and they could at very least support the latest LTS version.
ART is effectively the KVM.
Spring, Quarkus, Javlin, Vert.x, etc. It's for a simple reason: Kotlin worked nicely with those frameworks before they even actively started supporting it and people used it for the same reason Android developers started using Kotlin. It's just way nicer to use than Java and there are no downsides to using Kotlin with a framework that is exclusively designed for Java. It just works. So several years ago, all those frameworks started adding Kotlin extension functions to their libraries and designing features specifically for Kotlin users.
Android developers got a little headstart on the transition to Kotlin for two reasons: 1) google had some issues with Oracle that caused the Android version of Java to be stuck on a version without lambda functions for quite some time 2) Android developers frequently end up doing greenfield projects and they'll grab whatever works when that happens. So, about seven years ago, Kotlin was a drop in replacement for Java on Android that had a lot of nice language features that Java simply did not have. Irresistable for Android developers stuck on the Java 5/6 feature set. Google upgraded the java language version used on the platform over time. But most of that happened after they endorsed Kotlin as the main language.
Something similar happened with Spring but just a lot slower. I used Kotlin with Spring 4.x already in 2018. It had absolutely zero kotlin support but it was a nice upgrade nonetheless. Just worked and added a lot of value (data classes, nullability, etc.). With Version 5.x they added a lot of Kotlin support and they've been iterating on that for the last four years.
Do you know if this is possible with Kotlin/JVM, or only Kotlin/JS?
We've been sharing models via Kotlin/JVM -> Open API Spec -> Open API Generator, which is far from perfect or painless, and I was looking at alternatives like https://github.com/ntrrgc/ts-generator.
Ridiculous take. Waste of a good language frankly.
Swift + Kotlin + Java + C + JS + Lisp + C++ should have you covered for most things
Mozilla has been replacing parts of Firefox C++ with Rust for a decade. They recently celebrated Rust hitting 25% of the LoC in the main repo. More broadly, serious code at large companies is written in Rust: A chunk of Google's Fuchsia OS, Dropbox's storage engine, Amazon's VM manager, etc. There are niches where C/C++ are better suited but in general Rust is good for whatever if the team wants to use it.
What niches?
The pace of Rust is increasing, and anyway for the things is not possible to change right now Rust interacting with C/C++ is less hairy than other langs FFI...
> Kotlin/JS provides the ability to transpile your Kotlin code, the Kotlin standard library, and any compatible dependencies to JavaScript.
What does it means "compatible dependencies"?
Also, what are the pros/cons over using typescript? I personally dislike typescript but used to love Kotlin when I was doing more Android development.
There were other things that made Kotlin seem more modern to me, but I'm foggy now on what they were. But, when I wrote Android, I would always choose Kotlin for new projects.
Obviously both are miles ahead of Java.
- The annotation support is just better. JS ecosystem has forever been debating on decorator spec, but kotlin annotations (esp. with addition of KSP) provide good mechanism for compile time code generation.
- Support for builder dsl is just better. The js ecosystem has embraced ugly & verbose embedded XML (JSX) thanks to fb, but in kotlin we can do something like:
html { body { div(id="hello") { span(text="whatever") } } }
This is just syntax sugar for lambdas passed as last arg to a function, but it makes code a lot more readable.
- Inline methods - we don't have to worry about being functional vs being performant in most common cases. The implementations of map/reduce etc. in stdlib are all inline methods and compile down to for loops.
- Implicit it (single argument in lambda) and implicit this (in class methods) are minor niceties but they reduce verbosity of everyday code quite a bit.
- Interfaces don't get erased - you can use reflection to get interface references, check if an object complies with an interface at runtime. In TS this requires ceremony and assistance from third party libraries like zod/fp-ts etc.
- Extensions are cool, you can add extension functions to classes you don't control to mold their API in specific contexts. In JS world we can monkey patch whatever and TS interface merging helps with that but its a pattern generally frowned upon and prone to conflicts (which extension functions are not).
- Companion objects are nice to have. Instead of static methods/properties, you have a singleton associated with a class which can comply with any interface, can have its own extensions, can be passed around etc.
- Kotlin doesn't have F#/OCaml style pipelines, but you can achieve similar chaining by combining let/apply/with/also extensions. Eg.
getName().let { it.contains("foo") }.also { println(it) }
- expected & actual are pretty handy for multiplatform development
What TS does better:
- Structural typing: its a better fit when modelling types for a highly dynamic language. Being able to define interfaces for data coming from sources you can't control without needing mappers etc. makes life simpler.
- Features like intersection type, index types etc. are useful and missing in Kotlin.
- Compilation times are much better.
- large collection of typedefs in the definitively typed repo.
My current role involves mostly working with TS and a day doesn't go by that I don't miss kotlin.
Most everything else seems to come down to "Typescript is meant to be runtime-only", which definitely has upsides and downsides (I agree that the lack of meaningful reflection support is annoying).
myStringList.filter { it.startsWith("a") }
...and on arrays: myStringArray.filter { it.startsWith("a") }
...and on, for example, a boolean array (a standard JVM primitive array object): myBooleanArray.filter { it != false }
This works for any kind of array and any kind of list, etc., even though the objects are ordinary JVM arrays and lists.In Java, because it lacks extension functions, the stream functions are often not accessible from the object itself, so you have to hunt for where they've decided to put them for this particular type.
In the first case, we do have a stream method on the list:
myStringList.stream().filter(s -> s.startsWith("a")).toList();
But in the case of arrays, we have to hunt down a static method in the Arrays class: Arrays.stream(myStringArray).filter(s -> s.startsWith("a")).toArray();
And in the last case, with a boolean array, that method doesn't work and the solution I've seen suggested is this wonderful mess (involving a different static method on a different class): IntStream.range(0, myBooleanArray.length).mapToObj(i -> myBooleanArray[i]).filter(b -> b != false).toArray();Not quite. Extension functions are statically resolved and abide by usual access modifiers.
So within a class, I can have a private extension method for another class (say C). Now if my class receives any instance of C, I can call these extension methods on this instance. But when I forward this instance to someone else, they wont have access to any of these extensions.
Libraries like exposed use this quite extensively.
> Most everything else seems to come down to "Typescript is meant to be runtime-only"
Yes, this one too because it would involve type directed emit.
I don't understand understand the js tooling setup completely (I mostly used kotlin on backend) but the gradle-webpack integration seems to have quite some overahead. Perhaps moving to esbuild can make things faster.
I don't have a very powerful system (4yr old linux machine with 8GB ram) so ymmv.
Could you explain this a bit more? I thought kotlin annotations were like Java annotations - additional metadata attached to classes/fields/methods/etc but could not be used by themselves to generate code like a decorator.
KSP [1] is a new addition to the kotlin ecosystem that facilitates cross-platform annotation processing. Various annotation processors can use this metadata to generate code - the generated classes etc. will be separate entities as opposed to direct modifications to targets.
Decorators are more powerful in that they can act upon their target directly but also (usually) have runtime overhead - this overhead is one of the reasons why the js proposal had to undergo substantial revisions.
The general feel of the language is that of one developed by people who deeply understand what a nice language should feel like. It has a lot of features and syntactic sugar that eliminate verbosity, make things more straight forward to use and so on. It really shows that this is a language designed from the ground up to be genuinely nice to use by people who really know what they are doing because their core business is selling developer tools to developers.
I like typescript. It is a big upgrade from Javascript and MS has a lot of the same mindset that Jetbrains brings to the table in terms of developer friendly-ness and language ergonomics. Kotlin has most of the features that make typescript nice but without the whole business of trying to keep it compatible with javascript. That adds a lot of complexity, ambiguity, and weirdness to typescript that Kotlin simply does not have or need.
Svelte apps aren't written in JS but in Svelte's own component syntax files. It's "HTML" but all the parts are extended (JS -> reactive, HTML -> directives, CSS -> scoping) and it needs its own compiler to transform the source to something everything else understands.
In a svelte file, a lot of usual js constructs like labels, additions, assignments etc. have different semantics making it more work for another language to support it.