15 ms·
Problems with Kotlin
- ChicagoDave 10y agoThe impedance mismatch with its intended target (mainly Java) is enough to make Kotlin a complete waste of time.
- norswap 10y agoHow so? In my experience Kotlin works nicely with Java.
- ChicagoDave 10y agoI found it easier to just write Java.
- gigatexal 10y agoThis. But competition is good. And here's to Java 9 and eventually 10 and ...
- pjmlp 10y agoOn Android is the only sane path out of the Android Java fork, stale in Java 6, with cherry picked features from Java 7 and 8.
- kcorbitt 10y agoThis is a reasonable critique of other JVM-hosted languages I've worked with (Clojure and JRuby), but the external interface of classes and methods in Kotlin are completely compatible with Java by design. And in practice, it's very easy to write mixed Java/Kotlin projects where you don't necessarily know (or care) whether the class you just imported was written in one or the other -- it just works how you'd expect. I'd be interested in specific examples where you found any impedance mismatch at all.
- didibus 10y agoMaybe the closer similarity leads to more confusion and mix up. Clojure works pretty well with Java, but is so different, you'll rarely get things mixed up between the two. Just a guess, since I'm not the original commenter.
- norswap 10y agoThe post hits a lot of real pain point when working with Kotlin. In particular, nullable types seem like a good idea (I thought so as well) but in practice are a real PITA. That's most acute when defining fields, where non-nullable fields have to be initialized directly. JetBrains themselves realized it was painful, and so we have `lateinit` to define mutable non-nullable fields that can be initialized later. But sometimes it really is nice to be able to check if a field has already been initialized, which you can't do here. I must now have spent an order of magnitude time dealing with the initialization of non-nullable fields than I ever did tracking null pointer exceptions. That being said, Kotlin is still a net improvement over coding in Java. In fact, if you're going for a large codebases, I think it's one of the most tractable languages out there (C# is a strong contender as well).
- snuxoll 10y ago> In particular, nullable types seem like a good idea (I thought so as well) but in practice are a real PITA. That's most acute when defining fields, where non-nullable fields have to be initialized directly. > JetBrains themselves realized it was painful, and so we have `lateinit` to define mutable non-nullable fields that can be initialized later. But sometimes it really is nice to be able to check if a field has already been initialized, which you can't do here. I'm curious, where have you found the need for lateinit? Forcing initialization of non-nullable types has always seemed like a great idea to me, and learning to deal with it in Kotlin has made picking up Rust a lot easier.
- dimillian 10y agoJSON and reflection, you know you gonna get a value once you'll have instantiated your object from a JSON description. So my var are lateninit because I don't need a ? or !!
- snuxoll 10y agoInitialize them with default values, then? Or if you're using Jackson there is a module from FasterXML that provides support for Kotlin data classes. lateinit is a crutch to get things working, not something you want to use long-term.
- realharo 10y agoThe part about maps is wrong, you can write them like val myMap = mapOf( "A" to 10, "B" to 20 ) etc. Also, regarding that final sentence about matrices, that sounds like a perfect use case for type aliases.
- plandis 10y agoFix your website on mobile. The width of the ads is larger than the actual content.
- softawre 10y agoIt's not just mobile, it's that way on desktops when you want to view it at a small width. And if I max the screen... I still can't see all of the width of the code samples.
- andreygrehov 10y agoInteresting. What phone are you on? Could be because of a flexbox.
- dpkirchner 10y agoNexus 9 tablet here. While in portrait the content takes up what I'd estimate to be 40% of the horizontal space, with the remainder used for ads and whitespace. The code samples are basically unreadable (requiring horizontal scrolling inside the div). It's not so bad in landscape, however.
- ga2arch 10y ago[deleted]
- deleted 10y ago[deleted]
- gmarx 10y agoHere is a meta-comment that may seem irrelevant but I truly wonder about this odd tick of internet writing. The title should be "Kotlin Sucks" or "Why I think Kotlin Sucks". The article doesn't say anything about the circumstances that lead to the sucking (e.g. the main developer suffered a serious brain injury midway through the project) he just lists and details aspects of it that suck. This incorrect, misleading use of the word "why" in the titles of internet articles is so common I must ask, "why?"
- sctb 10y agoYou've convinced me that "Why" in this title is a form of a clickbait—perhaps to appeal to our craving for causality—so we've removed it. Thanks!
- gmarx 10y agoWow. You're welcome and thanks! I don't know why it should make me feel good that a stranger on the internet took action in response to my comment, but it does
- TelmoMenezes 10y agoMy theory is that it's a mix of two things: - Some guru years ago must have come up with some over-simplistic silver bullet such as: "if you claim to explain why something is the case in the title, everyone will be drawn in by the potential value you provide and the self-confidence you project". Or some shit like that (case in point - list "articles"); - Copying the linguistic mannerisms of some "in-crowd" makes you feel like you belong. This site is full of ticks like that if you pay attention.
- abiox 10y ago> he just lists and details aspects of it that suck it's possession of said aspects aren't why it sucks?
- simias 10y agoI've never used Kotlin (and I haven't touched Java in more than a decade) so I can't really comment on the usability issues of the language. That being said I think he completely misses the point of the nullable types and he's fighting them because he's treating them like "void * " instead of trying to understand how to work with them. In particular, to his: > Where does this absolutely crazy confidence of a compiler that each character of my program is an element of multithread concurrency come from? I'd reply: why would the compiler have this absolutely crazy confidence that a particular character of your program isn't an element of a multithread concurrency? Why do you want your compiler to make assumptions about your code if it's not able to enforce them? I don't know what's the right way to write what he means in Kotlin but in Rust it'd be something like: match (value) { Some(v) => v, None => 0 } Or alternatively: value.unwrap_or(0) Which are both safe and, in my opinion, clearer than the proposed code in TFA. I would assume that Kotlin has a similar syntax for that use case? That being said I can imagine that having to interface with Java (which doesn't share the same "mindset") might be frustrating. It helps when all the language and its libraries are designed from the ground up around a certain paradigm.
- algesten 10y agoI agree. I used to argue like the author, that null is a thing in computing and I just had to deal with it. But after spending some time in Rust and Swift, I learnt a whole new way of thinking about it. The killer combination is: no null + immutable I've taken this to javascript, and it is so much better. Just don't accept null values anywhere in the model code, and suddenly writing view code is super easy. No more endless if-cases or ternary to deal with nulls.
- gagege 10y agoYes. I usually refer to them as "optional" values, rather than "nullable" values. Something should only be null if it is truly optional to the class, view or whatever, which is a pretty rare thing. If a class requires a certain value to be able to do it's work, and that value is missing (null), why was the class even instantiated? That should be a big no-no.
- 10y ago
- Nycto 10y agoI'm a huge fan of Kotlin. I think the author just doesn't understand the niche it hits. My team has a significant investment in the JVM. I despise working in Java because of how heavy it is to write. I like Scala, but the team I'm on finds it too complicated. Clojure is out because nobody on the team wants to write lisp. And Groovy doesn't have types. We looked at Ceylon, too, but at the time we hit a lot of compiler issues (if I remember correctly). So where does that leave us? There are likely other languages we could choose that target the JVM, but the pragmatist in me says I don't want to stray too far off the beaten path for this. Is Kotlin perfect? No. But is it a better developer experience than Java? Oh hell yes.
- lmm 10y agoWhat did you struggle with in Scala? Anything you could write in Kotlin you can write in Scala with the same structure. Scala has some extra constructs that can save you a lot of code a lot of the time, but you don't have to use them if you don't want to. There are horribly incomprehensible libraries available in Scala and there aren't any for Kotlin yet, but I think that's just a function of the fact that Kotlin's so much less mature all-round, and again you don't have to use them.
- veli_joza 10y agoThe "just don't use those parts of language" argument was also used a lot for C++. I just don't buy it. You are not in sole control of your code base. You share it with your colleagues who are on different skill levels. You are drawn into community gathered around the language and you need to use, debug, and sometimes contribute to other people's code. Just fencing off some common language features isn't going to cut it. It's better to select tools that are well suited to problem at hand, at right level of abstraction and of manageable complexity to your team. Even if that means less features and more ground work.
- lmm 10y agoI agree with you as far as C++ goes. I think the difference is that the things Scala adds respect the rest of the rules of the language. If you introduce exceptions in C++, everyone working on any line of the codebase needs to understand exception-safety. If you introduce RAII you have to enforce it on every constructor, and since constructors can fail you have to introduce exceptions. If you introduce templates you have to use RAII for all your types in case they're used in a template. In Scala if you use a higher-kinded type it works exactly as you'd expect (indeed I'd argue that the absence of higher-kinded types is equally confusing - why can't I use List as a type parameter in Kotlin?) - a method or type that uses HKT acts like any other method or type. If you have a function whose implementation uses a pattern match it might make it confusing to read that function, but to any caller from outside that function still conforms to its signature and still makes sense. If your colleague writes a Profunctor instance for one of their types and litters your code with ^>> calls that's probably annoying (and should probably fail code review), but ultimately it's just a plain old function call that you can click through to in your IDE and see what it's doing and whether it makes sense.
- ghostc0der 10y ago"Actually, I wouldn’t care about for if there was an alternative. But there isn’t one." Learn the collections library. https://kotlinlang.org/docs/reference/collections.html https://kotlinlang.org/docs/reference/collections.html All loops can be written in terms of them. Also because of inlining they have have the same runtime costs as hand written for loops. "Smart cast to ‘Int’ is impossible, because ‘value’ is a mutable property that could have been changed by this time" Smart casts only work on immutable values because of concurrency. If the variable hast to be mutable use ?.let { ... } instead of smart casts. What's wrong with two exclamation points? If you're using it you are probably doing something wrong anyway. When getting a type from Java that hasn't been annotated as @NonNull or @Nullable it is regarded a platform type. This means it's programmers responsibility to check if it can be null. Same as in Java or any other language that doesn't have nullable types. Assignment is not an expression. We've written 20K of production Kotlin code without this ever being a useful convention. Assignment being an expresssion is layover from the C family of languages. If you really want C's syntax and semantics, go write C. The ?: operator is great when chaining a bunch of operations all of which could return a null which we want to convert to a default. Here is an example: claimData?.claimTimeMinutes?.toLong() ?: 5L Generics in Kotlin have the same issues as Java because of type erasure. It does offer a few improvements with the use of reified type variables. Lastly, if you want to have descriptive structures use data classes. This guy just wants to program in C. If it's not C it's crap according to the article.
- pyre 10y ago> Assignment is not an expression. We've written 20K of production Kotlin code without this ever being a useful convention. Assignment being an expresssion is layover from the C family of languages. If you really want C's syntax and semantics, go write C. Python doesn't treat assignment as an expression. E.g. I can't do: if a = 1: pass or def c(): return a = 1 or: a = lambda c: c.x = 1 But I can still do: a = b = c = 2 to set multiple variables at the same time.
- simias 10y agoThat looks rather inconsistent to me. Isn't the last expression equivalent to a = (b = (c = 2)), and if not why?
- relics443 10y agoI'm not sure how "tongue in cheek" this article was supposed to be, but most of his issues with the problem can be solved by buying into the language. For: Not sure what he's upset about, but there are many options in the standard library. I almost never use the language construct for it, and I'm very happy with it. Nullable: I never expected nullable to completely save me from all issues. It has the same function as the @Nullable and @NotNull annotations (and all the other variants). It gives you a simpler way to reason about nullability, and forces you to respond to it; you can't just ignore it. Smart cast on mutable I get that this sucks, but they can't show it to happen. Yes, the chances are small, but there could be concurrency issues. They have to account for that, and can't tell if your code is multi threaded or not. Most of the time his issue can be solved with scoping, using ?.let or ?.apply Java Nullability What do you want from them? They have no ability whatsoever to control this. Either get annotations in the Java code if you can modify it (which is a good idea anyways), or wrap it and provide nullability information. Assignment is not an expression He got it. It's too protect against if(v=v). I know he makes a joke about automatic type casting, but if you're not assigning the result to anything, the logic in the if will still fail. Elvis operator I assume they removed Javas ternary operator to not get confused with the Elvis operator. ¯\_(ツ)_/¯ I kind of agree with him here unless I'm missing something Automatic type casting Frustrating, but safe Type alias I'm fine with it for simple cases, didn't want to parse his problem. Generics I hear his gripe, but at the end of the day Kotlin generics are Java generics. If there are some potential bugs in the compiler, report them and move on. Structure syntax I assume he means list and map literals. I agree it would be nice. Not sure why they didn't include it.
- lmm 10y ago> What do you want from them? They have no ability whatsoever to control this. Either get annotations in the Java code if you can modify it (which is a good idea anyways), or wrap it and provide nullability information. What I want is consistency. In Scala optional is always safe and null is never safe, and that's true whether you're calling a Scala method or a Java method (even the most perverse Java libraries don't declare themselves as returning Optional<String> and then return null). In Kotlin null is safe some of the time and not safe other times, e.g. if you're passing it to a method it might be fine or might not.
- guelo 10y agoI'm just getting started with Kotlin so can't comment too deeply on its problems but here are a couple things that have already annoyed me. Kotlin is supposed to be less verbose but variable declarations and function signatures can get annoyingly long. //java String x; //kotlin var x : String? Also, the whole fad of all new languages putting the type after the name doesn't make sense to me. Where are the ints? Object objectThing; Object someOtherObjectThing; int thing; int someOtherThing; String stringThing; String someOtherStringThing; Much harder to find the ints in a long list of Kotlin fields: var objectThing:Any? var someOtherObjectThing:Any? var thing:Int? var someOtherThing:Int? var stringThing:String? var someOtherStringThing:String?
- johnfn 10y agoIn the question about ints, use any alignment editor plugin to align your colons.
- always_good 10y agoI'm not even convinced you should be doing that. I disagree with the idea that the Ints are hard to find in their post. That's just not the hard part of reading code, though it's a good example of a pointless micro-comment-benchmark.
- Jach 10y agoYes, they're easy to find here. They're even easier to find if the IDE supports coloring types. And even then, / or ctrl+f lets you quickly find what you know you're looking for.
- barrkel 10y agoPutting types after the variable is a fad that dates from the 60s - Pascal, and ML after it. Usually the name of something is more important than the type. In dynamically typed languages, the name is all you get, and it's enough for a lot of programmers to be perfectly productive.
- mathw 10y agoHonestly I started out thinking this article was satirical, and I'm not at all convinced it's not now, but it's a bit difficult to tell around the author's probably-non-native grasp of English. Everyone else seems to be treating it like it's serious though. Maybe I'm just too infused with the joy of Rust, Haskell and other such languages to think anything slightly hysterical-sounding about the utility of non-nullable types and the possibility of mutation by other threads can possibly be anything other than parody.
- jankotek 10y agoI think author would have a hearth attack from Scala. It does not even have a conditional loops :-)
- esarbe 10y agoIt does. https://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#while-loop-expressions https://www.scala-lang.org/files/archive/spec/2.11/06-expres...
- SomeCallMeTim 10y agoOK, this seems like a major fail on behalf of the Kotlin developer team: var value : Int? = null fun F() : Int { if ( value != null ) return 0 return value // error } Tracing value types through a function is a solved problem. Look at TypeScript: Almost the exact function above will work flawlessly. [1] Sure something in a JVM could be changed by another thread. But that would really be a bug no matter how you slice it. Doing type analysis like this seems like a minimal requirement for a modern language. [1] http://imgur.com/nxdN9vc http://imgur.com/nxdN9vc -- you can see that TypeScript can identify the remaining type. It works for optional null as well when strictNullChecks is enabled.
- pdpi 10y agoLook at the code carefully. The only way you can reach "return value" is if `value == null`, so the compiler complains with "Required Int, found Int?", because it (quite rightly!) can't prove that value is definitely not null Let's change it to var value : Int? = null fun F() : Int { if ( value == null ) return 0 return value // error } Now the compiler still complains, with a different error: "Smartcast to Int is impossible because value is a mutable property that could have been changed by this time". Right you are. val value : Int? = null fun F() : Int { if ( value == null ) return 0 return value } This version compiles fine because `value` is a constant (though I think the compiler should've complained about dead code. You can never reach `return value`.) fun F(value : Int? ) : Int { if ( value == null ) return 0 return value } This version also works fine.
- StefanKarpinski 10y agoIt's entirely unclear to me whether this is parody or not.
- taco_emoji 10y agoI really don't understand the complaint about `for` loops... is it just that you can implement the same functionality with a custom-made function? I don't really get what's wrong with the language having some syntactic sugar baked in. EDIT: should mention I don't know Kotlin so maybe there's something obvious I'm missing...
- nostrademons 10y agoI didn't understand his point either (and I know Kotlin pretty well), but since 1.1 for-loops are basically deprecated in user code and you'd use the forEach method on Iterables: collection.forEach { variable -> .... }
- vbezhenar 10y agoCould you elaborate, why they are deprecated, is there any sources? Actually I'm always wondering which form of "for" I should use and I always using language "for" because, well, it's part of language. I actually think that "for" will be enhanced in the future, e.g. including guards, nested loops, maps, etc, like Scala's version (or Haskell).
- akkartik 10y agoIn general, people complaining about languages really should be showing the results of their examples. Since a lot of programmers are interested in languages, requiring knowledge of a language in such a blog post is hamstringing yourself by restricting your readership. Tell us what the result would be, precisely what line compiles and what throws an error.
- jorgemf 10y ago> This article is based on Your Language Sucks in the form of half a joke. First I though the article was being ironic, I end up understanding by thinking it is a completely a joke, not half a joke. Otherwise I do not understand: - why the author compares '?' with '?:' as they are completely different things - complains about automatic casting of class variables without understanding that the languages have threads ( "thread intersections occur on a very small size of the source code, but due to compiler’s repressive care about this feature" -> it is much better to crash your program randomly in production than a compiler error, ouh yeah!) - complains kotlin has a useless for that only saves some lines of code (like few lines of codes repeated for every for you write in the code, which it is a lot of code) - complains about the alias without understanding generics - complains about poor generics without understanding generics - etc 100% I wont hire him as a engineer
- amyjess 10y agoWhat convinced me that Kotlin wasn't for me was Andrey Breslav's reasoning why he insisted on sticking to Scala's confusing "Unit" terminology instead of terminology that actually makes sense [0]. > Why we don't call it "Void": because the word "void" means "nothing", and there's another type, Nothing, that means just "no value at all", i.e. the computation did not complete normally (looped forever or threw an exception). We could not afford the clash of meanings. And then he doubles down on it in the comments: > "Unit" just stands for "something that has only one value", it's a traditional name, comes from functional languages. I agree that this name is not very intuitive, but we failed to invent a better name. He managed to convince me that Kotlin's highest priority was pointless academic nitpicking, and that's not what I'm looking for in a language. What I wanted was a solid JVM language that avoids all the unnecessary boilerplate of Java without diving headfirst into a morass of functional programming like Scala. I want something that's 100% practicality and straightforwardness, not something that thinks trying to emulate higher math is something to aspire to. Well, I guess there's still Jython, even if it is stuck on an ancient version of Python... (edit: oh, and Groovy... forgot about it because most people just use it for Gradle scripting) [0] https://stackoverflow.com/questions/22654932/what-is-the-purpose-of-unit-returning-in-functions https://stackoverflow.com/questions/22654932/what-is-the-pur...
- hepta 10y agoThis seems like nitpicking as well. If the intention is that everything is an expression (that seems to be it, to me) then you have to have a Unit, no mater what you call it. I'd rather have a name that 3 academics know than override a distinct concept (Void) or make something entirely new.
- vorg 10y ago> Groovy... forgot about it because most people just use it for Gradle scripting You can use Kotlin for Gradle scripting as well since Gradle 3.0 released about 6 months ago. Given that Gradleware also said they're switching their preferred language for Gradle addons to Kotlin from that version onwards, I'm guessing the same will happen for build scripts some day.
- hota_mazi 10y agoYou know a language has reached mainstream when it starts getting "sucks" articles written about it.
- hota_mazi 10y ago> How can we protect ourselves from something that is beyond the language and is not controlled by it? There’s no way to do it. There are plenty of ways to do it. The most popular is probably to capture the Java nullability at the border when Java values enter Kotlin code. From that point on, your code is null correct and will never give you an NPE. > The Smart cast to ‘Int’ is impossible, because ‘value’ is a mutable property that could have been changed by this time error is driving me nuts. I want to kill someone or break something. Yeah, lash at the compiler for pointing out your code is incorrect, right? Easy solution: use a `val` (which should be your default anyway). Another solution, although less easy: write better code.
- deleted 10y ago[deleted]
- maxpert 10y agoReading the article I have thought twice and thrice about how to respond. Problem is every language can't be C/C++; it's like looking at LISP for first time and just diving into writing a blog ranting about it. Why does + comes before; hell = should have been assignment operator, why are things immutable and blah blah blah. It took me some time to develop taste, but all well engineered languages are tailored towards a mindset or problem-set. I might say few of points might be right here but language design is really really difficult and subjective topic. Try building the language yourself fixing stuff you just ranted about and I can guarantee you people ranting about the Frankenstein you will make.