I have microservices in production using both. Kotlin the language, I absolutely love. I'd put it in my top 5 languages. I don't hate Java but I've never really enjoyed writing it. Even with all the cool new features, it's always felt bloated to me. I can't see that ever going away.
With that said, I really hate how tight of a hold JetBrains has on Kotlin. While you may find an outlier here or there, (someone using Eclipse/NetBeans - heck, I've even used Visual Studio Code and Vim to hack on some stuff) 99% of the people writing Kotlin are using IntelliJ. Kotlin is built to sell IntelliJ. (And the lock-in is pretty apparent) I don't begrudge a company the right to do this. I don't like it, but I have a choice whether or not to use the language.
Lastly, Kotlin feels unencumbered. One can program in a functional style like Scala. One can program in an OO style like Java. It feels "free". The sugar that it adds to Java makes my day to day a pleasure.
So consider me a fan of the language itself. I highly recommend building things with it. Am I optimistic about its future? That's really hard to say. Google's behind it at the moment, but Google's attention span rivals that of a fruit fly.
I wouldn't mistake popularity with attention. Dart is actually super actively developed and I am still saying in the year 2021 that it is going to become a very big deal once Fuschia drops which could be as early as this week at I/O.
I agree. Using Kotlin with Spring Boot and Micronaut are no-brainers for me. The Kotlin support for both projects is fantastic. I do feel that if Google pulled the plug and started putting their emphasis on DartVM for Android projects (or something like that), we'd see a reduction in Kotlin adoption in other areas though.
There's no actual lockin, it's just that JetBrains put a lot of resources into the IntelliJ plugin and the quality of that plugin is a large part of Kotlin's value. You can easily write Kotlin in any other editor of course, but the experience won't be as good. JB have a team of over 70 people I think working on Kotlin as this point, and the IDE plugin shares the compiler infrastructure, so they improve together. If you were trying to write a competitive plugin it'd be a lot of work. Of course, if your editor was written in Java you could also re-use the compiler infrastructure in the same way they do.
Their planning is half internal/half external. There are public specs that get feedback for all language upgrades. How JB choose to prioritise is up to them, of course.
The problem if you want to write your own plugin is that the compiler interface is really brittle and not documented properly, so thats going to be a maintenance nightmare.
One needs to simply go to the support forums and ask about support for any other text editor. While there is an Eclipse plugin, it's a pretty horrible experience I understand.
I'm a Vim user for pretty much everything I do, there's no chance I'm getting a decent Kotlin experience. Java's not too bad these days. I'll admit, IntelliJ is awesome for both Java and Kotlin... I just don't want to pay for the privilege of writing enterprise Kotlin.
What I'm asking is: does something stand in the way of the community building a decent Kotlin experience for Eclipse or Vim (a language server perhaps)? Or is there just a lack of will?
The same could be said about Java or any other statically typed programming language in a text editor for that matter. Neither Vim nor Nano are intended as standalone IDEs, so it makes sense the UI is less complete. Despite their rudimentary features, many developers still prefer text editors for their low latency and wide availability across most shell environments.
This is no different in Kotlin. If you want richer features like completion, refactoring and static analysis, use an IDE.
Not a good comparison. Vim as an IDE has capabilities on par and in many places exceeding the capabilities of proprietary IDEs. This is not the case for Nano.
Both look pretty well maintained to me. Just like any other language (including Java), there are tools which are more or less active depending where users are concentrated. Most JVM developers I know prefer the IntelliJ Platform, so it's not surprising to me that's where most of the development effort is concentrated. Still, developers have their choice.
It's really good and just works as long as you're using maven/gradle. The only time I have to reach for IntelliJ is mixed code bases (scala/java) and when I want to run arbitrary code while debugging.
As soon as I opened the page, I searched for "null" and saw it didn't show up in the original post. Leaving that out is almost a bad faith argument, because it is the number 1 Kotlin feature I doubt Java will ever get.
Now, I will say that build times are way better on Java. A large part of this is the ability to generate ABI jars with Gradle, which you can't do with Kotlin. If anyone from Gradle or Jetbrains are reading this, please please please try and make this work, I know there's ongoing tickets but in larger projects Kotlin and Java are not even close, for this specific reason.
It's funny actually: my java code had mostly made peace with null. A combination of tireless performance of that if-dance where necessary, generous use of static methods for certain routine tasks on nullables and most importantly, @NonNull and null object singletons creeping into more and more code.
Now in kotlin it feels like it's just "drown it in question marks". I certainly end up with lots of nonnull signatures and far more reliable null handling than in java, but the ease almost feels wrong.
I am using more and more kotlin these days as an Android app dev
it starts that way, but over time you don't need the question marks as much because you're dealing with more and more code where the variables are guaranteed to not be null.
Where my code is mostly interacting with itself I see question marks almost as rarely as I saw Optional during my scala adventures (still can't believe a decade went by!), but the android API provokes it's share of nullability and the kotlin approach to deal with it is just so "why didn't we have that back in the MIDlet days!"
Some coworkers seem to type questionmarks faster than that IntelliJ "convert to kotlin" button and I hate it, but much less than I'd expect.
I really think Goetz/the Java language people are waiting to see if nullable types actually pay off in C#/Kotlin first, like with every feature, before considering it.
Java went the route of Optional<?> instead of nullable types. You still end up with some nullability issues working with old libraries (and even the std lib, like Map.get()) but by and large you can force a "never use null" policy on Java codebases and NPEs become very rare.
I fairly strongly prefer Optional over nullable types. Especially how it works seamlessly with streams.
It's actually kind of instructive to consider how Scala mostly solved the NPE issue by simply having Option available and discouraging use of null.
There are still issues at the API boundaries with Java or JS code, but that's about it. Outside of that, NPEs are usually in more niche places to do with initialization order and that sort of stuff.
Of course if you're inventing a totally new language you probably want to just avoid the possibility of null outright.
Some interesting points in there. My personal summary as someone who's done plenty of JS and Android work: Kotlin is to Java as CoffeeScript is to JavaScript.
I loved using CoffeeScript at the time because JavaScript felt like an incredibly stagnant language. CoffeeScript brought so many usability improvements. But that in turn inspired ES6 JavaScript and now no-one uses CoffeeScript.
I wouldn't be surprised if we see something similar with Kotlin. But it has an invested and motivated corporate backer that CoffeeScript never had who are branching out in new directions like Kotlin Native, so I wouldn't count it out yet. Native offers some interesting possible futures for cross-platform development (for instance you can deploy to both Android and iOS, WASM soon I believe?). That alone might justify keeping it around.
I agree CoffeeScript usage has gone down dramatically, but has Typescript not usurped it? It doesn't seem like everyone just went back to using JS, so maybe Scala was CoffeeScript, and Kotlin is closer to Typescript?
TypeScript is in a unique position. It's basically a set of extensions to JavaScript, and with a very short list of exceptions, those extensions only affect the type system. You can mostly just convert TypeScript to JavaScript by going through your source files, selecting various ranges of text, and pressing "delete" on your keyboard. This is more or less how the TypeScript compiler compiles your code anyway.
The exception I can think of is enum types. These always result in some amount of generated code.
TypeScript can also apply some other transformations to your code during compilation, but as far as I know that's just so you can use newer JavaScript language features and target older JavaScript runtimes.
I don't want to stretch metaphors too far here but there's some truth in what you're saying. TypeScript usage is a tiny minority of JavaScript usage but it's climbing and I'm sure it's much higher than CoffeeScript ever was.
But I see TypeScript as a different beast altogether because of its aims. CoffeeScript and Kotlin were both created to make a complicated messy language more straightforward and powerful. TypeScript aims to make JavaScript safer by introducing types. If anything it slows development down, not makes it faster (and before someone jumps on me for saying that: yes, I think it's worth the price). IMO that makes comparisons difficult.
> TypeScript usage is a tiny minority of JavaScript usage
shudders at the thought
After using TypeScript for almost 5 years now, I can not imagine a scenario where I would write JavaScript without type safety - other than a 5 minute POC to test something out.
I look forward to the day when TypeScript can be compiled to wasm binaries and it can be a language all on it's own rather than a superset/wrapper of JavaScript.
I like TypeScript but I think there's a complexity threshold — if you have a massive collection of other people's code, types are essential. If you're building a basic web app which is using the built-in behaviour and have a reasonably modern editor + linter + test setup, type safety is still good but it buys you less than it does when your baseline complexity level is higher.
Since modern browsers and JavaScript give you a lot of functionality out of the box which people used to use libraries for, there are quite a few projects which are under that threshold.
For smaller projects, I find that the value is less the type safety (still valuable) and more the much stronger control of intellisense. Yeah, if you have a language server that's able to deal with typings your JS code will still be a lot better than without it, but starting with TypeScript just makes that way more fluid. I find that I write TypeScript much more quickly, and more correctly, than I do JavaScript, both for small and large projects.
I agree that TS is a good pragmatic choice for any non trivial amount of code but I am still surprised how bad it is.
Error messages in TypeScript are quite cryptic for a modern language. Compiling it is super slow. Type safety, well they are doing their best considering the very dynamic nature of JavaScript but now if we compare it to other languages that compile to JS like Elm, it is just not that huge of a step.
With Elm you get a guarantee of no runtime exceptions at all in productions plus the most helpful compiler ever written. Even compilation time feels much faster. Similiar for competitors like ReScript, Purescript and the like.
Of course TypeScript is the easiest to learn for established JS Developers. And I am quite grateful that the option exists but I just wish it would be better considering how much money is put into it.
That's fair, though I will say Kotlin's type system having nullability built-in is something I doubt Java will ever fully add (instead of the annotations it currently uses). So in that respect, it's making it more type safe, but the delta between Kt and Java isn't near as big as TS and JS.
> If anything it slows development down, not makes it faster
It doesn't really "slow development down", it just forces you to explicitly specify the data structures that exist whether you decide to acknowledge them or not. Eschewing types is just a form of technical debt that every developer has to repay as they deduce the application data structures through trial and error, often times in production.
That strong following might not last. My company made the decision to have PySpark be the default for training and future greenfield Spark projects, and they're only really making official what's been the reality for the past few years. A shame, as Scala seems like a nice language but I've never really gotten into it as Python is always the preferred option.
It's true that PySpark probably is overtaking (or already has overtaken) Spark with Scala. I still personally like Scala over Java in general for non-Spark projects as it's much less verbose which is my main problem with Java. However, I also haven't used all the new Java features to see how that would adjust the comparison for me.
I originally used MoonScript because Lua was an incredibly sparse language. Originally, that was why I chose Lua. As my use case (a game) continues to develop, now I want TypeScript with all its ES6 glory and maintainable types. I lament that nothing similar to ES6 came for Lua
I don't think the CoffeeScript comparison is fair. Kotlin fixes some major Java problems (NPEs and checked exceptions), CoffeeScript was almost purely sugar over JS semantics.
- never store null in a field, a collection, etc
- checks all parameters that are not nullable (most of them) with Objects.requireNonNull
(it's what Kotlin does automatically BTW)
>checks all parameters that are not nullable (most of them) with Objects.requireNonNull
I would go as far as say 95% of them are. So now your code is filled with effectively pointless checks (you run into an error at runtime instead of compile time) if your language had non nullable variables in the first place.
There's a very good reason why low-latency and high performance computing crowd don't use inventions like Scala or Kotlin but they do use Java.
Yes, they all run on the same JVM but most of the nice features and syntactic sugar comes at a price of generating huge amounts of garbage. It's possible to achieve zero- or low-allocating code with almost fully idiomatic Java but not so much with the alternatives.
Is the idea with Scala and Kotlin just that they encourage an immutable-first programming style, and that's why they create more garbage (as opposed to "nice features and syntax sugar")? Also, I thought idiomatic Java allocated all over the place as well (everything that isn't a primitive is an object which is allocated)? Maybe escape analysis is just fine-tuned for idiomatic Java (side question: is escape analysis a property of the JVM or the Java->JVM-bytecode compiler)?
EDIT: I'm getting downvotes, so to be quite clear my questions are genuine; I'm very curious about how JVM languages work, and my intent is not to disparage JVM or its languages! :)
So, the stereotype (mostly negative ;P) of "fully idiomatic Java" involves using factories (themselves managed by factory factories via dependency injection through factory factory factories... see "the hammer factory" post mirrored at https://danstroot.com/2018/10/03/hammer-factories/ or, to a lesser extent, Execution in the Kingdom of Nouns at http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom... for more information) to obtain objects, and most APIs simply don't need temporary arrays or large composites, so it tends to be pretty easy to take the high-performance parts of your code and modify them to never allocate anything at all (instead reusing existing objects from free lists, as the goal is to remove as much of--if not all of--the garbage collection pressure as possible, not to avoid the heap), in no small part because there is a pretty 1:1 mapping between the source code and the byte code... essentially, it is the same argument people use for why they love C (even more than C++, which I maintain has almost the same property): there are never any "hidden" allocations.
I guess I wasn't thinking about the stereotype of idiomatic Java, but rather I'm assuming that--barring escape analysis--every `new` corresponds to an allocation and idiomatic Java (again, not the stereotype) has lots of `new`s. So I'm asking if escape analysis is eliding most of those allocations, or if I'm misunderstanding something and there is some other mechanism for reducing those allocs?
My mental model of truly idiomatic Java already doesn't use new often, and it is then easy to take code which was written in idiomatic Java to remove remaining uses of new; like, idiomatic Java--even the classic stuff--tends to pass around primitives and uses imperative code to manipulate data structures... most algorithms don't really allocate anything other than strings (which are easy to accidentally allocate as those allocations are hidden by the library as opposed to the language, but also tend to be well-scoped in the codebase to parsing logic that should be using more powerful abstractions anyway... and knowing Java developers probably got replaced by XML early in the development cycle, the parser for which you might choose to view as a massive string factory factory ;P). As for the stereotype, it is really important... I added some extended references to my comment, as if you aren't using factory factory factories are you really using Java at all?! ;P. (FWIW, in Execution in the Kingdom of Nouns, two of the examples use new... but almost entirely in ways that feel completely unrealistic to me as someone who did a lot of programming in Java; then the remaining couple allocations I could see being "forced into" would trivially be replaced by a shared instance ;P.)
If you're into factory factories, you should really dig deep into delegation factory factories. There are many. They are a joy to work with as you get to export both interface blueprints and heap allocations to external third counter-parties. Just remember to sign full contract certs before doing anything by wire.
Those people are a frankly unimportant niche in the JVM world. Even in areas where its relevant (banking etc) 99%+ of the codebase is not coded for those tolerances.
Not sure what gave you that idea; it seems you have never been part of that crowd so just throwing unsubstantiated claims around. Performance has always been one of the major drivers in the JVM development. Just read the JEPs and see for yourself.
I you really want the best possible performance you absolutely can program in Scala with little to no performance penalty over Java. In fact, in exactly the same way you can program in Java and still remain competitive with code written in C/C++ (except the typical differential isn't as drastic).
You still have access to "raw" JVM arrays, mutability, etc.
The difference is that you can choose to just restrict the 'ugly' code to your performance bottlenecks and code everything else at a higher level. This gets even better in Scala 3 with opaque types, etc.
It's not some great mystery: Very few people are doing low-latency in Java in the first place, and all of the people who are have probably been doing it for a long time (in Java) already so there's a non-trivial cost to switching from Java to $OTHER_LANG.
It has nothing to do with how easy it is to achieve the performance if you really want to. Well, OK, I might grant that there are a couple of very minor things that kind of work against you in e.g. Scala, namely lack of a native 'for-which-is-a-thinly-veiled-while-loop' and such, but that can be worked around with e.g. spire's cfor or just using while loops.
Compared to the amount of effort to get anything-on-JVM working well in a low-latency environment in the first place, these obstacles are all trivial.
I’m working on converting a huge codebase from Java to Kotlin.
I like Kotlin and would recommend it, but to answer the question:
- slower complication time
- more complicated language: this means code that’s harder to optimize, or that can be overly complex when written by junior developers or language aficionados. (This doesn’t have to happen, but it does in my experience)
- lack of libraries means you will use Java code, and Java and Kotlin code mixing is really well done, but will still expose you to many quirks. This will mean developers will need to know Java on top of Kotlin.
- less stable: things are changing faster in Kotlin, and you’re more likely to see breaking changes if you have a big codebase when the next version comes out.
- performance: in the same way C++ can be as fast as C code - Kotlin can be as safe as Java. In practice though, you will use more abstractions and you may want critical components to remain in Java. From my experience though, runtime performance is not an issue in practice for all examples I’ve seen tested.
The HN crowd is not very fond of the magic in popular Java frameworks but to me that magic is what makes those frameworks so good, although with a bit of a learning curve at first.
Kotlin/Java with a framework like Spring is the sweet spot for web/api development. Fast enough for most use cases, great tooling, huge ecosystem, just the right level of abstraction, easy to deploy, easy to debug, very expressive code using annotations. An API backed by an ORM can be written in 10 minutes with less than 50 lines of Kotlin.
The cons are mostly compile time and startup time. Startup time isn't very relevant for backend services. Compile times aren't great but not horrible either.
The pain point with Java as mentioned in other comments in this thread is the presence of null, which among some other things make it a little verbose. That's where Kotlin comes in. Usually my projects will use framework libraries in Java and my own code is all Kotlin. The nulls go away once code exits from Java land into Kotlin land.
While admittedly not as nice as having it built into the type system from day one, there are a number of tools one can integrate into their build to add various degrees of null safety to Java.
It certainly won't help with verbosity (in fact, it does the opposite to at least a small degree :)), but it can dramatically reduce the number of actual NPEs when running your Java code.
Obviously I am not saying this is a reason to not use Kotlin. But, when, e.g. based on the things mentioned elsewhere in this comment section, you are deciding to stick with Java for a particular codebase, it doesn't mean static null checking is not an orthogonal option to consider.
I'd be totally OK with the magic in something like Spring or Ruby on Rails is another good example if it had code I could inspect when things go wrong. That is really my one and only complaint that I have about "magic".
I currently find myself playing around now a lot with Dart which has a lot of the same convenience and just handles it via code generation rather than dynamic magic at runtime. For me at least, it's a really nice trade off. It also for the record has fully sound null safety which is something I have only ever seen in Swift previously but is a real pleasure to work with.
I guess in the Java world you have options like Quarkus that also give you a similar kind of experience.
I aspire to be like the writer of this comment. Using the good parts of both languages to be a productivity machine.
> The cons are mostly compile time and startup time. Startup time isn't very relevant for backend services. Compile times aren't great but not horrible either.
I'd also throw in readability into the mix. Without knowing the magic it's hard to reason about. Then even by knowing what the magic does you have to have some intuition for its arbitrary rules based on its implementation in reflection-land.
<rant>
Let's take an example: Autowiring. Java is the type of language heavily that pushes programmers to use the Strategy Design Pattern. It's almost the core of the language's philosophy. However, if I want a file that globally states to always use a specific Strategy then I have to turn away from native Java to the dark magic of dependency injection frameworks (Guice, Spring). If I'm reading such code, I have to know to look for a file that maps a Bean to a specific strategy; which is not apparent anywhere on either file. It's somewhere else in XML or a vague annotation that I have to now wrap my head around. To do so, I have to understand arbitrary limitations to the dark magic like whether this Bean is matched by name, type, or qualifier. All of this can be a little overwhelming at times when you're looking at a file where every variable is a Bean.
</rant>
But if you drink the cool-aid, boy does it taste good. I can't start a new project without Guice (pun intended) now-a-days.
I've written a lot of server-side Kotlin recently. No dependency-injection framework. Our `main` method does the wiring up explicitly in code. No magic. The wiring up code is very straightforward and not very long. I would not go back.
In principle we could do the same in Java. The wiring code would contain the word `new` a lot though.
There is tooling for that now-a-days. IntelliJ shows a gutter icon on both the declaration and use side so you can click your way to the bean definition. Just like you can with implementations of an interface. It’s even profile/configuration aware.
Gosh... At my former employer we used Java/Spring for web backends. I am now using PHP/Laravel, it feels like another world when it comes to productivity.
10 years ago we are at PHP 5.2 days. PHP has evolved a lot since then, back then it was cumbersome, but things started to change with PHP 5.6 release and then with the entire PHP 7.x releases (skipped PHP 6) a new standard was set of language improvements, performance improvements and clean up of old bad behavior, impressive work from the core team.
In PHP 5.2 you can't even write inline callback functions, but since then you have closures, type signatures for functions (both for class types and scalar types), namespaces, short array syntax, anonymous classes, generators, null coalesce operator, typed class properties to name a few.
And with PHP 8 new leap forward with things like named arguments, attributes (similar as Java annotations), constructor property promotion, union types, match expressions, nullsafe operator.
Other interesting new stuff is FFI (Foreign Function Interface) so you can all C code directly from PHP.
Performance is also increased a lot, most notably is the array performance much better, opcache built in, but other things like now PHP has a JIT. And GC today is way better than the old days.
PHP community has also changed, lots of good frameworks and libraries and you can use composer (like npm but better IMHO) to use with your project.
You can of course write PHP as the in PHP 5.2 days if you want because new features are optional, so you can take your old code and (almost) run it in PHP 8, but if you adopt modern PHP with strict typing is as good long term as Java, especially if use something like Jetbrains PhpStorm IDE or some of the many static analyzers (psalm, phpstan, phan) that exist today.
Not something big enough to overrule other arguments, but the old fashion imperative java as in "mutate stuff in your local scope as if there's no tomorrow" is much nicer to consume in a debugger than the declarative "describe what you want and let the compiler figure out that it fits together or not once and for all" style that kotlin pushes even more than modern java. You certainly don't need the debugger as much for trivial mishaps that are simply not possible in the new style, but if something isn't working at all it's much harder to get your bearings with a quick step-through than in imperative. Of course it's just as possible to go all-imperative in kotlin as it is in java (even scala would allow it), but it's just painful to see an elaborate step by step block full of possible bug hiding places where a simple val...filter...map... expression could provide a clear description of the result.
That being said, my mind still hasn't adjusted at all to thinking about names before thinking about types, guess that's very much to expect after a decade of naming 95% of variables "class name, but lowercase".
(PS: I actually maintain the fantasy that there might be room for a language that abandoned the entire idea of local variable names and just referred to e.g. parameters as "the {type} parameter", pushing typical cases of more than one instance of a certain type sharing a scope into the type system)
There is a lot of reasons to prefer Java (Disclamer: I don't use Kotlin all that much).
First, there is really not that much reason to use Kotlin for the type of applications that would normally be written in Java.
When I look at Kotlin code in my org most of it looks like Java with some very slight, cosmetic differences. The reality is overwhelming majority of people writing Kotlin is Java developers and overwhelming majority of those continues what they were doing in Java but now in Kotlin.
It is more difficult to find people with experience to work on Kotlin.
Kotlin is slower than Java, but for most applications it shouldn't really matter (in that if you make it your focus you are probably wasting time while you could be doing something more worthwhile).
To develop in Kotlin well, you should also know Java. So now you really need to know two languages.
Let's face it, people who go to work with Java projects are not exactly cream of the crop (and I am saying this after working with Java for the past 20 years). Java has some excellent frameworks (ie. Spring), documentation and guidance (ie. stack*) on how to structure your application that makes it much easier for a junior developer to start writing new service and for everybody to understand existing code (because it all looks alike). As a tech lead this lets me focus on other stuff rather than telling developers how to write a controller, how to read configuration file, how to structure your database layer, etc.
> Let's face it, people who go to work with Java projects are not exactly cream of the crop
is a bit of a weird take.
If you're saying that most people working in software engineering aren't "exactly cream of the crop" to begin with, then you probably have a point (I'm a java dev as well, by the way), but I don't see how the programming language changes the equation.
* If the code is good, it will be in use for a long time.
* Hence if you want to work on software that matters, you will often work with a language that is not your one true love.
Me and my extremely brilliant collegues in my current project write Java, because that's the language the team has chosen. The language, when it's one of the major ones, has no significance.
That's still likely to be somewhat true, but it isn't really about programming languages, it's about new/niche technologies vs. established technologies.
By the same logic, Python would now also be in the 'uncool' group, since everyone and their mother uses it.
I think that it was never true. People always find ways to feel superior over random things and the above article was written to please certain kind of readers.
> if a company chooses to write its software in a comparatively esoteric language, they'll be able to hire better programmers, because they'll attract only those who cared enough to learn it.
During whole my career, I have found that there are always new things to learn. Learning is not limited to picking new language. And if you work in more popular language, no matter which one, there are always new framerworks, libraries, security issues, performance optimizations, approaches, tools to integrate with, algorithms, you name it.
What he is saying there is either that picking new language matters more then the above. I don't find that convincing.
> So a language that makes source code ugly is maddening to an exacting programmer, as clay full of lumps would be to a sculptor.
Is a programmer with aesthetic preference against java really inherently superior? I find that whole section low on arguments and high on colorful emotions appealing metaphors.
So weird that back in 2004 Python was the "hot new niche language". I guess the modern parallel would be Rust, and now I wonder if rust will eventually be the same as python is now.
>>> Let's face it, people who go to work with Java projects are not exactly cream of the crop
You can apply that saying to any language or project. The fact you are biased against Java is a bit disturbing. I know it is cool to be a Java hater but why?
At the university where I teach we used to have two year 1 intro to programming courses: Java and OCaml. The weaker students overwhelmingly preferred Java and the stronger students OCaml. I don't think that was a statistical anomaly in a 200+ size class.
With all the due respect, that's apples to oranges.
It's unsurprising that stronger students prefer OCaml, because it's objectively the more interesting (or at least the more intellectually stimulating) language.
When we're talking about programming languages as engineering tools, a whole lot of ancillary issues must be taken into account. Is the language performant enough? Is the tooling good enough? Does it have good library support? What about C integration? Is it easy do build and deploy?
Java vs. OCaml is precisely a great example of this conundrum: OCaml is objectively the better language by a mile, Java has objectively better support by a mile.
I think you both agree, you just guys don't see it.
I don't know if OCaml is better than Java because I don't use OCaml.
But in general, the better you are at development the greater choice you have. And also better developers on average prefer more powerful tools because for them the steep learning curve is not prohibitive and because they can recognize value of using more powerful tool.
Weaker developers are basically happy they can program at all and most weak developers to settle on the first programming language they learn.
Want to filter out poor developers? Don't hire anybody who only knows single programming language well.
Not because knowing two languages makes you better but because you put effort in learning another language which means you had the curiosity, perseverance and ability to do it.
Learning a programming language when you are good developer is no issue -- I do it in passing just to solve some particular problem and move on. If you are poor developer learning a language might be major effort and accomplishment you may not want to pay for again.
I personally know of no good developer who only knows single language.
In our school, everyone knew that Java is for lesser programmers before they ever wrote a line of it. I actually thought that too and being ambitious, I would go for different course.
Then I matured (both as person and as programmer) and now I don't hold the same views.
I don't want to say that "java is for lesser programmers". What I want to say is developers and companies sort themselves by making individual choices.
The end effect being that if you work for a company and you don't have a huge hiring budget you don't go looking for developers in esoteric languages.
Because then availability of developer is much more important than showing they can pass steep learning curve.
On the other hand developers who can't pass steep learning curve will gravitate to a language without one, where they can be hired more easily.
Does steepness of learning curve mean a language is better or worse? Not necessarily.
Does a person getting into Java development mean the person is bad developer? Of course not.
> The end effect being that if you work for a company and you don't have a huge hiring budget you don't go looking for developers in esoteric languages.
The salaries breakdowns I have seen did not worked like this at all. Esoteric languages paid less. I think it was mostly because those companies were in unstable businesses and because people who like those languages accept pay cuts more often. The salaries for boring languages were higher.
And second, the assumption that only difficult thing that can possibly attract people is difficult/esoteric language is odd. If you are in that situation, then you are in fundamentally easy situation. In fact, forums are full of developers for whom frameworks used in jave world are impenetrably complicated to learn. I can't square that with supposed superior willingness to learn. (I can easily square not liking these.)
> The salaries breakdowns I have seen did not worked like this at all. Esoteric languages paid less.
That's because salary is only one part of the cost. You are looking as if it was the only cost, which is not true.
Finding people for the project costs. Finding people with exotic abilities costs a lot and takes a lot of time which may complicate your plans or require you to have extra staff just in case somebody leaves.
It may pay less because in some specific niches people will work for less just to be able to do what they like to do. If I had ability to join a serious Common Lisp project I might do the same.
> When I look at Kotlin code in my org most of it looks like Java with some very slight, cosmetic differences. The reality is overwhelming majority of people writing Kotlin is Java developers and overwhelming majority of those continues what they were doing in Java but now in Kotlin.
I've never used Kotlin, but this is exactly my experience with Groovy. Ten years ago, my department had some Groovy enthusiasts that pushed it heavily, but now we have a bunch of Groovy systems where the majority of the development staff are NOT Groovy enthusiasts, and many are either new hires or low-cost offshore devs with only Java backgrounds. Now all Groovy provides us is the opportunity to experience new classes of bugs that we probably wouldn't see if they systems were written in Java [1].
Generally, I think long lived systems should be written in some kind of "lowest common denominator" language. That's likely to be more easily maintained long in the future. They especially should NOT be written in some other language where someone can get by by pretending it's the LCD language, since that an invitation for bugs wherever the other language violates LCD language assumptions.
[1] My favorite is one where a previous entry-level guy wrote a loop, declared the control variable as a STRING, then used ++ to increment it. Instead of failing fast, Groovy "made sense" of this by interpreting that last char of the string as a char, incrementing that, then coercing the whole thing back to an int for the comparison. This worked, UNTIL the control variable had to go past 9, after which the increment resulted in a ':' and the coercion back to an int started failing in prod.
The name Groovy brings back some old nightmares. Any time a language has syntax reduction as a main feature, it's just optimizing the generation of tech debt.
(Real advances come through safely bundled abstractions, not typing speed)
Findall/collect/each are not replacement for for loop. They only replace special case of for loop where you are not interested in the value of index.
In general, applications that just process collections of items and running some logic on them can most of the time get away without using for loops, as is probably your case.
>"Let's face it, people who go to work with Java projects are not exactly cream of the crop"
Here, fixed it for you: Let's face it, people who go to work with any software projects are not exactly cream of the crop.
This is natural. You have bad performers, meh performers (a majority) and top performers (a minority) and it goes like this in almost every area of human's productive activity.
Different type of developer is drawn to different types of languages and different types of projects.
Developers who barely can write loops don't go write games in C++. They are much more likely to go write corporate backends in Java because corporations are notoriously very bad at sorting who is good and who is bringing negative value.
- coroutines in Kotlin are a crappy solution compared to the future Java one, which is to keep using the Thread API and switch to an async model underneath, without the developer having to care about it at all
- multi-line Strings aren't fucked like in Kotlin (leading-whitespace behaviour)
- superior tooling: IntelliJ works much faster, refactorings are more reliable in Java
The reason i've heard voiced by managerial types is that it lets you have access to alot more off shore resources or contracted resources. TCS/Accenture/Infosys has a firehose of Java devs to throw at a project. Not so much Kotlin.
This isn't a "kotlin coding god" argument. Tata Consultantcy Services (to use an example) has thousands if not tens of thousands of Java "devs". Quality isn't great, but Java has been around long enough that at this point, at least some of who they send to your project actually do have the java experience they claim.
Though speaking from personal experience, the dude/lady with 5 years of java 7 and below experiences gets stuck in their ways and doesnt write more modern Java code. I had one dude who got mad and would try to block PRs if you did lambda functions from those bodyshops.
My experience dealing with body shops. If you ask for Kotlin, the body shops will send you devs that have Kotlin on their resume, and if your lucky the body shop had them do a 10 hour online course on it. If your corporate model uses body shops you are probably gonna get better results from them with a more mature language than something newer.
I can second both the availability and quality issues. Tried to get a Kotlin dev for Android via Toptal and settled for Java when they said they basically had 0 Kotlin experience on staff.
As for quality, the app worked and works well, but there were some serious WTF design decisions made that have made it impossible to maintain the app, not to mention total lack of testing.
I think this has always been the case no matter what language is used. Body shops push crap, it is just the way of life. It can be crap java, javascript or kotlin the fundamental of why they are shoving crap is not going to change because of the implementation language.
I've been considering Scala recently to move from Kotlin that seems to slow down in its evolution and future perspectives. But two points are still pain points for me 1) toxic community members 2) there is a NIH syndrome where there is pressure to rewrite everything in Scala when a Java lib exists (and I still don't know if it is because using Java libs is hard or just because of something else).
Using java libraries from scala is very easy. In my experience, there are two reasons why java libraries are either re-written, or more often, wrapped with a wrapper library:
- To make library usage more idiomatic in Scala. This usually means replacing nulls with Options, exceptions with Try, and mutable or java collection data structures with immutable or scala collection data structures.
- To provide idiomatic concurrency interfaces, such converting a synchronous libraries or internal threadpools to scala.util.concurrent.Future (or scalaz.concurrent.Task)
If you're like me and have spent several years working with Java projects, moving to Kotlin will slow you down at first. You also may not know all the cool new features available in Kotlin from day 1, so you may find yourself doing "java" things in Kotlin, or not knowing how to do some things in Kotlin at all.
If you're on a tight deadline for something, you might want to just stick with Java (if you know it) until you can dedicate enough time to learn Kotlin well. If you're new to both Java or Kotlin, then learn both. :)
> Java is trying to figure out smart ways to access CPU-native 80-bit registers
What? Java has made use of extended precision floating point on x86 (well, x87) since 1.2. There is actually a proposal to stop doing this now that the x87 instructions are no longer the best way to do floating-point arithmetic [1].
Or is this about something else?
EDIT: Why am i asking here? I asked on the Reddit thread.
Glad I wasn't the only one to notice that. No one idea what he could possibly mean but given that Java hasn't used x87 in forever and there is no reason to ever want to use them I guess he is just completely wrong here?
I think Kotlin is great. I feel much more fluent when writing Kotlin than I do when writing Java. The thing I really miss though, is checked exceptions. I have no clue which exception types a library function might be throwing unless they're explicitly documented (which is rare). Does anyone know if this is planned to be addressed at some point?
The single biggest reason is to avoid getting stuck with a codebase written in an evolutionary dead end.
Java and Kotlin will gradually diverge, particularly as Java gains features which are similar to Kotlin features but implements them slightly differently. Third party library APIs will start use the new constructs and you'll be stuck with two slightly different ways of doing something very similar in your codebase.
Over the course of 10 or 20 years, that will probably happen again and again. Java evolution used to be pretty conservative but it's picked up pace and its closest non-JVM competitor C# is miles ahead in expressiveness.
For example, CoffeeScript seemed like it made sense 10 years ago. JavaScript was full of defects and CoffeeScript fixed a lot of them, at the cost of a slightly different syntax, though not so different that you couldn't debug the resulting JS. But you wouldn't want to be stuck with a CoffeeScript codebase today.
Checked exceptions sound good in theory but to make it works it requires the whole community to buy into that level of paranoia right from the beginning. It's a much better concept for a language like Ada or Eiffel more design-by-contract style. Java already plays fast and lose with safety, checked exceptions are closing the barn door after the horses bolted. In reality checked exceptions in Java just means everybody swallows exceptions by doing nothing and moves on.
I'm not familiar enough with either of those platforms to answer that specific question, it was more a general comment on the respective developer cultures. I've worked on several Java codebases where swallowing exceptions was the norm, but in their defense it was because several libraries were way too chatty in their use of exceptions.
I worked on several Java codebases where more than 90% exceptions weren't swallowed. The other 10% were swallowed with a comment explaining why it is fine to ignore.
No it didn't. And they're not discouraged in Java SE. Ignoring errors and letting them propagate to thread's main is just stupid. I haven't heard single argument except "Meh, I have to write throws Exception to every method". It's either "throws Exception" or something like "Either<Exception, String>". Same principle, you declare errors in type system. And if you have reason to believe that it's a good thing to hide errors from type system, then please, convince me.
My problem with kotlin is not that it's not better, or not fun. It's that we have millions of lines of java code across hundreds of projects that will not be ported. Having to context switch in between maintaining projects is another stone on top of tech-debt mountain.
I think kotlin definitely works for android developers but other cases need more thinking. If you're building webapps in smallish teams then maybe those work too.
Some reasons against Kotlin are-
* If you are working in a mid to large team then having all developers learn a new language is a massive cost. Learning Java is also still a requirement if you're developing in Kotlin since many open source libraries are in Java. So teams need to be aware of 2 similar but different tech stacks.
* If you are developing platform libraries then you would look at higher adoption by using Java 11 LTS as the baseline. You could add an optional kotlin library for a better experience.
* Others have pointed out how Kotlin will be an evolutionary dead end as Java catches up on features.
The Kotlin ones are sometimes so buggy it defies belief, especially considering Kotlin is a JetBrains invention. The Java tooling & speed are leagues above Kotlin.
I beleive that Kotlin was built not to sell IntelliJ, but to build IntelliJ. JetBrains has that line of about 20 IDEs all written in Java sharing an awful lots of common code. I think that together it is among largest Java codebases still in super-active development.
So, you have to code on Java 40 hrs per week year by year. All those `Foo foo = new Foo();`, every day. And you think: "If only there was a language like Java, but better, and it was interoped with Java, so you can gradually introduce it into Java codebase!".
I can only speak for myself, but I've never found the `Foo foo = new Foo()` that onerous. In fact, it seems kinda quaint after a bunch of Guice and Dagger stuff
I think the question should be why Kotlin instead of Java because it provides part of the answer.
When I switched to Kotlin, I liked some nice things, but found that in the big picture, it wasn't a huge advantage, and many of the language artifacts I didn't like.
Most importantly: Kotlin doesn't produce more succinct code. The code is not really that much shorter. If you go to Android and look at all the Java/Kotlin examples, they are almost always similar in terms of length and complexity.
Once you find yourself dealing in an entirely Java world, with Java idioms, libraries, builds, jars and reading java source ... the bit of 'impedance mismatch' to your own Kotlin code then becomes a pain.
Kotlin is no way better than having to work in 'two languages at once' with the constant switching. And of course a whole bunch of extra tools as well.
Also, Kotlin is more of a 'bunch of features' than a cleanly designed language.
So in the end if you are using K for a very specific reason (maybe js compile target), or if you can do the whole project cleanly in K (maybe Android) etc. then maybe K is the choice.
But I've switched back to Java and accepted slightly more verbose typing and never missed it. The IDE's do a lot of that work anyhow.
Even more qualitative ... I find Java easier to read and maintain for some reason.
I would almost prefer a few small changes to Java than I would a new language.
Incidentally, the author of the linked post is one of the lead maintainers of Lombok, a widely-used Java enhancement library. So he knows of which he speaks.
What does that mean here? I'm not an Android dev but I cobbled together a couple of tiny PRs for something recently, and Google's Android docs cover both, with toggles to flip between Java & Kotlin example code.
Android Java doesn't count, it is a Java 8 subset, with cherry picked features from OpenJDK, stagnated on purpose as means to sell and market Kotlin on Android.
Oh, then I misinterpreted your comment. (To something like 'if you don't use Java like Android expects you to then expect pain and suffering'.)
I just assumed it was about Android because I've never heard about Kotlin being used besides Android. But then I suppose I don't hear about (because I don't work with) Java much either.
They don't, otherwise Android Java wouldn't be on its current state, a stagnated implementation, that fairs quite poorly against Kotlin when comparing language features.
I don't think "being like Java" is all that important. These slight variations between related languages are easy to learn.
I know a lot of people put a lot of importance on it, but I find the language the least interesting part of programming.
Recently someone suggested rewriting our Node.js backend in Python. I've never worked in Python (except the few times I helped my son with his homework), but I'm all for it (as soon as we have some room in our planning, which we currently don't). It's a great opportunity to learn something new. Although apparently it's because other teams in our current department (we've moved around a bit) also use Python on the backend, and they want to be able to move programmers around between projects, but then I wonder if those programmers understand the concepts behind our application, because that's the interesting part of programming.
As far as I can tell, the central point is that Kotlin and Java will drift away in the future as Java gets more features. One example is given (instanceof).
OTOH, Kotlin is growing extremely fast. It was already top 8 in the global developer population report in Q4 2018. Will it gain enough critical weight that it will become one of the standard JVM languages and influence how features are added to Java?
I worked in Kotlin for a few months, having very little experience Java to begin with. I have/had deep experience in several other languages, though - Python, Ruby, Clojure, etc.
Kotlin was nicer to work in that Java, but 99% of the concepts seemed to transfer neatly between the two. Server-side web app development was somewhat limited by the lack of a mature ORM. Exposed and ktorm were the big ones; Exposed explicitly didn't support many PostgreSQL features and had no plans to do some, while ktorm is a small project seemingly maintained primarily by a single developer.
> Server-side web app development was somewhat limited by the lack of a mature ORM.
I assume you mean a mature ORM written in pure Kotlin with this statement. Because Kotlin interopts so well with Java, you can use any of the battle tested web frameworks like Spring (Boot) with ORM's like Hibernate. Most of these frameworks/libraries even have additional kotlin extensions to enhance the experience.
Kotlin + Spring + Postgres is my default stack to do a web/api project in 2021. Super productive environment with good configuration/cloud/di/orm support and a huge ecosystem of available libraries.
Does it have to be an either or? Our project is mixed allowing us to leverage newer java things where appropriate but still getting the more concise code of kotlin for the majority of our project.
One reason not to use Kotlin: its syntactic sugar makes it harder to read for someone who doesn't know the language.
Most Java syntax and semantics are pretty much self explanatory for anyone who has worked with any object oriented language before. (Java programs are often rather difficult to understand though, but that's due to overengineering, not the language itself.)
As a person who is just starting to learn Kotlin for Android Development, Can you please tell me which language is better to pursue for android development?
As someone who's been in that field for the last, uhhh, 8 or 9 years, I'd say feel free to go with Kotlin. You will understand java the moment you see it later on, meanwhile Kotlin is easier to write, understand and think it. It will get you where you want to be faster than Java. All modern examples will be written mostly in Kotlin, so you won't have trouble adjusting. But in the end, just pick one and go with it, being paralysed by analysis won't help you at all, and after you're fluent in one the other will be familiar too.
I have nothing to say about the rest of the article, but here's one bit that doesn't make the point the author hopes for.
> The obvious difference with the app is that the Java version size is 74Kb, the Kotlin version is 781Kb. Rather a lot of bloat for a small simple app.
No, it really isn't. Anything less than one MB is negligible. Importantly, since we have exactly one sample for each we don't know if that's fixed overhead or variable. Does a 5MB Java app become a 5.7MB Kotlin app? Then the overhead is fully fixed and it doesn't matter. Does a 5Mb Java app become a 50MB Kotlin app? That's a problem. The truth is probably somewhere in between.
We don't know because the author made the unfounded statement about bloat with just one data point.
I would like to say Java, but given the way Google stagnates Android Java on purpose, and pushes Kotlin no matter what, Kotlin is the way to go for serious app development.
Then if you want to do anything related to 3D, realtime audio or machine learning, you also need either C or C++, as those APIs are NDK only (OpenGL is actually also available to Java, but Vulkan is the official 3D API since Android 10).
Now if you want to target Android only as hobby, use whatever you feel like.
One important consideration is if you need to scale up your team it is much easier to do it with Java than with Kotlin. I know the code/implementation aspect exists but scaling a development team quickly has a much greater chance of success with a "boring" platform.
Kotlin’s closed/final by default is a huge flaw when working with a large codebase. Code is not left extensible by default. I don’t want to sprinkle my code with the open noise. False performance optimization, big maintenance/flexibility expense.
It's not a performance optimisation, it's to avoid codebases accidentally becoming a big ball of mud. Prefer composition over inheritance. Definitely do not inherit accidentally or from a class that wasn't designed for inheritance.
The JVM can already optimise classes with no subclasses because it knows all the classes that are currently loaded, so it doesn't need language support.
Yeah, Java works. You have to sneak up on Kotlin to make it do anything. Also, when you have questions, the java community is a lot better. The Kotlin community is made up of the same tweed jacket wearing losers that were doing rails back in the day.
With that said, I really hate how tight of a hold JetBrains has on Kotlin. While you may find an outlier here or there, (someone using Eclipse/NetBeans - heck, I've even used Visual Studio Code and Vim to hack on some stuff) 99% of the people writing Kotlin are using IntelliJ. Kotlin is built to sell IntelliJ. (And the lock-in is pretty apparent) I don't begrudge a company the right to do this. I don't like it, but I have a choice whether or not to use the language.
Lastly, Kotlin feels unencumbered. One can program in a functional style like Scala. One can program in an OO style like Java. It feels "free". The sugar that it adds to Java makes my day to day a pleasure.
So consider me a fan of the language itself. I highly recommend building things with it. Am I optimistic about its future? That's really hard to say. Google's behind it at the moment, but Google's attention span rivals that of a fruit fly.