Having used Kotlin on and off for the better part of a decade, the one thing I can say is that their editor support is unrivaled by any other language today. While Kotlin's build tools leave much to be desired (looking at you, Gradle), their focus on building a "toolable" language was the right thing to lean into. You can add all the fancy type system features you want, but if the IDE does not understand them, convincing users is going to be a hard sell.
Whenever I try to get into another language today, the lack of language-aware editing tools are my main source of frustration - specifically, I expect navigation, refactoring and completion to work flawlessly. I know of no other programming language that puts as much effort into context- and structure-aware refactoring - if another language does one day replace Kotlin, it will need to offer a comparable editing experience.
I attribute this to the fact that Kotlin was developed by the same team that created IntelliJ, and fantastic IDE support was a requirement from day zero.
A big part of why Kotlin works is because IDE support is so fantastic now. And likewise, a lot of the reasons Java ties developers' hands is because there was no guarantee about the IDE they would be using.
As a trivial example, declaring variables. In Java, you have `final String foo = "bar";` while in Kotlin you can just say `val foo = "bar"`. They type is implied, but if you aren't sure, you can hover over `foo` and the IDE will tell you what the type is, so there's no longer a reason to type it out every time.
Also, you can now have multiple classes in a single file. When Java was created, the one-class-per-file rule made finding the source code to a file easy; just do a `find` for `Classname.java`. But with a modern IDE, you can just command-click an instance and be taken to the source code automatically.
Java's boilerplate is meant to make code discoverable, but the Kotlin IDE does that work for you, allowing developers to be more flexible.
This is funny because the other language I think of which wouldn’t be nearly as popular without an IDE, is Java. Especially older versions of Java.
Java is way too verbose to be workable if I have to write out all of the class declarations and anonymous classes and “equals/hashCode/toString” boilerplate and “ExtremelyLongClassName foo = bar.extremelyLongMethodName(…)”; and there are too many pitfalls like comparing with “==“ instead of “Object.equals” and implicit null. Except that I don’t have to write out anything or worry about any pitfalls (well, implicit null still hits me sometimes, but @NotNull and @Nullable make it much less common) in IntelliJ. IntelliJ has such powerful and seamless analysis, it does aggressive code folding on Java 7 so that you are looking at code with “var”s and lambdas. It also has built-in support for popular libraries like Spring and Lombok.
IntelliJ single-handedly turns Java from a verbose, legacy language into something I could actually recommend and start new projects on (although at that point I usually go with Kotlin). And Eclipse, NetBeans have very deep Java analysis as well. Java may have started off without expecting IDE support but now IDE support is responsible for a large part of its popularity.
> As a trivial example, declaring variables. In Java, you have final String foo = "bar"; while in Kotlin you can just say val foo = "bar". They type is implied, but if you aren't sure, you can hover over foo and the IDE will tell you what the type is, so there's no longer a reason to type it out every time.
This is something I've learned about Groovy that I really like. You can declare variables in multiple ways (terms are my own):
foo = 1 # normal assignment
var foo = 1 # declared assignment
int foo = 1 # typed assignment
A lot of our current code used the first "normal assignment" that you would see in shell scripts, Python, whatever. There's nothing interesting about this.
I started using the second kind consistently. The "declared assignment" says "I am creating a new variable foo and its value is 1". If you are not creating a new variable (i.e. if the variable exists already) your program fails. This is a great way to ensure you're not overriding variables from earlier in the program or from another scope. My experience tends to be that this throws errors "now" for mistakes you're currently making (at this point in the control flow) by overwriting a variable that existed before.
The last is a "typed assignment", where you're not just saying "I am creating a new variable", but specifically the type of variable is important. This errors if you ever try to misuse a variable down the road, and helps with ambiguity. It solves the "somestring = somestring.split()" issue of discounting a variable as the potential issue due to "it can't be this one, that's a string" being right for a while and then wrong for a while (or vice-versa).
Anyway, all that to say: not having to specify data types is nice in some circumstances, but I've been leaning into adding data types to my code just to make absolutely sure I know what everything is all the time. Not having to in Kotlin sounds nice, but I hope there's a way to be explicit about everything.
I think many of us have stale conceptions of Java formed decades ago. But some time ago, Java started evolving quickly and now isn’t that far off from Kotlin. When Kotlin started, that was not the case.
People still think of Java as stuffed full of wordiness, slow startup, garbage collection seizing up code, and long compile times, but that’s all in the past.
As a long time Visual Studio and C# .Net developer it’s always fun to hear people wax lyrical about these “amazing new” IDE features that have been pretty much standard in the toolchain for more than a decade…
So long as everyone on your team uses IntelliJ, then no problems. But not everyone uses IntelliJ, and now you've written code that is only easy to parse in a particular IDE...
For this reason, and being able to read my own code outside of just my IDE (say, in Github, etc), I've found it more necessary to be explicit with my typing in Kotlin for all but the most trivial snippets.
I would argue that C# and Visual Studio (and maybe Rider) has as good, if not better tooling integration compared to Kotlin, especially considering nuget and sln files solve the “build system leaves things to be desired” part of your comment.
This isn’t to say that Kotlin isn’t absolutely incredible, but I do not want to undersell the pleasure that C# is to work in with its tooling.
what do you have in mind about refactoring support with Typescript and VSCode? Maybe I'm missing something obvious but the only "refactoring" functionalities that VSCode provides me are "rename this variable", "rename this file" and "move this export to a new file" (can't move to an existing file, and can't even chose the name of the new file)
I've used both and Kotlin was a better overall experience for me. TypeScript has weird typing problems far more often due to the underlying runtime being dynamically typed.
Types in TS are Turing Complete [1], so any static analysis you build ontop of that language is bound to be unsound or undecidable. You could argue this rarely occurs in practice, but I would prefer a type system that is incomplete but sound and decidable. Incidentally, this issue also affects Java, which is both unsound [2] and undecidable [3]. Kotlin does have a fairly complicated subtyping relation [4], which has caused similar issues in languages like Scala [5], however whether the same issue affects languages based on mixed use-site and declaration-site variance like Kotlin is still an open question and requires further investigation.
Jetbrains and rust have brilliant refactoring. No idea how it compares to kotlin, but I can confidently move methods to other modules and files, rename anything, navigate to definition with no fear. Auto complete / auto import is also insanely good and is almost to the point where I’m auto completing almost every symbol because the IDE knows what I want precisely.
That's a JetBrains thing - they added loads of fantastic refactoring options to Visual Studio for C# which have now largely been integrated into the IDE directly. I've had an all-products subscription for close to a decade now and it's money well spent.
Kotlin has one of the poorer LSP implementations out of the popular JVM languages. Last I tried it was buggy, and slow. Developers are pushed into using JetBrains products directly or indirectly (Android Studios) I suspect leaving the wider ecosystem poorly supported.
I was evaluating Kotlin for a Spring Boot project a few years ago and would have loved to have programmed in it, but this was exactly why I stuck with Java.
Back when I was doing audits, the only languages that really had good IDE support for that were objective-C / swift using XCode. You could get a caller hierarchy and get some sort of recursive dropdown menu to go through the entire call stack, it was magical.
Last I was looking into Kotlin (couple years ago) they seemed hostile towards efforts to bring a similar level of support to editors outside the Idea family; basically they weren't going to do or support anything that threatened their "walled" garden of Kotlin + Idea. Is that still the case?
As a huge fan of Jetbrains products (I maintain a personal IDEA Ultimate subscription) this was still a huge turn off to me.
> I know of no other programming language that puts as much effort into context- and structure-aware refactoring
Do you mean JVM language? TypeScript, C#, and F# at least come to mind.
> Do you mean JVM language? TypeScript, C#, and F# at least come to mind.
As I mentioned in another comment [1] on this thread, soundness and decidability are non-negotiable for me. Types in C#, F# and TS are all Turing Complete [2], and therefor these languages are tooling-adverse in the sense that static analysis is fundamentally unreliable.
Have you used TypeScript? Not only is it better type system than Kotlin, it has great IDE support in VSCode, AND there’s a language server so you can get IDE support in Emacs/vim.
I'll bring up the Kotlin LSP[0] every time I see Kotlin on HN because I really hope the LSP takes off (which would make it viable to use Kotlin with a non-IntelliJ editor).
Kotlin as a language looks really cool, but I don't want to give up terminal-based, modal editing (which I'd have to in order to use IntelliJ).
Along those lines, I once tried diving into using Gradle outside IntelliJ, and I couldn't find any good resources to help with that. If folks have hints/links-to-blog-posts with regards to that as well, that'd be great!
Is that list of disadvantages really accurate? Reading them, I get the impression that the "popularity gap" between Kotlin and Java was a major reason FB was behind the industry on converting to Kotlin. (For context for non-Android engineers reading this, Kotlin has been the first party recommended language for 3 years now, and has been supported for 5 years) I can't imagine y'all were interviewing Android candidates in Java? And while certainly the Kotlin ecosystem as a whole is smaller than the Java ecosystem, the Java Android ecosystem is miniscule.
My recollection from my time in the building at IG was that build times and binary sizes were the two heaviest lifts, almost to the exclusion of anything else. Am I misremembering, or did the conversation change? Or does that list of tradeoffs reflect a realization by your team that you'd need to convert everything to Kotlin, not just the Android code?
I think this is a good depiction of our worries. Our biggest is and always was build times.
> I can't imagine y'all were interviewing Android candidates in Java?
We let people choose their preferred language for a while now. Also, while this blog is celebrating some milestones in the conversion, some smaller apps and new code was using Kotlin for a while now.
> My recollection from my time in the building at IG was that build times and binary sizes were the two heaviest lifts, almost to the exclusion of anything else. Am I misremembering, or did the conversation change? Or does that list of tradeoffs reflect a realization by your team that you'd need to convert everything to Kotlin, not just the Android code?
Binary size has generally not been an issue. Build times are an issue. We migrated and migrating some optimizations we have to alleviate that. We're also crossing fingers for more wins from the new Kotlin compiler JetBrains is working on.
1 & 2) Yes, almost all of the mobile code lives in one repo, and the 10M number quoted is all in one mercurial repo.
3) There's a lot of different things we do to work around such issues. Some things that come to mind right now:
- We have plugins for Android Studio to avoid loading all the code at once that help.
- We had forks for the Kotlin plugin for Android Studio to deal with some issues that were worse for our repo. (especially around module loading)
- We also worked with JetBrains by pushing some fixes and they fixed a lot of the issues over time.
- We do a lot of work as async jobs that run on the repo without you waiting for them, so you don't have to wait for such tools.
Have you released the source code for the following (primarily running AS in headless mode). It's something I've wanted to look into adding into our CI:
> As part of this step, we also apply our autocorrecting linters and apply various Android Studio suggestions in headless mode.
I'm not the right person to comment on the React Native part. (There's definitely quite a bunch of React Native in the app on top of the Kotlin)
Other people are also working on Obj-J/Swift, but from my superficial knowledge I think it's a much harder migration to do. I really think the Kotlin team did amazing language and tool design which makes Java to Kotlin migration easier than almost any other language migration I could think off. Kudos to them.
- The Facebook app is huge in terms of features. Just look at the menu with more things. I use very few of them, yet they're all pretty popular and justify themselves.
- Instagram is smaller than Facebook, but still has a lot in it.
- A lot of our code was optimized over time in many ways that add a lot of edge cases: internationalization, accessibility, optimizations for dealing with media, loading and data. It's can be easy to write something with much less code that looks pretty good at first sight, but all those extras really make the experience better and pay off for users.
- We build new features all the time, some code may be unreleased, some is in A/B testing and so you can have two or more pieces of code that do the same.
- A lot of test code.
- Not that much dead code. Trust me. I love deleting code! And I will happily spend time removing bloat. There's definitely a lot of dead code to remove, but it won't change those top line numbers by much.
(Also, it's 10M Kotlin lines of code, we have much more)
(I would love to know how many lines of code the other really big companies with big mobile apps have for comparison)
We're transitioning to Kotlin. And our main problem with it is slow compilation.
With only Java is was <2mins and we're touching 10mins now.
I'm not sure what exactly the problem is as we still have to investigate. Our use of Kotlinx.html (which we absolutely LOVE as HTML templating tech) seems to be a part of the problem, but we have not gone to the bottom of it yet.
Nothing against the language, everyone on the team loves it (when Java is what we consider normal). The extra type safety we get out-of-the-box or have put some effort into (using KFunction all over the place) is really paying off.
I wanted to post that ktfmt, the FB Kotlin formatter, is much less well-known than ktlint.
IMO, it produces the most (subjectively) readable code, and is the only one that doesn't leave room for you to inject personal style in certain places. (ktlint will let you get away with one of several ways of formatting code, so long as it falls within some guidelines, which can lead to inconsistent formatting).
These two formatters both suffer from the flaw that what intellij does when it autoformats is different from what either of those two do and can only be controlled through plugins. Especially when it comes to controlling imports this stuff is just broken in Intellij. The settings for this are not actually part of the code formatting settings.
Most sane code formatters & code standards: "don't use import wild cards!" Intellij's default since forever: "wildcards all over the place; please jump through hoops to get rid of them".
I've given up on having code formatters in my kotlin builds for this reason. Just not worth the hassle of trying to make both sides just do the same thing by default so I don't have to think about it. And then having to explain to every new team member how they have to customize their intellij setup so it isn't broken. I just gave up on it. These days I tell people, auto format your code, leave the settings alone. Try to only format the code you modified to avoid endless formatting related diffs.
The fix would be for Jetbrains to finally fix their IDE to have proper formatting that includes the behavior of organize imports and is perfectly in sync with whatever your build file says is the code style rather than whatever manual or built in stuff. Any IDE settings for this should IMHO just be removed as they are completely and utterly wrong in the presence of a build file that says how things should be formatted. Just default to whatever your build file says is the code standard with some sane default that just comes with the kotlin compiler. This should not be optional. You want to override it: do it in your build file.
Auto format on save in intellij. CI build verifies that nothing is mis-formatted because the IDE did it right because it does whatever the build file specifies needs doing without second guessing that. Have a githook to format before commit (optional). Zero manual fixing of anything ever related to formatting. It should not have a chance to go wrong and break the build unless somebody forgot to format or have a commit hook to do so. Just import the project and everything does the right thing. That would be the goal. IMHO it's not technically hard but it would require addressing what is likely to be quite a bit of technical debt related to this in intellij. And it's about time they did that.
Not sure what's preventing you from setting up Intellij to do what you want, even without .editorconfig. I setup intellij editor format preferences to follow the formatting I setup with my build-based linter/formatter. I just change the IDE settings so that they match my formatter, use it as the project setting, and then commit the codestyle files in .idea folder so that it's always there when I import or open a project. Never have to touch it again, autoformat in the IDE works and is 100% compatible with my ktfmt, ktlint, checkstyle, spotless or whatever. Imports, order, line wraps, indentation, etc... it 'just works' for me.
Yes, it's a minor additional step at first, but it's like 15 minutes tops, and after the first time you do it, you simply copy the xml from project to project if you want to use the same settings.
You wrote this entire comment but ktlint can generate a .editorconfig (and in fact used to generate a IntelliJ specific config file) which is a universal way of solving this exact problem.
Pretty sure the FB equivalent also has a matching .editorconfig
Also you could just setup a prepush hook so they run before your CI does which afaik both give you examples of.
When was that? IS that a big codebase? I fixed a memory leak issue a few months ago that would have a big effect when running over hundreds of files at once.
One thing that Kotlin got going for it is the tooling. I mean, the creator of Kotlin creates some of the best programming tools out there so I'd imagine (without actual experience of Kotlin) that it has great tooling.
Sometimes, the tooling is even more important than language features IMO. It makes developers move quicker, find bugs easier and so on. I like the idea of Kotlin, that it can compile to jvm bytecode, javascript and native.
So in essence, I can use the same language everywhere in the true meaning of the word.
> Sometimes, the tooling is even more important than language features IMO. It makes developers move quicker, find bugs easier and so on. I like the idea of Kotlin, that it can compile to jvm bytecode, javascript and native.
The only thing I'd worry about is Java overtaking it.
Do you remember Coffeescript? There was a point in time where it had impressive adoption, and quite a bit of buzz. But then Javascript added features, and all of a sudden the tooling burden associated with Coffeescript just didn't make sense any more.
With Oracle's 6 month release schedule, that's a distinct possibility. Especially since Java can no longer rest on its laurels as a language (if Oracle doesn't want it to become Cobol 2).
* Android is a massive platform, and Android is basically stuck on JDK8 (or JDK11 with desugaring, wooo).
* iOS compatibility-ish. KMM is not ideal and mostly generates ObjC compatible objects (so generics are mostly screwed for Swift and writing iOS code is not ideal, but even being able to define common and enforced contracts is cool. iOS benefiting from projects like SQLDelight is super cool)
* Jetbrains hedged their bets, and Kotlin/Multiplatform is a solid option. Coupled with Jetbrains Compose for UIs as well as having the entire Java ecosystem available is very solid. Compilation for so many platforms, directly to native executables is cool.
* Java is still very slow to evolve. Kotlin has had data classes for a long time, Java recently added records. Inline classes offer some nice type safety at basically zero costs. Coroutines and structured concurrency are a beautiful way to work, and Project Loom would only build the foundations of that. Context extensions (while terrifying in the potential for spaghetti code they offer) are a useful feature, reified generics have some great potential.
Now, Kotlin has its disadvantages too. Compilation times are not that great (hopefully K2 fixes this partly), but it's relatively safe and is kind of more than just a JVM language by now.)
Don't forget about WASM as another platform; it's coming as well. An experimental version actually ships with 1.7; it's just a bit unstable and under documented and very much a work in progress.
I think Oracle is catching up slower than Kotlin has been evolving in terms of new language features. Most of the stuff they add to Java (including most of the stuff they are talking about adding), Kotlin has been doing for quite some time. Kotlin is pushing out minor releases about every 3-4 months and major ones pretty much every year. Basically, they do 2-3 minor versions in between major ones. The pace is relentless.
If anything, Kotlin could use an LTS release because it's actually getting hard to keep up with the ecosystem.
A slower pace might be helpful with that. The main issue with frequent releases is that many libraries take weeks or even months to update and don't necessarily work well (or at all) with newer Kotlin versions. I've had repeated issues with e.g. code generation plugins requiring specific version of Kotlin breaking because some other library suddenly requiring something newer. So that then starts blocking a lot of library updates. We've actually put some effort in unblocking some of this for some of the dependencies we have by creating pull requests.
But I'm excited about the next 1-2 years. I expect Kotlin native to stabilize and grow beyond just being a thing for IOS. I also expect wasm support will become usable in that time frame. I hope to be able to use it with WASI for edge networking or serverless stuff. And maybe even some command line tools. IMHO Kotlin has potential for data engineering as well. There is actually jupyter support for Kotlin. And some machine learning frameworks. It's becoming a proper full stack language.
Yes that's right. In fact, Kotlin really works well with the IDE. But they didn't spend as much time in creating a language with a good and sound theoretical foundation. This works in the short time but shows its flaws later. Java is a bit better here (but quite slow though).
So yeah, I can see Java potentially overtaking Kotlin.
Do you know of any good backend web frameworks for Kotlin? I would wish for something like FastAPI for python. Kotlin may actually be a great fit for a service I want to build and I hadn't really thought of it as an option until now.
The biggest advantage of a statically typed language over a dynamic one is the tooling. Refactoring statically typed code, after working with JavaScript for a few years, feels like magic because the tools just make it work
I've found that migrating all your trunk code (data and infrastructure classes) to kotlin is the biggest win, and you can leave your old leafs (fragments and view models) in java if you want do a low risk migration. If a view isn't broken, you don't need to fix it, but getting nullability annotations in your data models and REST commands is a huge win for newer views and business logic going forward.
Whenever I try to get into another language today, the lack of language-aware editing tools are my main source of frustration - specifically, I expect navigation, refactoring and completion to work flawlessly. I know of no other programming language that puts as much effort into context- and structure-aware refactoring - if another language does one day replace Kotlin, it will need to offer a comparable editing experience.
A big part of why Kotlin works is because IDE support is so fantastic now. And likewise, a lot of the reasons Java ties developers' hands is because there was no guarantee about the IDE they would be using.
As a trivial example, declaring variables. In Java, you have `final String foo = "bar";` while in Kotlin you can just say `val foo = "bar"`. They type is implied, but if you aren't sure, you can hover over `foo` and the IDE will tell you what the type is, so there's no longer a reason to type it out every time.
Also, you can now have multiple classes in a single file. When Java was created, the one-class-per-file rule made finding the source code to a file easy; just do a `find` for `Classname.java`. But with a modern IDE, you can just command-click an instance and be taken to the source code automatically.
Java's boilerplate is meant to make code discoverable, but the Kotlin IDE does that work for you, allowing developers to be more flexible.
Java is way too verbose to be workable if I have to write out all of the class declarations and anonymous classes and “equals/hashCode/toString” boilerplate and “ExtremelyLongClassName foo = bar.extremelyLongMethodName(…)”; and there are too many pitfalls like comparing with “==“ instead of “Object.equals” and implicit null. Except that I don’t have to write out anything or worry about any pitfalls (well, implicit null still hits me sometimes, but @NotNull and @Nullable make it much less common) in IntelliJ. IntelliJ has such powerful and seamless analysis, it does aggressive code folding on Java 7 so that you are looking at code with “var”s and lambdas. It also has built-in support for popular libraries like Spring and Lombok.
IntelliJ single-handedly turns Java from a verbose, legacy language into something I could actually recommend and start new projects on (although at that point I usually go with Kotlin). And Eclipse, NetBeans have very deep Java analysis as well. Java may have started off without expecting IDE support but now IDE support is responsible for a large part of its popularity.
This is something I've learned about Groovy that I really like. You can declare variables in multiple ways (terms are my own):
foo = 1 # normal assignment
var foo = 1 # declared assignment
int foo = 1 # typed assignment
A lot of our current code used the first "normal assignment" that you would see in shell scripts, Python, whatever. There's nothing interesting about this.
I started using the second kind consistently. The "declared assignment" says "I am creating a new variable foo and its value is 1". If you are not creating a new variable (i.e. if the variable exists already) your program fails. This is a great way to ensure you're not overriding variables from earlier in the program or from another scope. My experience tends to be that this throws errors "now" for mistakes you're currently making (at this point in the control flow) by overwriting a variable that existed before.
The last is a "typed assignment", where you're not just saying "I am creating a new variable", but specifically the type of variable is important. This errors if you ever try to misuse a variable down the road, and helps with ambiguity. It solves the "somestring = somestring.split()" issue of discounting a variable as the potential issue due to "it can't be this one, that's a string" being right for a while and then wrong for a while (or vice-versa).
Anyway, all that to say: not having to specify data types is nice in some circumstances, but I've been leaning into adding data types to my code just to make absolutely sure I know what everything is all the time. Not having to in Kotlin sounds nice, but I hope there's a way to be explicit about everything.
var foo = "bar"; // you can add final if you feel like it
You could always have multiple classes in a Java file as long as there was only one public class.
People still think of Java as stuffed full of wordiness, slow startup, garbage collection seizing up code, and long compile times, but that’s all in the past.
So long as everyone on your team uses IntelliJ, then no problems. But not everyone uses IntelliJ, and now you've written code that is only easy to parse in a particular IDE...
For this reason, and being able to read my own code outside of just my IDE (say, in Github, etc), I've found it more necessary to be explicit with my typing in Kotlin for all but the most trivial snippets.
This isn’t to say that Kotlin isn’t absolutely incredible, but I do not want to undersell the pleasure that C# is to work in with its tooling.
Same, but this was the case for C# in Visual Studio 20 years ago.
> I know of no other programming language that puts as much effort into context- and structure-aware refactoring
TypeScript + VSCode do all this and more.
I similarly get irritated using anything else now.
[1]: https://github.com/microsoft/TypeScript/issues/14833
[2]: https://io.livecode.ch/learn/namin/unsound
[3]: https://arxiv.org/abs/1605.05274
[4]: https://kotlinlang.org/spec/type-system.html#subtyping
[5]: https://arxiv.org/abs/1908.05294
I can’t recommend jetbrains rust support enough.
https://youtrack.jetbrains.com/issue/KTIJ-12496/Provide-inte...
https://youtrack.jetbrains.com/issue/KTIJ-10606/Support-movi...
https://youtrack.jetbrains.com/issue/KTIJ-5063/Extract-prope...
As a huge fan of Jetbrains products (I maintain a personal IDEA Ultimate subscription) this was still a huge turn off to me.
> I know of no other programming language that puts as much effort into context- and structure-aware refactoring
Do you mean JVM language? TypeScript, C#, and F# at least come to mind.
[1]: https://news.ycombinator.com/item?id=33329509#33332183
[2]: https://3fx.ch/typing-is-hard.html
Kotlin as a language looks really cool, but I don't want to give up terminal-based, modal editing (which I'd have to in order to use IntelliJ).
Along those lines, I once tried diving into using Gradle outside IntelliJ, and I couldn't find any good resources to help with that. If folks have hints/links-to-blog-posts with regards to that as well, that'd be great!
[0] https://github.com/fwcd/kotlin-language-server#this-reposito...
I keep reading on HN and elsewhere that Scala's feature-full-ness encourages complex/unmaintainable code, but I gotta check out myself.
* A conversion in 1 commit: complicating/breaking the 'follow' behaviour of 'git blame'
* A conversion in 2 commits: the first 'rename' commit doesn't compile, complicating/breaking 'git bisect'
I hacked up a script which makes the 'rename' commit compile (when I was working with a ~100KLOC Kotlin conversion). This may be useful for others:
* https://github.com/ankidroid/Anki-Android/blob/937a6560913ec...
* https://github.com/ankidroid/Anki-Android/blob/937a6560913ec...
Is that list of disadvantages really accurate? Reading them, I get the impression that the "popularity gap" between Kotlin and Java was a major reason FB was behind the industry on converting to Kotlin. (For context for non-Android engineers reading this, Kotlin has been the first party recommended language for 3 years now, and has been supported for 5 years) I can't imagine y'all were interviewing Android candidates in Java? And while certainly the Kotlin ecosystem as a whole is smaller than the Java ecosystem, the Java Android ecosystem is miniscule.
My recollection from my time in the building at IG was that build times and binary sizes were the two heaviest lifts, almost to the exclusion of anything else. Am I misremembering, or did the conversation change? Or does that list of tradeoffs reflect a realization by your team that you'd need to convert everything to Kotlin, not just the Android code?
I think this is a good depiction of our worries. Our biggest is and always was build times.
> I can't imagine y'all were interviewing Android candidates in Java?
We let people choose their preferred language for a while now. Also, while this blog is celebrating some milestones in the conversion, some smaller apps and new code was using Kotlin for a while now.
> My recollection from my time in the building at IG was that build times and binary sizes were the two heaviest lifts, almost to the exclusion of anything else. Am I misremembering, or did the conversation change? Or does that list of tradeoffs reflect a realization by your team that you'd need to convert everything to Kotlin, not just the Android code?
Binary size has generally not been an issue. Build times are an issue. We migrated and migrating some optimizations we have to alleviate that. We're also crossing fingers for more wins from the new Kotlin compiler JetBrains is working on.
This post is the (pretty short) summary of a lot of work which took us a long time to do. So it’s nice to get any kind of validation.
Personally I read HN a lot and it’s my main source for interesting articles nowadays. So that makes me appreciate HN upvotes even more.
2) If not, how many LOC is the largest Kotlin repo?
3) How do you tackle challenges of large codebases like language servers/synthax highlighting crawling to a halt in IDEs?
3) There's a lot of different things we do to work around such issues. Some things that come to mind right now: - We have plugins for Android Studio to avoid loading all the code at once that help. - We had forks for the Kotlin plugin for Android Studio to deal with some issues that were worse for our repo. (especially around module loading) - We also worked with JetBrains by pushing some fixes and they fixed a lot of the issues over time. - We do a lot of work as async jobs that run on the repo without you waiting for them, so you don't have to wait for such tools.
> As part of this step, we also apply our autocorrecting linters and apply various Android Studio suggestions in headless mode.
I'll check again with the people who built it and see if it's doable to open source it.
Other people are also working on Obj-J/Swift, but from my superficial knowledge I think it's a much harder migration to do. I really think the Kotlin team did amazing language and tool design which makes Java to Kotlin migration easier than almost any other language migration I could think off. Kudos to them.
Deleted Comment
- There's a few apps here. Plus a bunch of tools.
- The Facebook app is huge in terms of features. Just look at the menu with more things. I use very few of them, yet they're all pretty popular and justify themselves.
- Instagram is smaller than Facebook, but still has a lot in it.
- A lot of our code was optimized over time in many ways that add a lot of edge cases: internationalization, accessibility, optimizations for dealing with media, loading and data. It's can be easy to write something with much less code that looks pretty good at first sight, but all those extras really make the experience better and pay off for users.
- We build new features all the time, some code may be unreleased, some is in A/B testing and so you can have two or more pieces of code that do the same.
- A lot of test code.
- Not that much dead code. Trust me. I love deleting code! And I will happily spend time removing bloat. There's definitely a lot of dead code to remove, but it won't change those top line numbers by much.
(Also, it's 10M Kotlin lines of code, we have much more)
(I would love to know how many lines of code the other really big companies with big mobile apps have for comparison)
Deleted Comment
Where did this come from?
Deleted Comment
With only Java is was <2mins and we're touching 10mins now.
I'm not sure what exactly the problem is as we still have to investigate. Our use of Kotlinx.html (which we absolutely LOVE as HTML templating tech) seems to be a part of the problem, but we have not gone to the bottom of it yet.
Nothing against the language, everyone on the team loves it (when Java is what we consider normal). The extra type safety we get out-of-the-box or have put some effort into (using KFunction all over the place) is really paying off.
IMO, it produces the most (subjectively) readable code, and is the only one that doesn't leave room for you to inject personal style in certain places. (ktlint will let you get away with one of several ways of formatting code, so long as it falls within some guidelines, which can lead to inconsistent formatting).
It's a superior formatting tool IMO.
https://github.com/facebook/ktfmt
Most sane code formatters & code standards: "don't use import wild cards!" Intellij's default since forever: "wildcards all over the place; please jump through hoops to get rid of them".
I've given up on having code formatters in my kotlin builds for this reason. Just not worth the hassle of trying to make both sides just do the same thing by default so I don't have to think about it. And then having to explain to every new team member how they have to customize their intellij setup so it isn't broken. I just gave up on it. These days I tell people, auto format your code, leave the settings alone. Try to only format the code you modified to avoid endless formatting related diffs.
The fix would be for Jetbrains to finally fix their IDE to have proper formatting that includes the behavior of organize imports and is perfectly in sync with whatever your build file says is the code style rather than whatever manual or built in stuff. Any IDE settings for this should IMHO just be removed as they are completely and utterly wrong in the presence of a build file that says how things should be formatted. Just default to whatever your build file says is the code standard with some sane default that just comes with the kotlin compiler. This should not be optional. You want to override it: do it in your build file.
Auto format on save in intellij. CI build verifies that nothing is mis-formatted because the IDE did it right because it does whatever the build file specifies needs doing without second guessing that. Have a githook to format before commit (optional). Zero manual fixing of anything ever related to formatting. It should not have a chance to go wrong and break the build unless somebody forgot to format or have a commit hook to do so. Just import the project and everything does the right thing. That would be the goal. IMHO it's not technically hard but it would require addressing what is likely to be quite a bit of technical debt related to this in intellij. And it's about time they did that.
Yes, it's a minor additional step at first, but it's like 15 minutes tops, and after the first time you do it, you simply copy the xml from project to project if you want to use the same settings.
Pretty sure the FB equivalent also has a matching .editorconfig
Also you could just setup a prepush hook so they run before your CI does which afaik both give you examples of.
Sometimes it'd hang for several minutes, memory usage would spike from time to time.
Didn't have time to bother debugging when ktlint just worked immediately.
Deleted Comment
Sometimes, the tooling is even more important than language features IMO. It makes developers move quicker, find bugs easier and so on. I like the idea of Kotlin, that it can compile to jvm bytecode, javascript and native.
So in essence, I can use the same language everywhere in the true meaning of the word.
The only thing I'd worry about is Java overtaking it.
Do you remember Coffeescript? There was a point in time where it had impressive adoption, and quite a bit of buzz. But then Javascript added features, and all of a sudden the tooling burden associated with Coffeescript just didn't make sense any more.
With Oracle's 6 month release schedule, that's a distinct possibility. Especially since Java can no longer rest on its laurels as a language (if Oracle doesn't want it to become Cobol 2).
* Android is a massive platform, and Android is basically stuck on JDK8 (or JDK11 with desugaring, wooo).
* iOS compatibility-ish. KMM is not ideal and mostly generates ObjC compatible objects (so generics are mostly screwed for Swift and writing iOS code is not ideal, but even being able to define common and enforced contracts is cool. iOS benefiting from projects like SQLDelight is super cool)
* Jetbrains hedged their bets, and Kotlin/Multiplatform is a solid option. Coupled with Jetbrains Compose for UIs as well as having the entire Java ecosystem available is very solid. Compilation for so many platforms, directly to native executables is cool.
* Java is still very slow to evolve. Kotlin has had data classes for a long time, Java recently added records. Inline classes offer some nice type safety at basically zero costs. Coroutines and structured concurrency are a beautiful way to work, and Project Loom would only build the foundations of that. Context extensions (while terrifying in the potential for spaghetti code they offer) are a useful feature, reified generics have some great potential.
Now, Kotlin has its disadvantages too. Compilation times are not that great (hopefully K2 fixes this partly), but it's relatively safe and is kind of more than just a JVM language by now.)
I think Oracle is catching up slower than Kotlin has been evolving in terms of new language features. Most of the stuff they add to Java (including most of the stuff they are talking about adding), Kotlin has been doing for quite some time. Kotlin is pushing out minor releases about every 3-4 months and major ones pretty much every year. Basically, they do 2-3 minor versions in between major ones. The pace is relentless.
If anything, Kotlin could use an LTS release because it's actually getting hard to keep up with the ecosystem.
A slower pace might be helpful with that. The main issue with frequent releases is that many libraries take weeks or even months to update and don't necessarily work well (or at all) with newer Kotlin versions. I've had repeated issues with e.g. code generation plugins requiring specific version of Kotlin breaking because some other library suddenly requiring something newer. So that then starts blocking a lot of library updates. We've actually put some effort in unblocking some of this for some of the dependencies we have by creating pull requests.
But I'm excited about the next 1-2 years. I expect Kotlin native to stabilize and grow beyond just being a thing for IOS. I also expect wasm support will become usable in that time frame. I hope to be able to use it with WASI for edge networking or serverless stuff. And maybe even some command line tools. IMHO Kotlin has potential for data engineering as well. There is actually jupyter support for Kotlin. And some machine learning frameworks. It's becoming a proper full stack language.
So yeah, I can see Java potentially overtaking Kotlin.
So in a sense, from a tooling and compiler perspective, they're orthogonal products, similar (I guess) to C# and F# on the .NET CLR VM.
Dead Comment
But I think the main strength of Kotlin is it being so damn developer-friendly compared to Java and Scala.
Both Scala and Kotlin can reuse Java tools, but with Scala it's awkward (and some tricky generics simply don't compile with Scala).
E.g. if I need to parse something, I search for "how to parse that in Java", not "... in Kotlin".
What? Do you have any example that wasn't fixed years ago?
Any non-trivial Scala app will consume dozens if not hundreds of Java libraries, without any issue.
That would be always. Tooling makes or breaks pretty much every language. Language itself is just a syntax that you write in.
Deleted Comment