12 ms·
From Java to Kotlin and Back Again
- s73v3r_ 8y agoThe crux of this is that they're not doing Android stuff, so they have the luxury of using Java 10.
- virmundi 8y agoAnd that is perfectly fine. Java 10 and then 11 and so on will bring a lot of niceties to developers. I switched my projects to 10. Haven’t had much issue. Now I get to use var!
- s73v3r_ 8y agoAgreed. Because they had that option to them, they were able to switch back. If they were stuck with Java 7, they may have decided that the niceties of Kotlin were worth more.
- eropple 8y agoTBH, I think Java 10 is strictly inferior to Kotlin even when you have that option. Kotlin on the Java 10 JVM is pretty great.
- stevenwoo 8y agoRoughly half of the complaints are against Kotlin specific features or hazard of mixing Kotlin with Java libraries - I was curious since I only use Java for Android as well and have not shifted to Kotlin.
- forfengeligfaen 8y agoI've been using Kotlin with Android for over a year. There have been few problems with SDK interoperability. Since I started using Kotlin Google blessed it. The one annoying gotcha was JSON parsing. If the fields on your models are not declared as nullable, they can still be set to null in the JSON which causes a NPE.
- on_and_off 8y agoI have been using kotlin in prod for over a year now on Android (and I already knew the language beforehand). I don't see myself writing full time in java again, ever.
- s73v3r_ 8y agoRight, but because they were able to use Java 10, a good amount of the pain points that Kotlin was intended to address go away. On Android, you're stuck with Java 7 with one or two Java 8 features, so Kotlin helps out a lot more.
- eropple 8y agoThere exist really, really good arguments for the structure of a programming language. Obvious example: I think Perl-as-is-generally-written is line noise. But complaints like "the type comes after the variable name [so that we can consistently define types, including in arguments, without inconsistent syntax like Java is now forced into]"...aren't good. You might not be comfortable with it off the jump; it's more consistent, it reads fine, it improves implicit typing because you don't need special-case syntax, and it should not be bothering you past the first hour with the language. T! being a little odd is a fair criticism--or would be if it wasn't literally inescapable when working with languages that are, like Java, guilty of Hoare's mistake. For my money they do a better job of it than Scala does, that they address it at all when Java doesn't is admirable, and I think it generally works pretty well. I think Kotlin should make every T! a T? and force you to deal with the null cases, to be honest, but that would probably make the author upset because it'd splat `!!` all over the place. Companion objects are objects, not special-cased static...things, and are significantly more useful than static methods and fields once you have put in a few seconds of chin-stroking to consider why people as smart as the Kotlin crew would have gone that way. Making useful things out of classes in Java sucks, whereas in other environments (something like Ruby comes to mind--as an example, Sidekiq::Worker provides meta-information to Sidekiq because of the configuration of your job class) it's fluid and natural. Kotlin tries--it's not perfect, but within the bounds of playing-nice-with-Java it tries--to improve that. Treating companion objects as useful things in Kotlin is solid. And I have no problem writing a program entrypoint from memory, on the rare occasion I have to. Probably because I understand what everything in it actually...does? And I'm not a Kotlin specialist or anything, I just take the time to understand my tools when I use them. Option/Maybe types are a good idea. I've used Kotlin-specific ones in Kotlin and it was...fine, but the "oh, look at this `let` thing, isn't it so much harder than the Java one?" thing is a head-scratcher. It smells like another case of "I expect things to look like Java so I throw a rod when it doesn't". Data classes are great. That C# doesn't have them is one of the reasons I dunk on the language so much (along with the `static` mistake, but like Java, they were young and foolish). Closed-by-default classes--meh, whatever. Have that argument if you care that much, but we're a tool-using species, set your linter to complain about closed classes if you really care that much. Don't get me wrong: I think one is probably wasting one's time to be using Java preferentially in 2018, but use what makes sense to you. Have decent reasons for it, though, and a lot of this seems like "this is different and therefore scary and therefore bad." Like--steep learning curve? Man, I was writing mostly-idiomatic Kotlin that plugged right into Java libraries in a couple hours. This whole article reads like a weird lazy lament: that changes are hard, seeking new local maxima of correctness and productivity is uncomfortable sometimes, and challenging that discomfort isn't awesome. And maybe Kotlin is worse for the author's particular flavor of code--but, having written a lot of Java and a lot of Kotlin, I really doubt it. Kotlin is spectacular for me specifically because it does not force me into Java's lowest-common-denominator design. It gives me room to be smarter about the stuff I write while still using the often-very-good libraries available through Java on the JVM. I don't get to write as much of it as I'd like, these days...but doing so is consistently fantastic. EDIT: Actually, while I'm at it, I'll give my one real grinds-my-gears thing with Kotlin: I think the way they do blocks is odd. I think that the braces should encapsulate the body of the block, not the variable expression as well; I get the resemblance to Ruby but I think their choice of `->` makes it read oddly. But that's a minor nit compared to the real one: `it` is a wart. I think you should have to name your enclosed variables and I don't think you should be able to shadow them. Heck, the reason I read this article in its entirety in the first place is because the author's first point about name shadowing is a good one...
- bitL 8y agoGood and clear summary of Kotlin warts. In the end I couldn't suppress the thought that there was some hidden Polish-Russian rivalry going on ("Kotlin" == "Heinz") ;-)
- V-2 8y agoHeinz is American (and, in the context of the article, a global brand), not Russian.
- bitL 8y agoSure, it's about the (negative/funny) association. I was recently told about persistent animosity between Poles and Russians; it crossed my mind given JetBrains is a Russian company masquerading as Czech. BTW, I also think that the name "Kotlin" is the worst aspect of the language, especially when you hear how is it pronounced by the authors in Russian. Big plus for language/runtime/transpiler features, big minus for the name.
- V-2 8y agoKotlin the ketchup raises perfectly positive associations for an average Pole. It's a household name, and a company with a nearly century-long tradition under its belt! The authors wanted to name it after a Russian island (as a nod to Java); if you browse the names, some other possibilities were Iturup, Urup, Sakhalin, Kolguyev, Paramushir... :) Kotlin ain't so bad, then
- forfengeligfaen 8y agoI found the transition from Java to Kotlin painless because Android Studio (Intellij) holds your hand all the way. If at first you're unsure of the syntax, you can just write code in Java and convert to Kotlin. I agree that the null-safety Java interoperability does not work properly if the Java code is not annotated correctly (or you're parsing JSON) but I'd still prefer to have it than not. I like Kotlin because: * If is an expression and it feels so clean * Functions are first-class (you can pass functions to functions) * Kotlin is less verbose than Java so there is less to read and write * You don't have to write "new" * Constructors are cleaner (you don't have to write (this.a = a) * The map function (on Android we were stuck on Java 7)
- kjeetgill 8y agoI'm unfamiliar with Kotlin in detail. Can you explain "Functions are first-class (you can pass functions to functions)"? Are they more powerful than Java's lambdas?
- forfengeligfaen 8y agoIn Java 7 (which is what I was using) you could not assign a method to a variable or pass it to another method. So I think it is more powerful. https://kotlinlang.org/docs/reference/lambdas.html https://kotlinlang.org/docs/reference/lambdas.html
- cmurdock 8y agoI think the big use-case is on Android where you're stuck with Java 7 and therefore can't use lambdas.
- dlubarov 8y agoThat used to be the case, but the build tools have supported lambdas for a while now, and it works even on very old devices. On the other hand, Java 8 classes like java.util.Stream only exist on API 24+ devices. So if you want to support older classes, you can't use the standard stream library.
- V-2 8y agoA number of valid points, but I'm not convinced by most of your critique of Kotlin. Colon between names and types (as in "i: Int") "makes work in Kotlin harder"? Seriously? By as much as having to end lines with semicolons in Java? : ) I understand it's a matter of habit, but how could that possibly make anybody's work hard is beyond me "I can’t imagine a valid use case for shadowing a method argument." Arguably this would be better off causing a build-time error, like in Java. But is this such a problem in practice? Do you really keep bumping into it accidentally? Just don't use name shadowing... "In my opinion, Kotlin’s type system with all these scala-like !, ?, and !! is too complex." You've listed "all these" already :) All three of them, among which "!" isn't even something you'll ever use yourself. How is it more complex than explicit null checks? It's also trivial to implement Optional in Kotlin if you think you need it. Thats pretty much all you need: https://github.com/gojuno/koptional/blob/master/koptional/src/main/kotlin/com/gojuno/koptional/Optional.kt https://github.com/gojuno/koptional/blob/master/koptional/sr... "Why Kotlin infers from Java T to T! and not to T??" Probably because not doing that would require putting "!!" or "?" pretty much everywhere you call Java code, even code that you know for certainty won't ever return null - such as Observable.create or every single RxJava operator, for instance. Observable .fromCallable(something)!! .map(String::trim)!! .distinctUntilChanged()!! .switchMap({ searchPhrase -> handleSearch(searchPhrase, view))}!! .scan( initialState ?: DEFAULT_BLANK_STATE, { full, partial -> full + partial })!! .doOnNext { logDebug(here) { "Returning new, updated full state:\n$it" } }!! Etc. That's what it would have to look like if they made it your way. "In Java, we write the class name with .class suffix: Gson gson = new GsonBuilder().registerTypeAdapter(LocalDate.class, new LocalDateAdapter()).create(); [...] in Kotlin, you are forced to write: val gson = GsonBuilder().registerTypeAdapter(LocalDate::class.java, LocalDateAdapter()).create() Which is ugly." Seriously? :) It's pretty much identical code, with slightly less noise in Kotlin. All the difference is type inference (which you praise at the beginning), and no need for two "new" keywords in Kotlin, at the cost of having to add one ".java" after "::class". The difference is rather subtle, so I honestly fail to see why the former version passes for normal while Kotlin's is suddenly "ugly"...
- kllrnohj 8y agoThat GsonBuilder example is also screaming for an extension function like so: inline fun <reified T> GsonBuilder.registerTypeAdapter(adapter: Any) = this.registerTypeAdapter(T::class.java, adapter) Bam, now it'd be: val gson = GsonBuilder().registerTypeAdapter<LocalDate>(LocalDateAdapter()).create()
- kodablah 8y agoI work in Kotlin and Java and have opinions on both. Some feedback... I disagree about the name shadowing issue. In fact, I wish Kotlin didn't suck so hard and not allow me to ignore those warnings specifically. My primary use for name shadowing is so that I don't use the previous variable. This may be a bit strange, but in highly functional contexts with immutable variables, shadowing a name is reasonable especially as you begin to nest. It's not like Kotlin has a problem reusing/shadowing the "it" var name in nested blocks. Rust makes me very happy with how it handles it and it makes the code quite readable. Something like `val someValue = someValue ?: error("Bad value")` is very reasonable. If anything, you can have reasonable scoping warnings if there appears to be ambiguity, but it should not be across lambda blocks as it is now. Can't cite type inference in Java if one of its most popular platforms doesn't support it. May be ok for you, not ok for everyone though. We might wish Android would keep up, but in the meantime we have practicality concerns. I don't think those three nullability sigils make it too complex and has nothing to do with Scala where devs can define their own sigil operators. And Kotlin is ok about inference when the Java code has reasonable nullable/not-nullable annotations. There are a lot of problems with Kotlin's compile-time null checks (namely their insistence on thread safety so a null-checked field can't be reaccessed and assumed null), but "platform types" is the best that can be done within the constraints of existing JVM code. Having the IDE put ::class.java in there is hardly a reason to go away. That's like saying I'm going back to Kotlin because sometimes in Java I have to type .class if its a type and .getClass() if its a value. The obvious reason for it is that Kotlin classes are supersets of Java ones and have more reflective properties. That and not everything is about the JVM (Kotlin has two other targets). If you can use KClass's, they are preferred. There are too many articles on why languages like Scala, Go, Rust, etc choose to add the type to the right hand side of parameters/functions for me to re-explain it here. Your complaints about statics are because how the JVM handles statics, not Kotlin. I appreciate the object approach over JVM statics. Just sucks that you keep having to go back to JVM-land where you are hamstrung. As your apps and library usage grows, you will move further away from the requirements forced upon you by Java and stop complaining about that being the reason you are going back. The key-value not using a new operator thing is simply because one is defined as a piece of a library and not part of the language. You want them to write a special operator for maps which are not even part of the language (just a class that happens to be part of the stdlib)? Instead of an infix "to" that creates a Pair class? The disappointing part is wanting to extend the language syntax even further. You wrote: fun parseAndInc(number: String?): Int { return number?.let { Integer.parseInt(it) } ?.let { it -> it + 1 } ?: 0 } and complained about readability, when I see that and think: fun parseAndInc(number: String?) = number?.toInt()?.inc() ?: 0 And I think, not only is that quite readable, but it sure isn't very practical to accept a null number here. Take a peek at the generated bytecode at some point too compared with your Java version. I'm a little concerned that this kind of stuff has you switching languages...if you make bad examples I bet they'll look bad. In your back-to-Java article you mention data classes with no Java alternative. Spring is annoying. If you're a Spring shop, and you're ok w/ all the magic, stay in Java. It might be best. Sorry I typed so much. I have lots of problems with Kotlin too...but I sure don't share share the ones in the article.
- johnwick17 8y agoMy 5 cents: It seems to me that the author did not spent enough time to learn Kotlin. The way he mixes Java types (Integer.parseInt) inside pure Kotlin code and then complains about lack of Null-Safety? It is enough to use an extension function String.toInt() to stick to Null-Safety and compiler will do the rest. His main() function? Another weird argument because Kotlin's documentation has some examples on how to write it. Author lacks understanding of how Kotlin is converted to Bytecode. Complaining about such insignificant things like class literals or variable name shadowing (there is a compiler warning for that!) makes me want to shout: Hey, Kotlin is the most amazing language ever if those issues ended up as #1 and #4 on authors "bad bad Kotlin" list... Generally speaking, when someone writes about a programming language in a bit hateful way it is better to learn the language first.
- kodablah 8y agoYup, I wrote a longer form of basically this. I wouldn't want the person posting to make the language decisions at my company.
- on_and_off 8y agoOr have to work with that person, which is especially bad since one of the goals of this kind of posts is to advertise your company.
- kodablah 8y agoA bit too far I'd say. I'd probably happily work with him.
- johnwick17 8y agoI have seen his other posts and he is a smart guy. No idea what bit him with Kotlin though...
- jxub 8y ago
- IshKebab 8y agoSome good points, but most of them don't seem like dealbreakers - you could easily get a much longer list of flaws with Java.
- HillaryBriss 8y agointeresting function parameter name shadowing issue they highlight. had not run into that, but, wow, that adds some serious confusion. i also heartily agree with the article's points about nullable types and Java library interop: it's pretty annoying to deal with Kotlin non-nullable types that have to interoperate with existing Java libraries that have nullable types in return values or function callback parameters. i have way more question marks in my Kotlin code than i originally thought i would. i also appreciated the article's scrutiny of the name and type order reversal in Kotlin and the "::" syntax for getting the class literal (::class vs ::class.java). still trying to get used to that. and as for the learning curve, i have to admit that it's been steeper than i expected when i first saw introductory presentations. Kotlin feels very abbreviated. the smart type inference and things like 'lateinit' have sometimes surprised me in their behavior. these aspects of Kotlin are indeed very smart, sometimes too smart for me. i feel like i have to think harder to understand a piece of Kotlin code, which is ok, but somehow, i wasn't expecting that based upon the initial presentations. overall, Kotlin is ok i guess, but, to go off-topic for a sec, as an Android programmer i wondered why Google chose to emphasize adding a new language when many other aspects (e.g. documentation, the jumble of GPS, Firebase, GCM and 3rd party libs, mysterious adb failures, emulator problems, instant run, etc), of the ecosystem needed improvement/simplification/clarification more desperately.
- _bxg1 8y agoTypeScript also has the weird reversed type declaration. I've never understood it; it's so much less natural to read. Having the type first allows you to easily mentally parse it as "A Foo named bob".
- eropple 8y agoSee, that's interesting to me, because I have always read declarations aloud as "bob the Foo", even when they're written "Foo bob". Reasonable people can differ, of course. Where it's harder to differ is that is much easier to parse type-after declarations and to make a consistent syntax with them--that's why Rust et al have gone that route. To do type inference in Java (or C#) they've had to add a new keyword, `var` (and the comedic `final var` in Java), because their declaration structure just wasn't up to doing it any other way.
- _bxg1 8y agoThat makes sense. It's definitely a subjective thing and I used almost nothing but Java and C++ for my first [counts fingers] 6 years of programming, so I'm probably biased.
- Rapzid 8y agoI'm pretty sure I've used to read them "A Foo named bob".. But I've been in TypeScript and golang land for a while now. I can kinda make sense of it because as an interface the types are what matter most, and the signature in something like F# simply be the input/return types..
- HillaryBriss 8y agofor me the trouble begins when i switch between these syntaxes when going back and forth between Java and Kotlin, which i still have to do all the time
- pavel_lishin 8y agoIt feels weird to me, too, but I'd wager you'd get used to it pretty quick, just as you get used to saying "la pelota roja" instead of "the red ball". /me hopes he didn't completely butcher the Spanish.
- V-2 8y agoJava version in the article: public int parseAndInc(String number) { return Optional.ofNullable(number) .map(Integer::parseInt) .map(it -> it + 1) .orElse(0); } And the Kotlin equivalent... "No problem one might say, in Kotlin, for mapping you can use the let function: fun parseAndInc(number: String?): Int { return number.let { Integer.parseInt(it) } .let { it -> it + 1 } ?: 0 } Can you? Yes, but it’s not that simple. The above code is wrong and throws NPE from parseInt()." Yes - that's why Kotlin standard library provides, among many others, a convenient extension function String.toInt(), which is a wrapper around Integer.parseInt(). You're supposed to use that, and then you're safe from NPE, because the receiver has to be explicitly non-nullable (it's String.toInt(), not String?.toInt()). Also there is no need to redundantly repeat "it" inside the lambda - plus you could further simplify the implementation by using type inference and converting it to expression body: fun parseAndInc(number: String?) = number ?.toInt() ?.let { it + 1 } ?: 0 "Now, compare readability of the Java and Kotlin versions. Which one do you prefer?" Well, I'll say orElse(0) is more readable than "?: 0" dangling at the end of the expression. However Java is more verbose. I'd say it's a matter of taste. The difference is that thanks to Kotlin's features - which allow for creating custom DSL easily - implementing orElse is trivial, if you can't live without it: fun Int?.orElse(fallback: Int) = this ?: fallback This allows for: fun parseAndInc(number: String?): Int = number ?.toInt() ?.let { it + 1 } .orElse(0) And this, to me, is already nicer than your Java version.
- kodablah 8y agoOr the one I posted below: fun parseAndInc(number: String?) = number?.toInt()?.inc() ?: 0
- V-2 8y agoOh yeah, I forgot about inc().
- ptx 8y agoTo me it seems really weird to have the function take a nullable string in the first place (and not obvious that null + 1 == 0), so the right solution is probably to deal with the null values at some earlier stage – but in the interest of further bikeshedding of the implementation, a simple if-expression is pretty clean: fun parseAndInc(number: String?) = if (number != null) number.toInt() + 1 else 0
- bberrry 8y agoAn article about Java's warts written with the same pettyness as the author would probably be the length of a small novel.
- marcodave 8y agoI would bet that back in 199x there would have been countless articles (more like usenet posts) about "from C++ to Java and back" telling all the downsides and gotchas with Java.
- foolfoolz 8y agocompanion objects are one of the best things about modern programming languages. it’s really helpful to think about static and dynamic this way
- on_and_off 8y agoCould you elaborate please ? What do they bring on top of static fields and methods ?
- foolfoolz 8y agothey don’t bring any functionality but it is clearer separation. i think it’s easier when you read these components in different scope blocks. they do very logically different things and importing static into instance makes more sense than keeping it all in one. maybe it was just me but i didn’t undserstand static vs dynamic after 4 years of school and into my first job. it took a while to grasp. but now that i know the differences i’d rather keep them isolated
- __sr__ 8y agoIs it me, or does the article feel like it is written by someone who didn’t actually bother to learn Kotlin. Instead they learnt the bare minimum syntax and tried to write Java in Kotlin. The author complains a lot about how Kotlin is different from Java. Err.. it is a new language — it is supposed to be different — otherwise why bother? > I have my favorite set of JVM languages. Java in /main and Groovy in /test are the best-performing duo for me. In summer 2017 my team started a new microservice project, and as usual, we talked about languages and technologies. There are a few Kotlin advocating teams at Allegro, and we wanted to try something new, so we decided to give Kotlin a try. The opening lines set the tone for the article. The author tried Kotlin because other people wanted to — not because he found it interesting. Most people learn a new language by writing a toy project or two. They don’t start with a real project. And of course it will take time to get used to a new language and be as productive in it as as you were in the old one. The friction is always there, no matter which language you are switching to. I am sorry, but I can’t take this article seriously — I feel that it’s written for the sole purpose of venting author’s frustrations.
- singularity2001 8y agoIt is just you. Edit: and some hundred others. (using my karma as stats counter)
- DeonPenny 8y agoNo thats exactly how it's written. It's written by someone who is so stuck in java land and never bothered learning any other language or paradigms.
- ptero 8y agoI feel the same way: author wants Java and was hoping only for a better Java: compatible with most patterns, tools, even libraries, but addressing some of his pet frustrations. When Kotlin did not satisfy his hopes he got disappointed. Understandably, but I do not see it as the Kotlin problem. The other problem I have with this post is that it did not state desires/hopes up front. The intro only mentions compile-time null-safety and less boilerplate (for which many languages are better than Java), then adds his desires throughout the text. Thus his complaints seem not a thought through list of failures to satisfy specific desires, but just randomly throwing rocks at vague targets. My 2c.
- hoodoof 8y agoval list = listOf("Saab", "Volvo") val map = mapOf("firstName" to "John", "lastName" to "Doe") The above seems a really strange decision for a "new" language - why would you not just use the most common structure, being JSON?
- cytzol 8y agoJSON doesn’t support non-String keys, for one thing.
- singularity2001 8y agoJS does
- jscissr 8y agoActually no, all keys are strings in JS, and if you use something that isn't a string as a key, it is converted to a string (unless you meant Maps[1], which don't use object notation). [1]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Map https://developer.mozilla.org/docs/Web/JavaScript/Reference/...
- jscissr 8y agoOk, I forgot Symbol, so you were correct.
- singularity2001 8y agoEvidence that designers of Kotlin have no taste
- kllrnohj 8y agoPerhaps worth noting that none of that is langauge syntax, it's library syntax. mapOf takes vararg pairs: Pair<K, V>, and then the 'to' operator is an infix function that makes a Pair<K,V>. So you could trivially do your own listOf or mapOf that creates whatever data structure you want, whereas languages with special syntax for this tend to hardcode the result of it. That's a valid choice, sure, but just that there are tradeoffs here rather than it being obviously better one way or the other.
- tabs_masterrace 8y agoMan i gotta disagree with almost all points in this article. Name-Shadowing is confusing? Should be common sense to not have multiple variables with the same name in the same scope. Optionals are ugly in Java-Interop, so we decided to just use Java instead. Great reasoning.
- choward 8y ago> Name-Shadowing is confusing? Should be common sense to not have multiple variables with the same name in the same scope. You're saying name-shadowing isn't confusing because it should be common sense not to use it? Then why not just enforce that in the language?
- apatrida 8y agoThere is an issue in the Kotlin issue tracker to be able to turn warnings into errors, and it was created by a Kotlin team member specifically for this name-shadowing case. So, you will be able to turn any specific warning into an error once this is implemented. Which is nice, I like 0 warnings.
- Rapzid 8y agoThe biggest red flag IMHO with Kotlin is the teams disinterest in supporting the language server protocol. They are taking a very insular approach to the ecosystem just like Microsoft used to with .Net. The world has moved on a bit from that mindset, but they are completely happy with coupling the experience to their companies IDE...
- jrs95 8y agoEven if they did support it, you'd be getting a much worse experience with other tools than just using IntelliJ anyways. Given that they've gone through the trouble to write an entire programming language & the amount of value it provides, I really don't mind them trying to use it to push people towards their products a bit. Especially since both IntelliJ Community and the Kotlin plugin are open source.
- ysleepy 8y agoI agree, all the language server stuff is a win for the scripting and IDE-less ecosystems, but for languages with proper IDE support it is such a monumental step back. So much that nobody working with the existing tooling/IDEs will invest time to implement a language server backend.
- Rapzid 8y agoI've got a couple languages in mind that have "proper IDE" support, and the vscode experience with them is pretty fantastic as well, even if not perfect.
- ysleepy 8y agoCould you name one or two? By proper IDE support, I mean support for advanced and precise refactoring, build integration, debugging and so on. Dot autocomplete is only a litte part of it.
- Rapzid 8y ago"much worse" sounds a bit hyperbolic. Lets assume it would be not as good though, at least at first. It's a little conceited for them to believe they are going to be the best at all things to all people. Letting it out of the nest has greater future potential for wider integration and features in the long run. Maybe Eclipse project or Redhat will eventually do the right by the language.. I don't mind them doing this either. I just find the thinking outmoded, and I also don't mind just not using Kotlin. And to clarify, it's not just the decision to not support language server protocol at this time; it's their reaction to the mere suggestion of it. The language steering is too coupled to the biz IMHO. For what it's worth, I feel the same way about F# and the Visual F# Power Tools team and is the prior experience that raises the red flag.
- V-2 8y ago"Kotlin changed the extends keyword into the : operator, which is already used to separate variable name from its type. Back to C++ syntax? For me it’s confusing." Not only C++; C# also. It's not very hard to confuse the author, is it :) I understand it's different from Java he's used to, but that doesn't mean one can hold every such difference against Kotlin. Not being Java isn't in and of itself a fault of a language. Why is ":" problematic exactly? It's more concise. It's true that this gives ":" more than one meaning, but it's so clearly context-dependent I can't really see how it could cause confusion when coding. An example would help. (Ruby uses "<" to denote class inheritance - by some miracle Ruby devs manage to get over the fact that "<" is also an arithmetic operator :) )
- hellofunk 8y agoAnd that’s not even how C++ uses the colon!
- Sir_Substance 8y ago>Why is ":" problematic exactly? It's more concise. Anyone, including non-java programmers, can make an educated guess at what the "extends" keyword does to a java class. The colon operator is contextless. Unless someone tells you or you've coded in c++/c#, you can't know for sure what it means without googling it. Here's a case in point, my biggest bugbear with the nim documentation. When you first see nim code, you're gonna see the '@' operator pretty much immediately. You're going to wonder what it does, and google "nim @ operator". You'll then remember that googling symbols doesn't work very well, and google "nim at-symbol operator". Sooner or later, you'll find your way here: https://nim-lang.org/docs/manual.html#lexical-analysis-operators https://nim-lang.org/docs/manual.html#lexical-analysis-opera... The nim documentation helpfully says "Yes, the @ symbol is an operator". So what does the @ operator do? It's a mystery, go fuck yourself, errr I mean figure it out for yourself! If you ignore the mystery and move on with your learning you'll come back to it via the key word "seq" within about 10 minutes, but there's no easy way to search for it if you don't know that, and by the way what a frivolous waste of time. Shorthand symbols are worth having, but they should be used only in cases where the coding speed benefit outweighs the readability loss. If you had to write "extends" in kotlin instead of use a colon, how often would you be doing it? If it's more infrequent than once every 2 minutes I would argue that "extends" is better because it's in natural language, and thus easier on average for new kotlin developers to understand /regardless of background/.
- singularity2001 8y agoTo add to the authors list: time kotlinc Hi.kt user 4.5s !! (OK IN IDE on second run) trailing comma not allowed no python like package manager. import mail? no a = b = 1 // assignments are not expressions
- tathougies 8y agoAssignment being an expression is a dangerous misfeature in a language with mutable data. It is a good thing to get rid of them, and all reasonable compilers already throw a warning if a program relies on this behavior.
- xfer 8y agoassignment being an expression is not a dangerous misfeature; what the assignment expression evaluates to is important to consider(see ocaml/rust).
- oblio 8y agoNo package manager? You can use Maven, Gradle, whatever.
- ender7 8y agoI suspect type declaration order is a deeply personal preference. I hate C-style type-first declarations with a passion; type-last declarations have always felt more readable and natural to me.
- bcoates 8y agoI agree (that it's personal) but attributes-first and types-last in the same language is just nuts. That's why the kafkaTemplate function declaration is so ugly.
- alexeiz 8y agoI read those reasons they switched back to Java, and frankly, I like how things are done in Kotlin better than Java (unless it's identical). I'm not sure what the complaining is about. Looks like the main reason is they don't want to learn a new language.
- iddan 8y agoThis is a dumb article
- xchaotic 8y agoOk, so, assuming that all the things he mentioned are just nitpicky, what's the upside of Kotlin over Java 10? Lots of people would need adequate training, perhaps some new tools and rewrites. There needs to be a serious upside to get a mainstream company to a niche language.
- suyash 8y agoIt's not worth it, Java is getting better and more feature rich that improves programmer productivity. Kotlin is like a cool JavaScript library in the market.
- wasyl 8y agoMajor thing for Android developers is that the adoption of new Android versions is so slow, we're really stuck with Java 6/7 features. While backend can happily update to Java 15 on their own terms, we're limited by Android OEMs to provide updates to their phones. This is one of the reasons Kotlin is so popular with Android -- you get new Kotlin features when you want to, not when all of your app users buy new hardware (and good luck convincing business people to ditch 10% of the users on old API versions). While we get support for Java 8 (but not 9 or 10) language features via special tool, we still don't have access to Java 8+ APIs.
- peter303 8y agoI could be wrong, but thought a motivation for Kotlin is to get Java-8 and Java-10 power into versions of Android that cant use those levels yet.
- dagenix 8y agoIt seems like the author likes Java quite a bit. Kotlin, not being Java, seems to be his primary complaint. Take his first point - Kotlin allows variable shadowing. He doesn't say why it's bad or how it caused a bug, he just says that Java doesn't support it and he doesn't like it. Everyone is entitled to their opponion. But, this article doesn't seem to have much of a point. It would be like if I wrote and article about how I preferred cherry popsicles to grape popsicles. That my opponion and I'm entitled to it. But, I don't know why I'd want to be publish a blog post about it or why anyone else should read it or care.
- jillesvangurp 8y agoI've been spending some quality time with Kotlin the past few weeks and have been converting some of our Java code. The fact that this is easy and that you can mix java and kotlin code makes the transition very easy. Mostly the transition has been pretty smooth and I'm liking this enough that I don't really care about switching back to Java at this point. For reference, I've been doing Java since 1996. It's been my primary language for most of that period. Kotlin is a big deal for me and I'm not doing this on a whim. I've been following Kotlin progress for years before deciding to switch. What this author seems to get hung up on is that not all Java idioms port well to Kotlin. Some of his criticism is fair, e.g. the companion object thing is indeed a bit of a kludge. No matter how the Kotlin people spin it, the fact is that it is coming up frequently in forums, stackoverflow, etc. It's clearly a problem and it is entirely fixable. So, it would be helpful if they added proper support for static fields and methods without requiring ugly annotations and offer full back and forward compatibility to Java. The JVM supports it and clearly their compiler supports it if you get insistent with the right amount of ugly annotations and verbosity. So, I see no sound technical reason for not doing this. However, it is not a show stopper. Companion object with some functions, add @JvmStatic annotations, problem solved. There definitely are some more ugly corners in the language but mostly is clearly better than Java. And just because it's there doesn't have to mean you have to use all of it all the time. Adding question marks all over the place doesn't look like idiomatic Kotlin to me. Better to just have null safe code and not having to deal with nulls. Also, java.lang.Optional works just fine in Kotlin and kotlin probably adds some useful extension methods. Otherwise, sane generics, extension functions, flexible property definition, data classes, no difference between boxed/unboxed primitive types, etc. All great stuff and kind of refreshing after dealing with Java's broken type system for years. Add to that the upcoming support for co-routines, javascript (you can do react apps in kotlin) and native compilation, and the endorsement for android development, awesome tool support, etc. and you have a great language that is ready for just about anything. So, mostly good stuff to say about Kotlin. As for Scala/Groovy, I never really cared for either. I'd say Kotlin's strength is that it cherry picks a few popular things from those and other languages without really trying to be those languages. It's seems to be succeeding where those languages failed in trying to get Java developers to abandon Java. Java 10 is a nice incremental change but doesn't really address most of the things that Kotlin fixes.
- cesarb 8y agoThe author wrote a lot about nullable types, but didn't mention a very useful feature of the Kotlin compiler: it understands several (IIRC, more than a dozen) third-party Java nullability annotations. It treats Java types annotated with @NotNull or equivalent as T, types annotated with @Nullable as T?, and only types with neither are treated as T!. And on the other direction, the bytecode generated by the Kotlin compiler also has these Java nullability annotations (it uses the org.jetbrains annotations package), so for instance Dagger2 can know that a type is nullable from the presence of the @Nullable annotation. If your code already uses @NotNull/@Nullable everywhere, introducing Kotlin to your code base becomes easier. As a bonus, IDEs can sometimes use these to warn you of potential null pointer mistakes in your code.
- kevinr 8y agoThis is a really useful article. What I really want is Java-minus-Oracle, and it sounded from some of the chatter around Kotlin like it might be that, but it seems what I really want is Groovy.
- lokedhs 8y agoWhen I saw the first compliant he had, about variable shadowing, I was asking myself: This guy works for Allegro and he doesn't understand shadowing? It's used all the time in Lisp. Then I realised it's a different Allegro. Another case where knowing Lisp makes you a better programmer, no matter the language you use.
- microsuck 8y agoI understand there are a few valid reasons not to use Kotlin, but this article is blown up with a lot of trash arguments. > ... so you need to scroll Maybe you should indent your functions properly? > How much time do you need to find the return type of this method? 0 seconds. It's literally right below... > Simply, the neat syntax for collection literals is what you expect from a modern programming language, especially if it’s created from scratch. Then don't compare statically typed languages with Python or JavaScript > First, you need to type and read this noisy colon between names and types How much time do you spend on typing and reading semicolons? > Back to C++ syntax? For me it’s confusing. Are you only able to write Java? Is it really that hard for a veteran to switch between languages?
- anad7 8y agoI've said it earlier, I am saying it again. "Kotlin enthusiasts or rather PR representatives cannot stomach criticism", this is quite visible on the blog itself and here on HNews. Consult with your CEO, CTO and/or Director of Engineering before switching to Kotlin, there may be things you might not be aware of, think 20 years ahead and think objectively about the pros/cons before heeding to advice of the enthusiasts, they won't be there to help you when your app behaves unexpectedly, or if your tech debt increases or when you are unable to find people willing to work with your messed up code base, remember there's no reverse Kotlin to Java converter built into IntelliJ. My advice is to sit it out and wait for Java to evolve, which shouldn't be far away, in the meanwhile enjoy writing your code in Java in which you have your actual work experience(8+ years in my case), which has books and resources dedicated to help you understand the pitfalls, design patterns and every trick out there since 22+ years of its existence. Besides I would recommend developers to not waste their time on a language which piggy backs on JVM, many other languages which did that or are doing it have failed, Kotlin won't be an exception. Instead use Java to learn and write complicated Data Structures and Algorithms and learn technologies like Machine Learning, Neural Networks and AI etc to increase your job prospects.
- marcodave 8y agoI agree, very well spoken!
- apatrida 8y agoI'm a Kotlin enthusiast (since 2013) who has also used Java since 1995 and was quite the enthusiast for many of those years, tracking the progress of Java in detail since inception. I've contributed to both languages. Just so you are aware of my background being strong in both. Now back to this blog post and enthusiastic defence of Kotlin: This blog post wasn't a criticism, it was instead under-informed and misleading. You will indeed attract the attention of enthusiasts if you take an authoratative viewpoint against the thing those enthusiasts care about, publish it publically, promote it to the whole community, and use bad (or no) evidence in the process. Who wouldn't stand up and protect something they care about in that circumstance? By the way, when we were helping to create Java at Borland, we were told many things like you just said: "it will fail", "the CEO/CTO/CIO won't want it", "we can't take the risk", "in 20 years it will be gone", "it's just a toy and not for the enterprise", "dancing Duke is all it can do", "it will fail like the others, Java is no exception", "no real application will be written in it", "it can't do server-side", "stick with C++", "stick with Delphi", "stick with VBA", "stick with PHP" So obviously the prognosticators and non-enthusiasts were wrong. What makes you better are reading the future than they were? Is Google wrong when backing Kotlin? Is JetBrains? Is Square? Is the Spring Team? Is the Gradle team? Is the JUNIT team? Or are these some of the same people who made the right call on Java way back in 1995-2000 as well? In fact Java would have failed had the enthusiasts not carried it through tough times, shaped it up, improved performance, fixed critical bugs, cleaned up bad specifications, and showcased it to the world. Because of enthusiasts, you have Java. So let the enthusiasts do their work of defending a good thing against people that just don't yet see the light (or maybe never will care to, so bet it).
- V-2 8y agoThe particularly funny thing is how the blog admin - the author himself? - censors comments not to their liking, marking them as spam : ) They clearly are a bit touchy. Below, the comment he's deleted twice; you be the judge :) (I wouldn't normally repost, but the first time round I erroneously assumed it was due to including a link in it; apparently not). ---- The article has been commented extensively on Hacker News. I'm not pasting the link, as this gets my comment marked as "spam" (go figure), but it's trivial to find it with very basic google-fu. Now, while I don't approve of the unneccessarily biting tone of some of the remarks posted there, I think it's been demonstrated convincingly that a large share of this Kotlin critique is highly dubious at least. I believe that in general the longer we work, the less eager we are to learn new stuff, and we become more set in our old ways. It's only natural and human, but often we go to great trouble only to rationalize this attitude somehow. And that's what should set your alarm bells ringing. For the sake of your own development, nobody else's. Publicly criticizing a language without even knowing its standard library (as evidenced by the "Integer.tryParse" example, which indeed runs into troubles, but only because it's outright wrong - see the comments on Hacker News for more details) seems premature, especially for a veteran programmer like the author. ---- To me there are two takeways here; more important than Kotlin. Two factors that inhibit our professional development, especially in the long run, once we're "seniors" already. The first is what I already pointed out in the blacklisted comment, above. The other is sort of self-evident now; and that's the ego problem. Not only we become conservative over time; we also develop an oversensitive ego, and conversely, an allergy to being corrected. I really hope I won't fall into this trap myself... I sure as hell exhibit similar signs now and then
- apatrida 8y agoThat forum (disqus) is very very bad at spam detection. And hates links in posts.
- madmulita 8y agoCan't comment on the java vs kotlin thing, but what 'microservice' takes months to write by a team?
- apatrida 8y agoA comment I posted on that blog post, that likes to keep going to spam box. 1. Name shadowing is a compiler warning. It is good to pay attention and clear all warnings by resolving the issues. It isn't a secret when you name shadow, and a developer I would hope would pay enough attention to not do it on accident. I've used Kotlin since 2013 and don't think I've shadowed a name even one time on accident. There is an issue in the Kotlin tracker to allow turning specific warnings into errors, this would give you the behaviour you want once added. 2. Kotlin type inference is the best out there, nothing compares in accuracy and scope. You aren't getting the same thing from Java 10 that Kotlin has by far. 3. Compile time null safety is accurate from Java libraries if they inform as to their null safety, for example there are many libraries that use `@NotNull ` and `@Nullable ` annotations and Kotlin respects and enforces those. They also handle this for JDK calls so that all standard library calls are correctly interpreted. You can fix your own custom Java libraries which also helps with Java static analysis. And eventually you'll use more and more calls to your own Kotlin code or to Kotlin libraries and you'll really be glad all of this null safety is there and part of the compiler. 4. Class literals are many times not used in Kotlin API design. Instead you as an API designer would just write an extension function that reifies the generic parameter and auto infers the class literal. Or you can do it yourself to extend any API you wish. You will only do that once and then enjoy the magic a thousand times after. There are actually modules for things like Jackson and GSON that do this already. So then the syntax is better than the Java because you don't have that parameter at all (which is type erased whereas reifying the full generic type is not). Here is an example of Java vs. Kotlin using Jackson object mapper in the same use case you were demonstrating: Java: final MyStateObject state = mapper.readValue(json, MyStateObject.class) // type erased, which sometimes is ok final List<MyStateObject> states = mapper.readValue(json, new TypeReference<List<MyStateObject>>()); // not type erased Kotlin: val state: MyStateObject = mapper.readValue(json) // not type erased val states: List<MyStateObject> = mapper.readValue(json) // not type erased Alternative Kotlin: val state = mapper.readValue<MyStateObject>(json) // not type erased val states = mapper.readValue<List<MyStateObject>>(json) // not type erased Isn't type inference wonderful? Especially with reified types making API's like this possible. 5. Type declarations in the form of `name: Type ` are by design to allow for unambiguous syntax which keeps the language smaller and leaner than the C style typing which cannot be used everywhere without extra cruft to delimit what is going on. Plus this is more readable when scanning variable declarations since they are at a fixed position from the left instead of a random position on the right. Here are some good reading for you that let you know the Java style `Type varName ` is actually the less common across languages: https://softwareengineering.stackexchange.com/a/311739/208884 https://softwareengineering.stackexchange.com/a/311739/20888... and then this post about how it interferes with higher level concepts in language to have it backwards as Java does: https://softwareengineering.stackexchange.com/a/311730/208884 https://softwareengineering.stackexchange.com/a/311730/20888... 6. Companion objects are there so they can be extended, including with extension functions. You can easily do things like logging using other models and delegates instead of adding a companion object. Your logger system likely caches the logger by the way so having a reference on the object is not a huge item to add. You can also have a `main()` as a top level function and is not required to be in a class which probably makes more sense for a main anyway. 7. Collection literals are not present in Kotlin because in the JVM developers are more specific about the exact type of collection they wish to construct, and there are simple helper functions which make things clearer. The `: ` being used for maps would overuse that symbol and cause it to have different meanings (I think you complained about two uses of `: ` then you later suggest a third). What is wrong with `to ` for creating a pair which is used to create the map? it is an extension function, highly readable, and you can actually make your own with some other name (other than `: `) `to ` isn't part of the language syntax nor forced upon you. The Groovy syntax is bad because it looks like you are declaring a list/array. The other syntaxes don't say whether the maps are readonly or mutable and that is important in Kotlin. It is a carefully thought through issue. 8. Maybe? is not needed as much due to alternatives and null safety. But, there is the JDK Optional which you are showing and can just as easily be used by Kotlin as well. And more "native" versions in open-source Kotlin libraries. Kotlin just doesn't have one in its standard library, nor does it need one. I personally dislike API designs that force optionals on me for everything, so I'm glad Kotlin doesn't. For your example code, why are you using Optional for this case of `parseAndInc `? Kotlin has the `?. ` safe operator to continue a chain when not null, and the `?: ` Elvis operator to provide a fallback on null values. Any operator like `+ ` is also available from its operator function (i.e. `plus() `) or in this case simply `inc() `. Therefore: Kotlin: fun parseAndInc(possibleNumber: String?) = possibleNumber?.toIntOrNull()?.inc() ?: 0 Yet you can also write the same Kotlin code as your Java example (and slightly less typing): Also Kotlin: fun parseAndInc(number: String): Int { return Optional.ofNullable(number) .map(Integer::parseInt) .map { it + 1 } .orElse(0) } Compared to your Java: public int parseAndInc(String number) { return Optional.ofNullable(number) .map(Integer::parseInt) .map(it -> it + 1) .orElse(0); } Please remember that everything you can do in Java you can do in Kotlin including using all those Java classes you are familiar with. But, you can also learn idiomatic Kotlin and write it differently. This is one of the reasons the learning curve is very low. 9. Data classes, so you aren't complaining here or are you? You can't inherit the equivalent in Java either, you would have to rewrite `equals `, `hashCode `, `toString ` and more if you did that and each would need to be customized. So Kotlin has the same issue, inheritance of these is dangerous because manual decisions need to be made in order to do so. You CAN inherit from another class, and you could use composition and interfaces instead. Data classes are a life saver in code, covering a huge number of cases without all the boilerplate of manually coded JavaBeans. 10. Final classes by default are a good thing, and this has been heavily researched and talked about in the Java community as a best practice. Some old Java libraries do not know how to handle this because they don't expect it to be a problem. But those libraries are changing, and complier plugins for these libraries already help you out with 0 effort in changing code. Plus, newer libraries deal with this without problems. If you want to modernize, you have to modernize and not just expect new things to continue with allowing bad habits because some legacy code doesn't do things elegantly. I can't think of any blocking case related to this. It was well known, well covered, and is a non-issue. 11. Shallow learning curve. Kotlin is small language, consistent, and elegant. It does NOT have a steep learning curve. It is no where near Scala in terms of effort and complexity, yet you lump it in there anyway. Plus, isn't it worth learning a language over a week that'll save you 40-50% the lines of code, automatically eliminate whole categories of bugs you write, be many times more readable and maintainable? Kotlin is a few days to a week for an ex Java developer to write reasonable code, and then later they'll write more elegant code over time. And about Spock vs. Spek: You don't have to pick either/or, since you can use Spock from Kotin too like any other Java library.