Kotlin is one of those things that I avoided learning for so long just because I didn't want to learn another new thing.
And one day I had to work on a project that was 100% kotlin and so i decided to do a 3 hour crash course on Youtube (actually watched it at 3x speed so it was really 1 hour) and once I grasped the basics it really made so much sense and I don't think I'm ever going back to writing Java classes anymore after having seen the light.
Same happened with xpath long back. So long I resisted learning it because CSS selectors did the job but once I reluctantly learned it it changes your whole way of thinking.
I think my fear of learning new things comes from coffeescript, something that actually had a negative impact and I would have better off not learning it which also made me scared of learning new technologies.
Java developers are rightfully conservative and sceptical of "new things". That said I believe Kotlin really provides a strong value proposition over Java. You also don't sacrifice much, there is less tools ofc but enough to get by, performance is equal for the most part etc.
Also unlike stuff like CS it has a very strong future with Android backing.
I'm not sure how well "less tools" holds up when Jetbrains has done an awesome job of supporting Kotlin in their Java IDEs. There's something to be said for a dev tool shop developing a language.
To have used both, Kotlin is probably the #2 language with best IDE support, and the gap between the #2 and the others is as huge as the gap between #2 and #1 (Java)!
Java has much more inspections, more intentions and some next generation inlay hints such as the "related problems" view.
Thankfully Kotlin is catching up (and is e.g currently getting support for code vision)
On the other side Kotlin is THE language optimized for developper Happiness/ergonomics and its shows that it has been designed by IDE developers.
Oracle does a really good job improving the Java language. I really don't see any reason for why I should start using Kotlin. I use Groovy when I just need to do something fast without all the boilerplate code. But for 95% of the business problems, plain old Java is exactly what I need. For anything else, its Rust, Python, Javascript that shines in each of their category.
I felt the exact same way until last year. Java 8+, IntelliJ IDEA, and Lombok combined massively reduced boilerplate.
Groovy was great for “more than Bash” and DSLs.
I was wrong. Last year we gave Kotlin a try as a team and at this point we’re 100% Kotlin where we would’ve been using Java or Groovy (which would be the vast majority of our code).
Spring and IDE support has made this transition easy. Coroutines are great for the type of code we write, SAM advances in Kotlin 1.4x have removed the last couple “I like the way Java handles that better”. Best off, all of those libraries we already created and use are still completely usable, we didn’t have to rewrite anything.
For me nullability checks by default, synthetic/map backed properties, extension functions, inline/reified functions, and coroutines have so drastically improved the readability AND conciseness of our code I can’t imagine going back.
Oracle is doing a good job adding features to Java to keep up with modern languages, but it’s not just about adding — some things need to be removed or changed.
By way of example:
Final classes by default with an open keyword instead of open by default with a final keyword. Inheritance is a very tricky thing to get right and it’s better to explicitly say “I thought about this and put in the effort to make it work”.
Checked exceptions are a contentious topic and I’m not sure which choice I prefer, but Kotlin chose to remove that, and it has an impact on style.
I can see checked exceptions being a good option for a pre-Java8 world, but they interact horribly with functional interfaces, which are fundamental to a bunch of other newer Java features.
A lot of those are almost philosophical differences, though. A Java feature that is unambiguously bad, but probably impossible to remove, is the different equality semantics between atomic types and their boxed versions.
...is exactly the wrong way around. Inheritance is very much about unplanned reuse and programming by difference. That is: there is something that almost works the way you want, but not quite.
If you are actually planning this ahead, then typically inheritance is the wrong approach and you're better off using composition.
The whole point of OOP is that each object is responsible for maintaining its own invariants. Open classes are useless without open methods, and open methods are a weak point in terms of letting your child classes mess up those invariants.
Interfaces are completely free of this burden. Abstract classes signal that you're working with an incomplete implementation and you're expected to cooperate with the base case to make things work. Final classes just opt out of this whole thing altogether.
What, exactly, does a class being open say? In a default-open context, you don't know whether this is an omission or a design choice. In a default-final context, you're explicitly allowed to mess with the class (and, because of the explicitly open methods, only in safe ways).
> The whole point of OOP is that each object is responsible for maintaining its own invariants.
I think there are a whole lot of people who might disagree with the assertion that this is "the whole point" of OOP. Including one Alan Curtis Kay.
OOP to me means only messaging, local retention and protection and
hiding of state-process, and extreme late-binding of all things. It
can be done in Smalltalk and in LISP. There are possibly other
systems in which this is possible, but I'm not aware of them.
You seem to mix "class" and "object" rather freely. They are quite different things. Also, not sure what you mean with "open methods". I can add methods to something in a subclass. I can override methods in a subclass.
> letting your child classes mess up those invariants.
Who is the "you" of the "your" in this context? A class? But a class is not a really a thing, objects are. And it is the objects that are the units of encapsulation in OOP. Not classes. Classes are just convenient bundles of behaviour and templates for state that is attached to objects.
You might think this is silly nitpicking, but it's actually a really, really important distinction:
As a teacher of object-oriented programming, I know that I have succeeded when students anthropomorphise their objects, that is, when they turn to their partners and speak of one object asking another object to do something. I have found that this happens more often, and more quickly, when I teach with Smalltalk than when I teach with Java: Smalltalk programmers tend to talk about objects, while Java programmers tend to talk about classes. I suspect that this is because Smalltalk is the more dynamic language: the language and the programming environment are designed to help programmers interact with objects, as well as with code. Indeed, I am tempted to define a “Dynamic Programming Language” as one designed to help the programmer learn from the run-time behaviour of the program.
And the object in question is an instance of the subclass, and if you are going to involve classes, it is the subclass that is responsible for maintaining invariants. The superclass no longer has that responsibility for instances of the subclass. So nobody is messing with anyone's invariants.
Wow, I am pretty much exactly of the same view (except for using Python, I really don't like Python, been burned too much by its constant problems with using system libs that only ever seem to work on "my machine" - Groovy is a lot more reliable for scripts IMO)... but I do use Kotlin sometimes, but with Java 17 likely bringing sealed classes/interfaces to Java, I am less and less excited about using Kotlin.
> When you use any Micronaut AOP Advice, it creates a subclass at compile-time to provide the AOP behaviour. This can be a problem because Kotlin classes are final by default. If the application was created with the Micronaut CLI, the Kotlin all-open plugin is configured for you to automatically change your classes to open when an AOP annotation is used. To configure it yourself, add the Around class to the list of supported annotations.
Many years ago, I used to think that Scala was going to be my "next Java".
Now, guess it's not Scala, by Kotlin. Why?
- First class citizen for Android development. Yes, most of my works is on Android.
- Not to foreign compared to Java. In general, Java devs should be able to Kotlin in relatively short time. Not sure about Scala, which is influenced by Haskell/ML etc. At least in my circle, not many folks familiar with functional programming.
Everything was hot, shiny and new at one point. Java is no longer that, and the developers referenced in the parent comment may not have had any interest in Java when it was hot, shiny and new.
From my modest experience with Kotlin few months ago in a small Android project for learning purposes. I can just say that the language resulted very expressive, concise and easy to use for me. Coming from other languages (Go, Rust, C#, JS, PHP among others) but doing almost no Java in the past, I was able to getting started with that Android project few weeks later after have been passed across Kotlin's docs https://kotlinlang.org/docs/home.html
I guess I remember incorrectly it was 3 hours long. It is only 1hr few minutes and you can easily watch it at 2x speed.
But overall Youtube is a great resource for learning new things. If you search Kotlin crash course (filter by duration > 20min) you will find ton of such courses and you can easily judge them by number of likes/dislikes.
And make sure to watch it at 3x speed with subs ON initially (video speed controller for chrome). This is truly a great hack when learning tech things via video.
The thing about Coffeescript is that you don't really gain anything other than syntactic sugar. Compare it to, say, Typescript and Clojurescript where you gain a whole set of features and, with Clojurescript, the semblance of a standard library.
I really don't remember it was a long time ago but from what I recall there was just too much magic happening and things would break a lot of times because it was easy to make mistakes with it.
Come to think of maybe I didn't learn it well enough at that time and blamed it for my silly mistakes. CS did introduce a lot of good things like the fat arrow which was just amazing at that time.
Completely different motivations, and I suspect Kotlin is a reason that Clojure and Scala seem to be losing much of their initial steam. Clojure offers Lisp on the JVM, but what most people really wanted was a fixed Java. That's exactly what Kotlin delivers. Clojure has decent Java interop, but there's a serious impedance mismatch working with native Clojure and Java libs. Kotlin otoh dogmatically sticks to Java's model of programming, just a cleaned up version.
IME many Clojure programmers come from non-Java backgrounds and aren't looking for a Java like experience. So I can believe the "more better Java" audience probably heads for Kotlin today. I think this is a win for both the Clojure and Kotlin communities and developer cultures.
To inject some time perspective, Clojure is 14 years old, so it's not too bad to be moving from initial steam to young-adulthood steam now :)
Kotlin has this amazing concept called compiler plugins where you can extend, intercept and alter the compiler at any stage of the compilation pipeline (ast, psi, ir) through an API.
While this is cool, it doesn't look like something very different from other existing JVM compiler plugins... it seems quite similar to Javac plugins[0] and perhaps somewhere in between that and Groovy AST transformers[1].
Manifold[2] is basically a javac plugin if I'm not mistaken, and it shows just how powerful stuff can be accomplished with this approach (including e.g. auto-generation of Java types from common modelling languages like GraphQL, JSON, YAML etc. adds extension methods, unit expressions, ranges, C++-like preprocessors, structural subtyping, even crazy stuff like type-safe reflection - like Ceylon used to have!).
For Groovy, besides the built-in AST annotations like `@Immutable` and `@Canonical` (which turns a class into a data class, basically), you can achieve stuff like the Spock Testing Framework[3] which changes the Groovy syntax a little bit to make it really awesome for testing.
Interesting! However I wonder if building Java plugins is harder.
For example: JPA entities have for requirement to have a no-arg constructor.
Both Java records and Kotlin data classes have not such a constructor by default.
However kotlin has a no arg compiler plugin that autogenerate it for data classes (without any annotation) and Java Records don't have anything similar yet to my knowledge. (however they would still remain incompatible with jpa anyway because unfortunately they are immutable)
Thanks for mentioning this. Not knowing Kotlin, I'll read the links you provided.
Guessing this is a bit like Java's annotations. FWIW, I'm not a fan Java's annotation processing plugin stuff. It's fun for personal projects, cuz metaprogramming FTW. But debugging someone else's custom annotation stuff really sucks.
Yes you can. I'm using the Fritz2 framework, which is pretty nice. There's another one called KVision. There are also some people doing react in Kotlin. You can also just program straight against the browser APIs as they have nice Kotlin DSLs for large parts of that.
Basically, to stay on topic, there are currently multiple kotlin compilers, including one that transpiles to Javascript. There is also tooling to interface with npms, to adapt typescript type mappings to Kotlin, and a few more goodies. Basically you lose the java standard library but you gain access to the browser APIs. Node API mappings are more of a work in progress but you should be able to target node.js as well. Browser side kotlin-js is pretty nice. You can do pretty much everything that you would normally do in js/ts. The build tooling uses gradle, which underneath uses webpack. There's a dead code eliminator, source maps, minification, etc.
Our web app uses cordova (for IOS and Android wrappers) with a few plugins, integrates Leaflet for maps, has reactive components (using co-routines and flows), has styled components, etc. So, pretty nice and modern way to do frontend. We have a handful of js things we integrate (like leaflet) and quite a few Kotlin multi platform things (like our own API client).
There is also a js backend for the new IR compiler, which is the thing that Jetbrains is currently building to unify the many Kotlin compilers they have. There is also a wasm compiler backend for that in the works but it's to early to rely on that probably. The IR to JVM backend is currently in beta and kotlin native also uses the IR compiler.
Kotlin-js is not for everyone just yet (a lot of these tools are beta quality) but if you are more comfortable with Kotlin than js/ts, it's worth checking out. That being said, our setup is quite nice compared to some react train wrecks I've been involved with.
Pretty much yes to all of that. You can add npms as dependencies. Some typescript type annotations can be adapted to Kotlin type annotations. And if not, you can write your own. There's a dynamic keyword to deal with untyped javascript objects. Also you can define external interfaces for things. So, interop is pretty good and you have plenty of tools to integrate whatever. With Fritz2 you can create or integrate web components pretty easily as well.
That being said, it doesn't really make sense to try to use mainstream javascript frameworks as they are a poor fit for a strongly typed language like Kotlin. And in general, there aren't a lot of npms that are worth integrating. We made an exception for leaflet and that was pretty easy to integrate in the end. Otherwise we mostly use multiplatform kotlin libraries.
Kotlin is made by JetBrains and additionally compiles to native code and JavaScript, OpenJDK is open source, Google has their own JVM for Android. You could use Kotlin pretty much everywhere with no/only indirect Oracle contact.
Oracle owns Java, plain and simple. There are alternatives, sure, but it's foolish to think that when it comes to anything within the Java ecosystem, the buck doesn't stop with Oracle. All they have to do is modify the Java license and all that open source goes poof.
We're talking about a company that sued it's own salesperson for earning too high of a commission.
There is Oracle risk to be sure, but people using the greater java ecosystem are far less tied to the JVM itself than they used to be because of cross compilation to targets that help with ffi boundaries, JIT, IO, memory concerns, etc. That's true with both Kotlin and Scala.
Meanwhile the Oracle vs Google case is still going on.
And one day I had to work on a project that was 100% kotlin and so i decided to do a 3 hour crash course on Youtube (actually watched it at 3x speed so it was really 1 hour) and once I grasped the basics it really made so much sense and I don't think I'm ever going back to writing Java classes anymore after having seen the light.
Same happened with xpath long back. So long I resisted learning it because CSS selectors did the job but once I reluctantly learned it it changes your whole way of thinking.
I think my fear of learning new things comes from coffeescript, something that actually had a negative impact and I would have better off not learning it which also made me scared of learning new technologies.