8 ms·
I, personally, happen to like writing in Kotlin more than Java - with a lot of experience in both (though admittedly, all? the Java I wrote is in the pre-Stream
by t-writescode 2y ago
I, personally, happen to like writing in Kotlin more than Java - with a lot of experience in both (though admittedly, all? the Java I wrote is in the pre-Streams style).
I like:
* data class Foo(val theImplementationAndStyleOfDataClasses: String)
* elvis?.operator?.chaining
* the order of variable declaration (type afterward)
* how function pointers at the end of a method call can be auto-inserted as the next curly bracket
* how you can have fun foo() = returnValue; in one line.
* fun `method names that can have spaces - and dashes - in them`()
The preceding 3, combined, allow for:
@Test
fun `much easier testing`() = commonTestSetupWrapper {
// the code under test
}
* val immutable by default
While I agree that Kotlin has definitely helped push Java in the right direction; and I agree that it's probably not especially necessary to migrate 10MM lines of Java code to Kotlin, especially since they're fully interoperable, I definitely would prefer writing _new_ code in Kotlin over Java for the for-the-lazy devex improvements, if nothing else.
fwiw, my "good at it" programming history follows the lineage in historical order of:
* Java (8?? years of it including competition programming)
* C# (5+ years)
* Python (2016ish to current)
* Ruby (3-ish years, lots of Rails)
* Kotlin (2-3 years, through current - written over 40k lines of Kotlin in the last year, alone)
- 0cf8612b2e1e 2y ago`method names that can have spaces - and dashes - in them` Eugh, that is a turnoff. Maybe I have programmer Stockholm’s, but at least with a single connected word, I can always double click to select the token. Maybe, I might have wanted dashes at some point, but spaces seem like a step way too far.
- ditn 2y agoGenerally these are only used in test methods, which is fine. I've never seen anyone use them outside that.
- recursive 2y agoWhat benefit do they provide in testing scenarios? I've never written Kotlin, but from an outsider's perspective, it seems like a slim benefit, outweighed by the cost of the mere existence of this syntactical oddity in the language's grammar.
- t-writescode 2y agoWhen writing tests, you can name the methods more useful things, such as: class MyTestableClass { fun `methodName - when input does not parse to valid regex throw exception`() { } } It's pretty clear what is under test in a situation like that. That's basically the only situation I ever see it used in (and would code-smell the heck out of it if I saw it in other circumstances). People who are familiar with RSpec-style testing are very used to this sort of thing. describe MyTestableClass do context 'input parsing issues' do context 'when not valid regex' do it 'throws exception' do ... end end end end Anecdotally, I've also found that such style naming for tests allows me to write out the desired names for all the tests ahead of time more easily and then implement them. That happens to be my flow.
- codedokode 2y agoI like how tests are made in Python - you don't even need classes, just functions, and use a single assert keyword for everything. Also it's easy to parametrize them using decorators.
- t-writescode 2y agoParameterized tests are a huge, huge win, yeah. I am a big fan of them and look for how to do them in every test framework I use. RSpec was the weirdest for me; but NUnit and JUnit have been quite easy, and I'm not surprised at all they're easy in Python too (admittedly, I don't remember if I ever wrote them in that language).
- stickfigure 2y agoParameterized tests in Junit are basically the same as decorators: @ParameterizedTest @ValueSource(strings = {"first", "second"}) void fooGoesBar(String param) { ... } Also, once you get used to assertj, you'll never want single-assert again. It's fantastically useful to know (for example) not just that two lists aren't equal, but specifically what elements differ.
- thaumasiotes 2y ago> Maybe I have programmer Stockholm’s, but at least with a single connected word, I can always double click to select the token. If you're using anything that can do syntax coloring correctly, you can still do that.
- Freak_NL 2y agoWhile that is avoidable by sticking to a coding style, that horrid and unavoidable 'fun' instead of 'function' (or 'fn') just saps my will to work on such a codebase.
- t-writescode 2y agoThe best part about lots of languages being around is that you can pick the one that resonates most with you :)
- wiseowise 2y agoRight. You have selection of Kotlin and Kotlin in Android/Kotlin heavy company.
- coldtea 2y agoIf that's the case, it doesn't sound there was much will to work to begin with...
- int_19h 2y agoWhy do you hate fun so much?
- RedComet 2y agoAgreed. Obviously `func` wasn't going to happen because it is already so similar to Swift, but `fn` at least should be an option.
- aembleton 2y agoI like it for unit tests. Makes naming them easier
- coldtea 2y ago>Eugh, that is a turnoff. That's because you're too used to C/Algol style languages
- usrusr 2y agoAs others have said, I would not expectany any style guideline to tolerate those names outside of tests. But it's not entirely test-only: When you are dealing with code generation for schema defined in/for other languages, being able to just drop names in backticks and be done with it would be far less hassle than making up your own transformation and deciding between verbosity and safety from collisions.
- badsectoracula 2y ago> at least with a single connected word, I can always double click to select the token I'd expect an IDE for Kotlin to detect `stuff like this` and select the entire name. Considering Kotlin came from JetBrains, IDEs are most likely already in the Kotlin community's DNA. (i never wrote or anything related to Kotlin myself but i do appreciate IDEs helping with stuff like this)
- eptcyka 2y agoThis also means that JetBrains will never write a language server for Kotlin, locking you into their ecosystem.
- int_19h 2y agoIt doesn't lock you into their ecosystem given that other people can (and have) written language servers for Kotlin.
- eptcyka 2y agoWhich are not nearly as capable and will forever be catching up. For a better situation look at Apple’s sourcekit. I’d take kotlin over swift in less than a heartbeat if it was more open source than Swift. Which us a very low order.
- t-writescode 2y agoHow’s Apache 2? https://github.com/JetBrains/kotlin https://github.com/JetBrains/kotlin
- wiseowise 2y ago> Considering Kotlin came from JetBrains, IDEs are most likely already in the Kotlin community's DNA. Idea understands and performs dramatically better with Java.
- 2y ago
- wiseowise 2y agoName is wrapped in ``, so it’s not “true” use whatever you want. You also have to use `` on call site.
- paulddraper 2y agoThe better benefit is that you can use the right name for something instead of tiptoeing around reserved keywords.
- jeroenhd 2y agoThe feature isn't just about spaces. It's also how you'd work around interacting with JVM code that uses what would be Kotlin keywords. For instance, Java classes with a method named "is" or "val" can be called through val isBar = foo.`is`(bar) rather than needing to use reflection like you would to accomplish the same in Java. The Kotlin style guide basically says "never use this outside of test names" and some targets, such as old Android, don't even support the feature in test cases.
- yearolinuxdsktp 2y agoIf you use a good IDE it will select the whole method name. In general you would not use spaces for method names of anything that’s a shared/common use facility. They are best used to give test methods readable names. E.g. “test parallel writes are thread-safe”. And not “write with timeout.”
- NIckGeek 2y agofwiw in modern-Java they have data classes: record Foo(String theImplementationAndStyleOfDataClasses) {} The string is final. While sadly there is no elvis operator, the Optional type helps: evlis.map(e->e.operator).map(e->e.chaining) I still strongly dislike working in Java but Java 23 is a long way ahead of the Java 6 I first learnt Java with.
- ncallaway 2y agoI also really like conditionals like switches and ifs returning values.
- overhead4075 2y agoJava 14 introduced switch expressions. https://docs.oracle.com/en/java/javase/17/language/switch-expressions-and-statements.html https://docs.oracle.com/en/java/javase/17/language/switch-ex...
- bberrry 2y agotry statements being expressions is also especially lovely
- akoboldfrying 2y agoHonestly, none of those differences you listed seems especially compelling to me, except possibly for the ?. operator. What would be compelling: Array types that don't hate generics, or generic collection types that don't hate primitive types. Does Kotlin improve on Java at all here? It's such a pain having to remember this bonus complexity when all I want is a consistent way to manage a bunch of things. (I suspect not, as I think the limitations are at the JVM level, but I don't know.)
- t-writescode 2y agoOut of curiosity, what are you wanting that autoboxing doesn't resolve?
- kjeetgill 2y agoStripping out Maps/Lists with boxed keys and values is the first easy thing to do when perf tuning a piece of code. It's so frequently impactful that it's worth doing immediately without any measurement. You just swap them out with fastutils or trove and call it a day.
- akoboldfrying 2y agoI think you're right, that's probably the best (lowest mental overhead, fewest footguns) way -- always use a List instead of a raw array, and always box primitive types. This also avoids the parallel explosion of Stream types and methods (IntStream, mapToInt(), etc. (and the fact that there's no BooleanStream or ByteStream, etc.)). That said, I tend to get bitten by the fact that == on 2 boxed numeric values is roughly as misleading as possible -- it does reference comparison, but interns small integer values only, so (Integer)42 == (Integer)42, but (Integer)420 != (Integer)420. (So the small values you probably used in your unit tests will appear to work just fine with your broken, ==-using code.) ETA: Deleted a misplaced "new". I also don't love that, e.g., ++x does a heap allocation + deallocation if x is boxed (since boxed types are immutable). But usually I care more about the cycles I spend coming up with correct code than cycles the CPU spends executing it.
- sjrd 2y ago
- haspok 2y ago> * data class Foo(val theImplementationAndStyleOfDataClasses: String) For the purists there are records now in Java (which can be combined with destructuring / pattern matching - there were significant improvements in this area in the last few JDK releases, and more are coming!). In this regard Java had surpassed Kotlin by some margin. For the enterprise coders, there is the Immutables project (https://immutables.org https://immutables.org) which you can say is Lombok on steroids (but implemented correctly, that is, by generating classes which you can inspect as regular source code, instead of relying on hacking the compiler...). > * elvis?.operator?.chaining This will hopefully be finally resolved by one of the subprojects of project Valhalla, as a prerequisite for value class support (which cannot be null, so...). The others on your list are small and subjective stylistic differences, of course your preference may vary, but should not weigh heavily in any Java vs Kotlin discussion.
- t-writescode 2y ago> pattern matching ... In this regard Java had surpassed Kotlin by some margin. I did just glance at Java's pattern matching; and yeah, it does look like it is a bit more powerful than Kotlin's pattern matching in that it can, at the same time, look for both type and a conditional. That's relatively neat - not something I've personally needed / wanted; but neat just the same :) The JVM is a really nice virtual machine in how it lets us use both of these languages fully interchangeably to pick the one we like more. I'm glad Java has been investing in some of these areas, too. Everyone improves when paradigms and new learnings are distilled.
- houli 2y agoKotlin 2.1 has added "Guard conditions in when with a subject" as an opt-in feature https://kotlinlang.org/docs/whatsnew21.html#guard-conditions-in-when-with-a-subject https://kotlinlang.org/docs/whatsnew21.html#guard-conditions...
- unscaled 2y agoJava records do not have a copy method (or with clause or whatever equivalent), and there are no keyword arguments. This makes Java records extremely painful to use for any data has more than 3 fields or so. You could use them together with an annotation processor like RecordBuilder (or Immutables or Lombok, but I don't think they support records?), but that's just not pure Java. Annotation processors that generate byte code always come with their own complexity. Kotlin data classes have their own warts (order-based destructuring can be dangerous and the copy() method is a bit hacky) but the overall ergonomics for large value objects are better than Java records at this point.
- usrusr 2y agoWhen it's "sleeping" code, not as in unused but as in not currently being worked on (no changes in open branches), then it can be quite valuable to have some bulk translation run while the code actually is sleeping, and not at some future time when there'll likely be a whole burst of activity happening in parallel. Repo host products might actually add "transform while sleeping" a possible feature, with their cross-branch knowledge, and perhaps some history mangling for a best effort approach to retaining some of th knowledge available through blame through the conversion. As for Kotlin in general, I agree with your list. I really enjoy the way Kotlin improves the dev experience not so much with audacious new (or "new to a java-like environment", of course I'm looking at you, Scala) concepts but with small trivialities like being able to assign the outcome of an expression chain to a name without polluting that name's scope with intermediates that really don't have any purpose after the result of that chain is assgned. And I don't hold it against Java that it does not follow that path (it focuses on more impactful changes), I would consider it almost out of character if it introduces e.g. .let. The only thing I'm a bit torn about when it comes to Kotlin is wether the "this" variants of scope functions were a good idea. They are certainly part of kotlin, and some "DSLy" styles would really not be the same without them, but if I were to pull what I like about kotlin into other languages I'd probably introduce let and apply (and the this-less run) and skip run/with/apply (assuming that the target language even has a this to run/with/apply on)
- OtomotO 2y agoI used to do Java and Scala. In 2020 I started a new project in Kotlin. I like Kotlin, but what I hate is that in the meantime I migrated all my programming to Neovim and Helix. All programming? No, not Kotlin, because the LSP isn't there and JetBrains clearly has no interest, they want to sell their IDEs. Now don't get me wrong, I have an IntelliJ license since 10 years, even back when I was employed and paid it out of my own pocket. It's not about the price. I would gladly pay for the LSP implementation. But I don't want to use IntelliJ anymore. So a new project on the JVM where I have a say in the stack? Java or maybe Scala. No more Kotlin.
- bberrry 2y agoThis is the biggest issue with investing in Kotlin IMHO. The stewards of the language have a conflict of interest in democratizing the tools.
- wiseowise 2y agoNot only that. Their official position is sitting with smug face saying “well, duh, you’re free to roll out your own LSP and IDE implementation”, ignoring the fact that nobody outside of Google and JetBrains cares about Kotlin. And why would they? If the stewards aren’t interested in investing into healthy ecosystem.
- owlstuffing 2y agoIntelliJ CE is free and destroys any LSP in terms of dev productivity. Other than consistency, why would you not use it?
- fnord123 2y ago> how function pointers at the end of a method call can be auto-inserted as the next curly bracket This is one feature I wouldn't mind making it into other languages. It makes so much sense for doing UI stuff.
- CharlieDigital 2y agoI recently started picking up Kotlin and to me it felt like "lesser C#". I'd personally prefer modern C# as it's been outpacing advancements in other major languages for DX, IMO. It is sad that its adoption seems to have boundaries defined either by large ecosystems dependent on the JVM or ideological.
- t-writescode 2y agoIndeed. It's C# that makes me like Kotlin so much. I was trained in Java but used C# in a fully-professional setting for longer. C# as a language make a lot of very smart decisions that Kotlin took into itself when being created and out if it comes a non-Microsoft-owned (which matters for some people), comfortable, powerful language. If I had to switch and use C# as my main work language for a company, I would be perfectly happy to.