In this article, we’re going to explore why young programming languages with modern features can’t be adopted quickly. Additionally, we’re going to take a look at one exceptional example that got specific parameters right to be both young, modern and mature, just ready for adoption at small and big scale.
DISCLAIMER: Some details are omitted intentionally. Keep your mind open when reading. If something seems naive, or not entirely true, bear in mind that the author thought into both the front and back sides of the coin, and the unseen third side of the coin, as well. You’re welcome in comments for a more in-depth discussion—it’s going to be worth your time for sure!
We all know that most of us, software developers, love to chase after shiny things just as much as we like to build them. This is not different for programming languages.
And, in this day and age, new young programming languages pop up like these mushrooms:
Why new modern languages can’t be adopted quickly?
A distinct feature of a young language is that creators and community gets the chance to experiment with different features and designs to potentially fix some problems of the existing mature languages. Mind you, any solution to any problem will bring minimum two more subtle issues. So this cycle of continuous improvement will never end.
While young languages can explore more advanced features and designs, they usually don’t have a robust ecosystem of libraries, frameworks, and tooling. Moreover, when the community develops these, people will still have to learn them, and that means that they (albeit temporarily) will be much less productive. And I’m not even going to talk about potential vulnerabilities, bugs, and so on.
Now, wouldn’t it be great if the new young modern language could rely on the existing mature ecosystem? Wouldn’t it be fantastic if using existing libraries, frameworks and tooling was entirely natural and not awkward at all?
If you ask me these questions, I’ll tell you that you’re perhaps describing Kotlin. Kotlin is a programming language where you can naturally use any library, framework or tool from the JVM ecosystem without any awkwardness.
Now, there were languages before, that could do that as well, like Scala, Groovy, Clojure, and so on. And they all got something wrong: natural use.
Why these languages don’t want to rely on the existing mature ecosystem?
Either it wasn’t natural to use the same framework or library, or it was even impossible to use the same tooling. And in the scenario where it would be possible to use same tooling, framework, and libraries naturally; somehow, the majority of the community went out there and built new tools, frameworks, and libraries (I’m looking at you, Scala, and sbt).
My hunch is that this happens because most of the early adopters of these new languages (“promised replacements for Java”) have somewhat an adversarial relationship with Java language and JVM ecosystem.
They hate it.
As early adopters, they set the playing field, because they are in the vast majority in the community during the first few years of the new young language. This way, they get to write all the brand new shiny tools, frameworks and libraries. And they are the ones who start new projects in these languages at actual companies and startups.
This way, the community style sets in: unique tooling, frameworks, and sets of libraries that people use. Sometimes, these are even designed on purpose to be radically different from their older alternatives from the JVM community.
This makes the learning curve very steep, and so the language gets adopted only by like-minded people, and poor developers who just have no choice but to maintain the codebases where this set of tools is being used already.
How to attract different early adopters that will be happy to leverage existing ecosystem?
Kotlin is radically different from this approach. The playing field rule number one: “100% bidirectional interoperability with Java and JVM ecosystem.”
Thus the community attracts fellows who are not looking to do everything in the entirely different approach; instead, they want a more modern language, AND they want to transfer their skills, knowledge, and experience from working with the mature ecosystem like JVM.
These early adopters don’t want to rewrite their existing codebases entirely because they are large, so being able to write only new code in Kotlin, and keep older code in Java helps a lot!
Small story of a fellow software engineer
I’m going to give you a tangible example:
Clara is a software engineer, working for a big organization, mostly working with Java, JVM, and Spring Boot. Clara’s professional level is senior and perhaps even beyond that:
- she applies best software practices,
- knows how to design simple software iteratively,
- can solve any complex problem you throw at her,
- knows her audience when writing the code (current and expected in the future level of her team members),
- excellent communicator and team player,
- teaches and mentors other developers,
- can take on the role of a team lead today,
- and lives the life of a life-long learner.
Her current development workflow includes building the application and automating development tasks with Gradle, and she gets her coding done within a modern IDE like IntelliJ. She doesn’t have any of the adversarial feelings towards any of these tools and technologies.
Quite the opposite: she loves them!
Sometimes though, she feels feature envy to all these cool modern programming languages where you could have one-liner data classes, less boilerplate in general, and the null-pointer exception is not a dreaded threat at every step.
And here is Kotlin programming language that recently became “production-ready.”
So she tries out to build a tiny web app (a tad more complicated than “Hello world”). And it seems like she can still use the same build tool—Gradle; and she still can use any of her favorite libraries, and much more critical, she can use the same web framework—Spring Boot.
And using all these things is not awkward at all, and feels just as natural, as in their “home” environment—Java.
Now, she has the next question: “This language is great but quite new… do I have to lose all the great features of my IDE now?” Because that is what happens to most modern languages—the IDE support is lagging way… way behind.
And now she gets pleasantly surprised: 95% of the IDE features that she needs are there and are supported:
- basic and advanced refactorings,
- jump to definition,
- find usages,
- running application and tests from IDE,
- running a single test in the current context,
- debugger,
- code completion, even cross-language,
- etc.
And this makes so much sense because the language is developed by the same company that develops the IDE (JetBrains). This certainly ensures that the tooling will be at least somewhat up to speed with the new modern language.
“This all sounds great!” Clara thinks, “Do I have to rewrite my application at work now fully to Kotlin?”
Most important playing field rules fostering the adoption
And she gets pleasantly surprised here as well. All she really needs to do is to add Kotlin Gradle plugin (few lines of change in a single file), and she can start adding Kotlin files to the source code base. All the old files, written in Java, are still working correctly.
Moreover, cross-language calls are working out of the box: she can call Java code from Kotlin, and Kotlin code from Java; AND it all feels just as natural. At almost no point, the calling code is even aware that it is calling one or the other because there is no difference.
That is what making “100% interoperability” a most significant playing field rule right from the beginning can do for the new modern language!
So if you’re going to design a new programming language, I suggest you consider imbuing it as one of the top priorities, as it will allow for much better adoption. And what creator of the library, tool, or language doesn’t want this kind of adoption superpower? ;)
As you could notice, Clara is not looking for an entirely radically different approach to coding, and instead, she is looking for a way to keep 75% of what is working well, and perhaps use a few more modern features of the language to improve the other 25% significantly.
This could be reducing the amount of the boilerplate by letting the language figure out the obvious so that you don’t have to specify it every time. This could also be a different decision to make everything an expression, which makes specific scenarios much more ergonomic and more comfortable to read, for example, try-catch block, where you need to set a variable in the “try” part and rethrow an enhanced error in the “catch” part.
These things and more are improving the readability significantly.
Additionally, the ability to have first-class immutable variables and nullable/non-nullable types eliminates whole classes of possible mistakes and errors. It is fantastic!
Stand on the shoulders of the giants!
Most of the modern languages are created to be used standalone, detached from the existing library and tooling ecosystem, either by design or “forced” by community guidelines or culture.
These modern languages might see some adoption, but they will eventually die out or stay in the small niche because the majority of professionals will just continue using the mature ones because they have better support for literally everything. There are rare, infrequent, exceptions from this rule.
If the new programming language wants to stay strong, it needs to stand on the shoulders of the giants.
So, instead of going against the former mature language, and doing everything differently, leverage as much as you can from the mature ecosystem, and add more value on top of that. This way, people, when learning this language don’t have to give up anything, and they only stand to gain— a real win-win situation!
Did that spike your curiosity about Kotlin?
I have written a 4-part (350-pages total) “Ultimate Tutorial: Getting Started With Kotlin” (+ more to come), and you can get it as a free bonus by becoming a member of my monthly newsletter.
On top of just Kotlin, it is full of goodies like TDD, Clean Code, Software Architecture, Business Impacts, 5 WHYs, Acceptance Criteria, Personas, and more.
—Sign up here and start learning how to build full-fledged Kotlin applications!
Thank you and ask for you!
Thank you so much for reading this article! I hope you enjoyed it. Please, tell me what you think about this in the comments!
Also, it would make me so much happier if you could share this post with your friends and colleagues who you think might benefit from it. Or you could share it on your favorite social media!
You are welcome to read my blog about Kotlin, and my blog about TDD and best software engineering practices.
And let’s connect on LinkedIn: I post short weekly updates about software developer’s productivity and happiness, teamwork, mental health, and a bit about Kotlin.
If you want to hear more of my opinions, follow me on Twitter.
Originally published on iwillteachyoukotlin.com blog.
cover image source: pexels
Top comments (20)
Kotlin is a great language, I hope it will be fully adopted by the Java developers within the next years.
Also, I think Typescript is another language that was developed in the same way as Kotlin: any JS code (from the old ES3 to the ESNext) is a valid TS code. Adding definitions to the previous libraries such as loadash and jQuery was extremely easy.
Indeed it is. That is my hope as well, actually, 😅 What do you think might stand in the way of this happening?
Also, TS has the problem that most JS libraries won’t work until adapted for TS, which is super unfortunate :(
Well, I don't know if some codebases would have problem with Kotlin, I'm talking about Java 5 or older code. In those cases, some refractory will be needed.
I've read something about it, it is necessary a gradual migration from JS code to TS code. It is not obligatory but it's needed if developers want to use types.
Of course, such old code will need to be upgraded to recent version of Java anyways.
I did recently a migration from JS to TS, and it is still quite painful. You have to hunt a lot of TS config options to make them just right so that JS + TS can work together and not get into any 'import' errors.
For me the iteroop with Java is one of the main selling points of Kotlin. The ability to use all the mature, tested and known ecosystem allows us to make the switch without much hesitation. Works with Kotlin? Good. It doesn't? Switch back to good old Java.
In your past experience what didn’t work well w/ Kotlin? What did it take to fix the problem if you tried?
Well, out-of-the-box I had some problems with JavaFX. It would throw the classic NullPointerException for no apparent reason, so I didn't bother with it and simply started using TornadoFX.
Besides that, I think I never encountered another compatibility problem.
Just as Kotlin is easy to adopt. I am a Dartisan(dart programming language) guy and Dart can be easily adopted too, and that's because Dart's intention was to be familiar for experienced developers. My first programming language was C++ and second was Java. I tried Kotlin in Android Studio because of the announcement Google made during the I/O 2017. I was naive enough to understand the APIs of the android and the syntax of Kotlin. I really wanted to learn Kotlin in Android Studio but I gave up due to the bloated IDE I've been using. My point of learning a programming language is to use for the right tool and not for just learning the syntax itself.
With Flutter today, I am now eager to learn Kotlin just to use Platform Channels to access Android APIs(bluetooth,nfc,battery,connection state, audio, etc.).
I still think Kotlin will become more popular because of the optional semi-colon that most beginners really wanted. Diving deep, and I'll be learning
coroutines
,data class
,non-nullable
and much more.People don't move to a language just because of the syntax (re: optional semi-colon)
They move there because it solves their problems better (or at least, that should be the motive if it's not for their own education)
Hi Oleksii, nice article! I don't have any experience of JVM languages (just a bit of super obsolete Java knowledge) but I still enjoyed your article. For the sake of argument and because I love languages can I ask you which other languages are you referring to in comparison to Kotlin?
I'm sure you didn't mention them explicitly to avoid fueling a potential flame but, hopefully it won't happen, I would like to have a reference to render your comparison with the "X language" more complete to me.
Regarding JVM interoperability... that seems absolutely wonderful. If I were a Java programmer I would have already "absorbed" Kotlin (as many Android developers I know have done).
A couple of weeks ago I read the following article here on dev.to
Q: How Much of "the Kotlin Way" Is the Right Way?
Preslav Rachev ・ Dec 28 '18 ・ 2 min read
The author's thesis is that Kotlin is interoperable indeed but there are still cases of people rewriting libraries instead of "interoperating", thus creating a sub community that's "incompatible" with the rest of the ecosystem. He writes:
(Though if I understood correctly those libraries would be usable from Java too, they are just "duplicated" efforts)
A discussion ensued in the comments and I asked why this happens. @jbristow gave me a nice explanation:
You had to pick one of the worst examples of Java, didn’t you?
URL.toStream sucks and is not intuitive to read 6 months down the line. (And let’s not forget having to add in your own retry policies, header and response code parsing, turning off ssl verification, etc.)
Apache HttpClient is old and feels old. It gets the job done, but at the cost of having to implement anonymous interface implementations whenever you’re trying to mess with settings.
The biggest kotlin http client repo I can find is fuel. This library is... alright. We’re running into trouble debugging problems with it because it tends to barf deep inside HttpClient, which makes me feel like I should have just bit the bullet and gone with using the Apache jar straight up.
Another source of fun problems is java reflection. Specifically bean reflection. This is most noticeable when attempting to use Jackson to serialize the following class:
outputs:
Yes, I know that’s not proper kotlin idiom, but it’s non-obvious to me that Jackson would just convert them all from Pascal to camelCase. (The reason is that it’s the bean spec! Use annotations and make your kotlin ugly again! Yes, one of the things driving me to Kotlin is the explosion of Annotatiomania and Lombok. Used sparingly, annotations are good. Using them to code-gen, do too much abstraction, or hack the language are bad.)
Yet another fun one: in Apache Tinkerpop’s gremlin library, there’s a class named
__
.If I’m writing a couple lines of interop, then yes, a nice facade will do. Just sweep the mess under the rug so I don’t need to see the FizzBuzzIteratorCheckFactoryBuilderContexts bleeding through every so often.
It’s just that used long enough, the facade takes on a life of its own. Debugging how the facade works and then having to context switch back to 1.6 era Java code when diving through undocumented code is even more taxing!
(And full disclosure, I really wish I had the time to just write all this crappy code in Haskell or Pony instead. Writing Kotlin is better than writing Java, but it’s not truly taking the shackles off)
What do you think?
In the end I do believe there's an advantage in targeting existing ecosystems when creating a new language (see Elixir) but it doesn't always work because not all languages have virtual machines with a bytecode. The other alternative is to write compilers targeting another high level language (see the many languages that compile to JavaScript) or a common binary specification like WebAssembly.
Thanks again for the article!
Great languages that I’m talking about are Scala, Clojure, and Groovy. They’ve had the same opportunity as Kotlin, and community or tech reasons steered in a different direction. Which is fine—people wanted to create a very different way to build and design applications.
I think that this phenomenon is not avoidable entirely. It seems that some examples of these libraries emerging are good, because they are attempting to fix real problems, and they are contributing back to the ecosystem.
Not just duplicating effort as "an act of rebellion…" or in pursuit of more complexity for the fun of it…
I much prefer when big libraries and frameworks add more and more Kotlin support natively so that you don’t have to build another library or wrapper. Think Spring-Boot and efforts made by Sebastien Deleuze and others.
And it is the power that we all hold. With the current state of things, most developers can go and create a PR for their favorite library and framework to add more Kotlin-friendly interfaces.
Oh, got it! I thought you were referring to other recent languages that don't target any previously existing ecosystem.
I am writing Kotlin/Android at my daily job. I switched from Java to Kotlin very recently.
First, it was the promise that Kotlin gives us. It solves many problems that a Java developer faces on a daily basis --- Null safety and verbosity being on the top. Next, the interop was another selling point.
I don't have to write a
class
for every single file that I have. Concurrency using Coroutines are easy to follow. List processors likemap
,reduce
,zip
etc are a part of the standard library. I know when something can be NULL. Extensions are fun stuff.Kotlin: What are your favorite extension functions that you authored?
Vishnu Haridas
I promote Kotlin among my colleagues that work on JVM. They must try this modern language for sure.
Did you have some success with your colleagues so far? Do they have reservations?
It is a success. People are getting more interested when they see the real code. Now two of my colleagues are full-time Kotlin, and four are currently learning Kotlin. We have decided that all our upcoming projects in Android will be 100% Kotlin. My colleagues want to switch mainly because they see how easy and efficient to write Kotlin than Java.
Using Kotlin from Java, you almost don't realize how big of a deal it is just how seamless the interop really is. I've been spending a while trying to get comfortable with Kotlin/JS, and it really puts things in perspective. Kotlin/JS works very well in isolation, but getting it to play nicely with existing libraries and tooling just isn't very clean or easy, and it really does feel like a young language in contrast to the maturity of Kotlin/JVM.
Definitely. I feel like, in JS world, a bit different patterns are usually used. When I write front-end code with Kotlin, I actually avoid using libraries at all, so that I can have nice architecture. And Kotlin stdlib gives me a lot already.
Great post. I recently converted a medium size Android Java project to Kotlin and had an almost identical experience as you describe. Do a bit at a time and go slowly at first, you will learn to love Kotlin!
Kotlin is a great language. Although it may be lacking in performance sometimes.
Of course there is a case by case scenario where it doesn't matter and some scenarios where it can be critical.
Thank you for a great article and a great example of usage by a backend developer.
So one can make an informative decision, can you please share the cons/challenges that the language is facing at the moment?
Thank you again for a great read!
A lot of iterations in a short amount of time 🤷🏽♂️