10 ms·
I'm impressed with how Java is shaping up. With records, pattern matching, destructuring, and virtual threads all arrived or arriving, what advantages do Kotlin
by hamandcheese 3y ago
I'm impressed with how Java is shaping up. With records, pattern matching, destructuring, and virtual threads all arrived or arriving, what advantages do Kotlin and Scala bring?
- jdm2212 3y agoThey're really great for making sure Java devs will absolutely never contribute to your project. (I say this as a Java dev who occasionally gets tempted to try to help out in repos that are Kotlin/Scala, and gives up very quickly.)
- the_overseer 3y agoIs this supposed to be a good thing or a bad thing?
- hamandcheese 3y agoDouble edged sword. Spring devs: stay far, far away from me.
- jdm2212 3y agoMostly a bad thing, at companies with lots and lots of Java devs.
- soulbadguy 3y agoIsn't that true for any other language as well ?
- jdm2212 3y agoI'm happy to take a crack at Go and C++, but coming from Java it is totally impossible to decipher wtf is going on in Scala. Kotlin is better, but still pretty awful. Also, devs who use Go and C++ usually have a good reason (embedded systems and such), but Kotlin and Scala use seems to be motivated mostly by vaguely hipster-y annoyance with Java 8. And, like, sure, if you are annoyed by Java 8 and then use a language designed to have nothing in common with Java 8 except that it can import Java libraries and run in the JVM... well, it's gonna be a pain in the butt for your colleagues who do Java all day. And some of them aren't going to make the effort to work with it.
- soulbadguy 3y ago> wtf is going on in Scala I hate to admit it as someone who enjoy trying new languages and enjoyed my time using haskell a long time ago, but scala 2.x was definitely the most confusing and intuitive language i have ever used professionally. Really felt like a collage of desperate features without any coherence between them.
- tome 3y ago> most confusing and intuitive unintuitive, perhaps?
- soulbadguy 3y ago+1
- still_grokking 3y agoIn my experience Scala is one of the most intuitive and coherent languages out there. Very hard to beat in those regards. A tiny language with only a few, but powerful, features which can be used as building blocks to express even the most advanced patterns. The problem are just the people "holding it wrong". If you try to use it as Java++ Scala will be more cumbersome than Kotlin. If you try to use it as Haskell this will become very painful quite quickly. You need to use it as Scala… This means you need to embrace its features and philosophy. Just use the best parts of OOP and FP together!
- soulbadguy 3y ago> A tiny language with only a few, but powerful, features which can be used as building blocks to express even the most advanced patterns. And yet from the scala 3 website itself : > One underlying core concept of Scala was (and still is to some degree) to provide users with a small set of powerful features that can be combined to great (and sometimes even unforeseen) expressivity. For example, the feature of implicits has been used to model contextual abstraction, to express type-level computation, model type-classes, perform implicit coercions, encode extension methods, and many more. Learning from these use cases, Scala 3 takes a slightly different approach and focuses on intent rather than mechanism. Instead of offering one very powerful feature, Scala 3 offers multiple tailored language features, allowing programmers to directly express their intent: > The problem are just the people "holding it wrong". If enough people have the same problem with a programming language, at one point it become the problem of the language, not the people. > Just use the best parts of OOP and FP together! Assuming that one can cleanly extract the best part of OOP and FP without bringing the baggage of eiter. It's not clear to me that those part don't have a certain level of "contradiction" which leads to the whole beeing less coherent than just OOP or FP.
- piokoch 3y agoKotlin provides modern features in the Android development Java land stuck on the ancient Java 6. Scala was an academic experiment on how to match nicely object oriented world with functional programing paradigm that got some hype because Java development was crawling like a snail. I am not sure if this experiment was successful after all, though.
- kllrnohj 3y agoAndroid isn't stuck on Java 6 and many of the changes are in the compiler not the runtime anyway.
- spockz 3y agoWith Scala 3 a lot of the idiosyncrasies of scala 1/2 got fixed. (If you can get over some naming.) What is mostly brings for me is showing that composition beats inheritance and that classic OO trying to shove the real world in an inheritance tree is not the way to go. Also, it got Java to move up development, together with the move to cloudnative. From a language enthousiast point of view I’m still curious why Kotlin and now these features in Java get so much traction while most have been available for 20 years in Scala. Was it marketing? Was it people? Was it symbol soup? Who knows?
- vbezhenar 3y agoAs a Java developer for 15 years and as a language enthusiast myself I'm curious as well. Because I definitely don't see many places where I would use pattern matching in my code or even records. Recently I wrote like 10k LoC and I used record once: in test code to return pair of values. May be I'll replace some `if`-s with pattern matching, just like I use `instanceof` pattern matching today, but that's absolutely minor thing which is hardly worth mentioning. I would even dare to say that lambdas and `var`-s for me are questionable features. Actually as I grow older, I appreciate ascetic nature of Go and sometimes I think that using Java 1.4 might actually be preferable for many codebases. I understand that for code which manipulates trees like compilers with their ASTs, pattern matching might be god send. The thing is... 99.99% of developers don't write this code, so optimizing language for it is strange goal. Sometimes I think that some language features are driven by hype, even with Java. I always happy about runtime improvements, though. And Java delivers in that front, so I can tolerate pattern matching and streams if I can get virtual threads and struct values.
- gavinray 3y agoI can give perspective as someone who enjoys modern Java, writes Kotlin at their dayjob (and loves it), and also likes Scala 3. Here are the things that if Java had, I probably wouldn't see a reason for other languages: 1. Lack of first-class lambda syntax. In Kotlin/Scala you can write something like: fun doSomething(handler: (String, Int) -> Foo): Blah In Java, all you have are the "Function<>" and related interfaces, which are clunky to use. 2. Opaque types (Scala 3). These have been one of the most impactful programming features I've ever used, and I sorely miss them in languages that lack them. object Foo: opaque type UserId = Int opaque type Email = String def mkEmail(s: String): Email = s def findUserIdByEmail(email: Email): UserId = 42 import Foo.* val email: Email = mkEmail("foo") val valid: UserId = findUserIdByEmail(email) val invalid1: UserId = findUserIdByEmail("bar") // error: can't use String as Email val invalid2: UserId = 123 // error: can't use Int as UserId 3. Union types (Scala 3). You can emulate them in Java/Kotlin with Sealed Types but it's much more verbose. type JsonScalar = String | Int | Boolean type Json = JsonScalar | Map[String, JsonScalar] | List[JsonScalar] // Makes writing functions that take multiple argument types much easier: def handle(it: String | Int | Boolean): Unit = ... 4. Context-oriented programming with "given/using" in Scala 3 and "context-receivers" in Kotlin. This one is harder to explain succinctly but essentially it allows you to decorate methods/classes with required "contextual" args. Instead of passing them as regular function arguments, you must invoke the function inside of an "environment"/"context" where the requirements are satisfied. This makes threading dependencies through your code much easier, and eliminates the need for dependency injection frameworks in many cases. interface Logger { fun log(message: String) } object ConsoleLogger : Logger { override fun log(message: String) = println(message) } ctx(Logger) fun doSomething(): Int { log("Hello") return 42 } fun main() { val logger = ConsoleLogger with (logger) { doSomething() } } 5. First-class support for asynchronous programming. With "suspend" in Kotlin and a current prototype being done in Scala 3: - REPO: https://github.com/lampepfl/async https://github.com/lampepfl/async | SLIDES: https://github.com/lampepfl/async/blob/main/scalar-slides.pdf https://github.com/lampepfl/async/blob/main/scalar-slides.pd... | YOUTUBE TALK: https://www.youtube.com/watch?v=0Fm0y4K4YO8 https://www.youtube.com/watch?v=0Fm0y4K4YO8 6. Passing arguments by name, rather than positionally. fun doSomething(a: Int, b: Int, c: Int): Int = ... doSomething(a = 1, b = 2, c = 3) 7. Tuples (Scala). They're like anonymous data classes/records. val t: (Int, String) = (1, "foo") val (a, b) = t
- mhfu 3y agoDon't know anything about Scala. Kotlin has null safety and a bit cleaner syntax, but other than that, I don't see too much advantage over Java for backend. In Android, Java is still lagging behind a lot. Also, Jetpack Compose, a declarative UI framework is Kotlin only. Kotlin is also working on wasm (so is Java I think, but Kotlin has working examples with wasm GC) and Jetpack Compose is going multiplatform, including wasm. This video has some examples in description https://youtu.be/oIbX7nrSTPQ https://youtu.be/oIbX7nrSTPQ
- kaba0 3y agoThere is teavm and cheerpj which can already execute java (or any jvm class file) in js or wasm.
- matsemann 3y agoThe stdlib of kotlin with immutable types, lots of good extension functions on for instance lists etc is hard to beat. Especially with the nice lambda syntax it makes it a joy to write functional code compared to streams and having to call separate functions by wrapping instead of chaining. Operator overloading can be misused, but for certain things it makes stuff much prettier as well.
- AlexITC 3y agoScala stdlib is considerably better than the one from Kotlin, one detail I dislike about Kotlin collections is that `map` invocations always result in a List.
- jbellis 3y agoDid kotlin ever add an equivalent of parallel streams?
- jillesvangurp 3y agoYes, via co-routines and flows. And with some convenient extension functions you can easily deal with Java APIs that take or return streams. The structured concurrency proposal in JDK 21 takes some steps in the same direction. That's basically the higher level stuff that will make Loom more usable. In general the theme of that release seems to cherry pick a lot of stuff that Kotlin and Scala have been supporting for some time. That's a good thing. Java developers have been missing out on a lot of good stuff. There's quite a bit more of that of course where this came from.
- xmcqdpt2 3y agoKotlin's standard collection are "immutable collections" only in the sense that they are read-only. Adding an element to a Kotlin immutable set copies the whole thing, https://github.com/JetBrains/kotlin/blob/924c28507067cbfbf78a6509ea89eabe496e34ca/libraries/stdlib/common/src/generated/_Sets.kt#L84 https://github.com/JetBrains/kotlin/blob/924c28507067cbfbf78... This is not that different from Java unmodifiable. In contrast the Scala immutable Set supports constant time addition, https://docs.scala-lang.org/overviews/collections-2.13/performance-characteristics.html https://docs.scala-lang.org/overviews/collections-2.13/perfo... This isn't just an ivory tower concern either. Because Kotlin immutables aren't actually immutable (they just don't expose mutation interfaces) this means that if I get a ref to an immutable Set, I can't modify it but I can't rely on it not changing because it's still back by a mutable one.
- re-thc 3y ago> what advantages do Kotlin and Scala bring That it's not Java. It's a huge thing with some developers not wanting to touch Java for <insert reason> but would be fine with Kotlin or Scala.
- pjmlp 3y agoThen better go elsewhere, rather than work on Java Virtual Machine. It is like using UNIX and not wanting to understand, touch, C.
- erik_seaberg 3y agoThe JVM’s main value props are a world-class single dispatch runtime and GC, and a huge ecosystem of compatible OO libraries. It also doesn’t care whether you are writing Java by hand. If your team can master any of the more concise and productive languages, they should.
- pjmlp 3y agoExcept the tiny detail that a big part of that value proposition is written in Java. If people want to ignoring the foundations of their toolbox, that says a lot about the skillset.
- erik_seaberg 3y agoIt’s hard for me to judge, when I’ve known Java since 1996. I might need to know Java, but I don’t need to write it. Maybe it’s enough that someone on the team knows it. Maybe it’s not really possible to master Scala/Clojure/Kotlin/Groovy/AspectJ without knowing at least some Java. Likewise, I probably need to know C to use POSIX, but it’s so unsafe that I should not be writing it.
- pjmlp 3y agoYes, the poor guy that needs to jump in for: - understanding stack traces - writing idiomatic bindings for libraries - debugging why Java frameworks fail consuming jar files whose bytecode was generated in a different way - debugging why a jar misbehaves after a JVM bytecode rewriting tool messed up the bytecode sequence used to emulate other language semantics on top of the JVM - adopting libraries whose compiler plugins and annotation procesors only understand Java semantics - mapping debuging information and telemetry data from tooling like JFR into the original code of the guest language.
- social_ism 3y agoFeature soup is kind of meaningless. The open source community has whatever it needs now. Many "alot" of java programmers in the US cant code to JDK8 already. I love the JVM but these Java releases are not being adopted on any real scale for a reason. They break things. And syntax sugar is boring and unnecessary for a crew of software engineers that have no real ethos surrounding records or any of these features. They are just being rolled out to appease devs from other ecosystems. They will not form a new or better method for building systems or improve performance.
- Defletter 3y agoFor me, the biggest pain point with Java is the lack of optional chaining <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...> and nullish coalescence <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...>. I've noticed so many libraries and JDK APIs that try to solve this problem in such a limited way. What is `Objects.toString(thing)` other than a botched `thing?.toString() ?? "null"`? And that utility method is only limited to `toString`, what if you want null-safety for other methods? You have to write that yourself. It's silly. Adding optional chaining and nullish coalescence would be a wonderful QOL change. It'd reduce code complexity, and it would flatten code (ie, hide less logic behind tiny methods). I do a lot of serialisation. You have no idea how much I'd love to be able to just to `data.set("thing", this.valueEnum?.name())` instead of having to do `data.set("thing", this.valueEnum == null ? null : this.valueEnum.name())`.
- kaba0 3y ago> I do a lot of serialisation. You have no idea how much I'd love to be able to just to `data.set("thing", this.valueEnum?.name())` instead of having to do `data.set("thing", this.valueEnum == null ? null : this.valueEnum.name())`. You may be already familiar with this, but mapstruct is a godsend package that easily beats any kind of optional chaining.
- 3y ago
- AlexITC 3y agoI don't see much advantage from Kotlin unless you are stuck with an old jdk (like the one from Android), still, the latest jdk is still far away from current Scala.
- kernal 3y ago>what advantages do Kotlin bring? Elvis operator. Drops mike.
- pjmlp 3y agoI rather focus on the disadvantages of additional layers to debug, with their own set of libraries, and on Kotlin's case, a way to sell InteliJ licences. Meanwhile using Java, means using JDK out of the box with no extra sugar. Pretty healthy.
- lolinder 3y ago> a way to sell InteliJ licences. This doesn't change much for me, because I can't imagine writing Java without IntelliJ. Eclipse is just a disaster by comparison.
- peterashford 3y agoI'm not fond of Eclipse, but Netbeans exists =)
- pjmlp 3y agoIndeed, how can anyone live without a full compiler instead of an incremental one, buying additional licenses for JNI development (Clion), ten finger chords, an index system that never stops, having to manually call for specific code inspections, ...
- jeroenhd 3y agoUntil Java finally includes real nullability guarantees in its language (and its standard library) I'll stick to Kotlin when I can. These improvements are still nice for when you're stuck dealing with Java code, but in my experience getting projects to run on the latest version of Java isn't very easy with various dependencies all needing support first.
- jdm2212 3y agoFWIW, it is not difficult to set up NullAway: https://github.com/uber/NullAway https://github.com/uber/NullAway
- lolinder 3y agoIt's also not nearly the same as having null checks be a first-class part of the language.
- jdm2212 3y agoYes, it does offend the language hipster instinct in me too to have to add 8 lines of gradle to a turn on a build plugin.
- ohgodplsno 3y agoAnd then have to deal with the fact that the libraries you consume don't use NullAway either.
- jdm2212 3y agoIf you import Java libraries into Kotlin, you can still get NPEs from the libraries. And if you don't import Java libraries into Kotlin, well... you could just write Java without those Java dependencies, too.
- jeroenhd 3y agoJava has tons of nice additions (Lombok, NullAway, Manifold) but that's not part of the language itself. When you bind yourself to libraries like these, you're stuck waiting for them to update whenever a new Java release comes out. That can take months or years, and sometimes a library just stops getting updated at all. If Java were to include NulLAway in their standard language, which they clearly can do if they wanted to, I would consider it to have feature parity with other modern languages.
- mm007emko 3y agoWithout Scala, Clojure or Kotlin this probably would have not happened.
- eeperson 3y agoThe major things from Scala that I find useful are: - higher kinded types - null in types - for comprehensions - macros - opaque types - implicits/type classes - persistent immutable collections - EDIT named & default params
- usrusr 3y agoIt's the small things that make kotlin awesome. Not microscopic things like removing semicolons, but the left-to-right of .as?, .let and friends that allow simple things to remain simple instead of littering the code with almost-single-use names. Give those trivial intermediates a name when you think the name will be helpful, not when the syntax is unhappy without. Those aren't astronaut level language features to treat someone's Haskell-envy, but simple things that just happen to add up really well.
- listenallyall 3y agoThis question is fundamentally flawed. People don't use Kotlin just as "a better Java" (maybe they did in 2017), Kotlin is an independent language that runs on the JVM, as well as other targets. Most Kotlin devs don't see Java and Kotlin in competition with each other or wish to use Java if it only had feature X.
- ActorNightly 3y ago>With records, pattern matching, destructuring, and virtual threads all arrived or arriving, Yet literally none of those things actually matter for any sort of real world application. What matters is how quickly you can get code to do what you want, and Java/Kotlin lost that plot almost a decade ago.
- chii 3y ago> What matters is how quickly you can get code to do what you want it's pretty quick to start with java (and presumably kotlin too - not too familiar with it). I argue that it's even faster than with javascript. You at least don't have to toil with the build tool (java == maven).
- haspok 3y ago> What matters is how quickly you can get code to do what you want... This is the falsest statement I have read in a long time. Maybe, if you write once and then throw it away (like a use-once shell script). Otherwise you will have to maintain your code, and then readability and safety trump everything else. If not, it is about performance, but then a lot of time is spent on fine-tuning.
- ActorNightly 3y agoAnd yet, every single java enterprise project has a shitload of files, and compiling and running all of those takes significant time, in the 10s of seconds, all because of how Java is structured. Trying to edit something means you have to dig through layers of inheritance into factories and injection frameworks, debugger is a slow piece of shit that almost needs ide wrapper to run, and as far as safety goes, people seem to have forgotten about log4shell, REALLY quick. You can believe that strong OOP and all the theoretical bullshit in JDK21 matters, but in the future, Java developers will be the first to go as the world moves towards much smaller dev teams that are well versed in a super high level, AI powered language+compiler, where you can knock out production web apps in a day.
- haspok 3y agoThere is no desctructuring in Java, as mentioned in JEP 441 (for some "future version" of the language). Or maybe I'm missing something in which case would you point me to a JEP or an article about destructuring in Java? EDIT: nevermind, I should have checked JEP 440, which is about destructuring record patterns... Aside from that, immutable / readonly collections and null safety are two big reasons for Kotlin or Scala.