[HN Gopher] Translating 10M lines of Java to Kotlin
___________________________________________________________________
Translating 10M lines of Java to Kotlin
Author : ermatt
Score : 206 points
Date : 2024-12-18 17:29 UTC (4 days ago)
(HTM) web link (engineering.fb.com)
(TXT) w3m dump (engineering.fb.com)
| freeqaz wrote:
| What are the benefits of Kotlin over Java? Something I wish they
| went into!
| cute_boi wrote:
| > maximize our gains in developer productivity and null safety
|
| Java is to too verbose. Kotlin have features like null safety,
| better functional programming, better coroutines, advanced
| sealed classe. Java virtual threads is still not ready and
| development was very slow. Blame oracle for being too
| complacent.
| s6af7ygt wrote:
| I'm a dunce
| fnord77 wrote:
| it has been getting better. Records and lambdas cut down on a
| lot.
|
| still seems too verbose though even though it is my preferred
| language
| t-writescode wrote:
| I commented here: https://news.ycombinator.com/item?id=42483538
|
| Mostly, I find it far less verbose with a couple huge
| convenience features that I'm constantly using and would feel
| very lost without; and, they all come as part of the language,
| rather than bytecode hacks / pre-processors, like lombak
| smrtinsert wrote:
| Lombok is absolutely painless.
| t-writescode wrote:
| I admit I have no direct experience with it. For my
| perspective on it, I rely on one of the best developers
| I've ever worked with - especially when it comes to
| debugging and deep investigation and she *hates* it. If I
| had to assume (we don't work together anymore), it's
| because it did some freaky stuff that made debugging the
| weird bugs really, really hard.
| aembleton wrote:
| Lombok does provide a lot but it doesn't make types non
| nullable by default or reduce verbosity or give us
| extension functions.
| wiseowise wrote:
| Lombok is absolute garbage. Either use proper Java 2.0 like
| Scala/Kotlin or stay in Java.
| LinXitoW wrote:
| My biggest pet peeve with Kotlin is that they got rid of
| checked exceptions and replaced them with nothing at all. All
| error code flow is now just invisible unchecked exceptions,
| the single worst kind of error handling imaginable.
|
| I know they added the Result type later on, but there's zero
| convenience to it, so you have to manually handle every
| error, even if you just want to bubble it.
|
| Checked Exceptions were better, though Rust still has the
| best error handling in any non-functional language.
| bberrry wrote:
| Depends on what you're writing I guess (as always). I write
| backend services and if there is an exception thrown,
| generally the whole request is forfeit. So a top-level
| exception handler is all that's needed.. no checked
| exceptions ruining my lambdas or streams like in Java.
| TheSociologist wrote:
| Steve Yegge has a fun article on why someone might prefer
| kotlin over Java: http://steve-yegge.blogspot.com/2017/05/why-
| kotlin-is-better...
|
| Do note that Java has quite a few features now that it didn't
| at the time of writing.
| billisonline wrote:
| "More specifically, from JetBrains, the makers of the world-
| famous IntelliJ IDEA IDE, whose primary claim to fame is its
| lovely orange, green, purple and black 'Darcula' theme"
|
| This must be a bad attempt at a joke, right? Darcula is a
| nice theme (I personally prefer high contrast), but surely
| IntelliJ's code inspection and automatic refactoring have
| always been its claim to fame.
| sitkack wrote:
| Themes are the cup holders of the IDE world. You can't sell
| one without them.
| TheSociologist wrote:
| Yegge's writing has a pretty sardonic sense of humor. I
| like it but I've seen it put off some folk.
| latenightcoding wrote:
| > we decided that the only way to leverage the full value of
| Kotlin was to go all in on conversion
|
| Could someone expand on this please.
| phyrex wrote:
| From the article:
|
| > The short answer is that any remaining Java code can be an
| agent of nullability chaos, especially if it's not null safe
| and even more so if it's central to the dependency graph. (For
| a more detailed explanation, see the section below on null
| safety.)
| trollbridge wrote:
| One of my biggest gripes with an otherwise strictly typed
| language like Java was deciding to allow nulls. It is
| particularly annoying since implementing something like
| NullableTypes would have been quite trivial in Java.
| t-writescode wrote:
| Would it have been trivial and obvious for Java (and would
| Java still have been "not scary") back in the 90s when it
| came out?
| nradov wrote:
| It wouldn't have been particularly hard from a language,
| standard library, and virtual machine perspective. It
| would have made converting legacy C++ programmers harder
| (scarier). Back then the average developer had a higher
| tolerance for defects because the consequences seemed
| less severe. It was common to intentionally use null
| variables to indicate failures or other special meanings.
| It seemed like a good idea at the time
| kelnos wrote:
| > _It would have made converting legacy C++ programmers
| harder (scarier)._
|
| And that, right there, is all the reason they needed back
| then. Sun wanted C++ developers (and C developers, to
| some extent) to switch to Java.
| acaloiar wrote:
| In addition to what @phyrex already pointed out, without any
| Java in the code base, they probably hope to hire from a
| different cohort of job seekers.
|
| Younger developers are far less likely to know Java today than
| Kotlin, since Kotlin has been the lingua franca for Android
| development for quite some time. Mobile developers skew
| younger, and younger developers skew cheaper.
|
| With Java out of the code base they can hire "Kotlin
| developers" wanting to work in a "modern code base".
|
| I'm not suggesting there's something malevolent about this, but
| I'd be surprised if it wasn't a goal.
| trollbridge wrote:
| I think you're on to something here. When recruiters contact
| me about Java jobs, I tell them my level of interest in a
| Java job is about as high as RPG or COBOL, and that I'm wary
| of spending time on a "legacy" technology. Most of them are
| fairly understanding of that sentiment, too.
|
| If I had someone call me about Kotlin, I would assume the
| people hiring are more interested in the future than being
| stuck in the past.
| phyrex wrote:
| You're already expected to learn a number of exotic (Hack) or
| old (C++) languages at Meta, so I'm pretty sure that's not
| the reason.
|
| To quote from another comment I made:
|
| > I don't have any numbers, but we know that the Meta family
| of apps has ~3B users, and that most of them are on mobile.
| Let's assume half of them are on Android, and you're easily
| looking at ~1B users on Android. If you have a nullpointer
| exception in a core framework that somehow made it through
| testing, and it takes 5-6 hours to push an emergency update,
| then Meta stands to lose millions of dollars in ad revenue.
| Arguably even one of these makes it worth to move to a null-
| safe language!
| irunmyownemail wrote:
| An NPE means an incomplete feature was originally pushed to
| production. It would still be incomplete or incorrect, in
| Kotlin and would still need a fix pushed to production.
|
| It's even worse with Kotlin, without the NPE to provide the
| warning something is wrong, the bug could persist in PROD
| much longer potentially impacting the lives of 1 Billion
| users much longer than it would have if the code remained
| in the sane Java world.
| acaloiar wrote:
| "The" reason is not what I'm speculating on, because I
| don't think a singular reason is likely to exists.
|
| There is likely a mix of reasons -- of which NPE avoidance
| is almost certainly one. And hiring/talent management is
| almost always another, when making technology choices.
| Particularly when choices are coupled with a blog post on
| the company's tech blog.
| mukunda_johnson wrote:
| Wait a minute, this isn't an AI article...
| aduffy wrote:
| I'm skeptical of the value in doing this. There are a mountain of
| tools like NullAway, ErrorProne, Immutables that make it so much
| easier to write safe code in Java. New developments in the
| language like first-class record types improve the DX as well.
|
| I think Kotlin helped push Java in the right direction, but at
| this point it seems like a weaker choice. Spending years to
| migrate a massive Java code base like this feels like wasted
| time.
| t-writescode wrote:
| 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 wrote:
| `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 wrote:
| Generally these are only used in test methods, which is
| fine. I've never seen anyone use them outside that.
| recursive wrote:
| What 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 wrote:
| When 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 wrote:
| I 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 wrote:
| Parameterized 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 wrote:
| Parameterized 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.
| benatkin wrote:
| methodName_whenInputDoesNotParseToValidRegexThrowExceptio
| n
|
| They did a study and it isn't hard to read camelCase.
| https://ieeexplore.ieee.org/document/5090039
| richbell wrote:
| I mean, it's harder to read compared to normal text with
| spaces and punctuation.
| benatkin wrote:
| That doesn't seem to be the case based on the study. And
| normal for one thing, such as paragraphs of prose, might
| not translate to another thing, such as a sequence of
| words in a line of code.
| richbell wrote:
| > That doesn't seem to be the case based on the study.
|
| The study does not say that camelCase is unequivocally as
| easy, or easier, to read.
|
| Selecting the correct identifier from a list of 2-3 words
| (expandAliasTable, expandAliasTitle, etc.) is a wholly
| different exercise.
| grapesodaaaaa wrote:
| That's just one study, and I'd argue we should write
| books in camel case to make them more compact if there's
| truly no difference.
| t-writescode wrote:
| Sure, but I like writing the other more. It's entirely a
| style thing and you're not required to do it :) it's also
| basically only ever seen in tests :)
| unscaled wrote:
| This study only compared camelCase to snake_case and what
| the results are mixed, depends on what you call "hard to
| read". They only seem to have tested finding identifiers
| from a word cloud, and it did take more time to read
| camelCase identifiers (although they were also resulted
| in more accuracy).
|
| It's important to note that the researchers only tested
| short phrases with 2 and 3 words. "getNextPath" is a
| different beast compared to "methodName_whenInputDoesNotP
| arseToValidRegexThrowException".
|
| On the other hand, there is a good body of research that
| generally shows that proper sentences (not just 2-3
| words) without spaces are harder to read, at least for
| English speakers[1]. Early medieval Latin manuscripts did
| not use space between words[2]. The fact that spaces were
| seen as an improvement when they were introduced, is
| probably telling.
|
| [1] https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5
| &q=unsp...
|
| [2] Roman-era inscriptions did use an interpunct (a small
| middle dot) to separate words, but this practice fell out
| of fashion in Late Antiquity and Early Middle Ages and
| I'm not sure if it was ever the norm in handwriting.
| yearolinuxdsktp wrote:
| From experience CI test reports are vastly more
| comprehensible at a glance.
|
| That study compared camel case to underscore spaces. Well
| underscore space is still not as readable as methods with
| spaces and dashes.
| usrusr wrote:
| It's a place to put intetion that isn't so much of a
| second class citizen that it will likely be ignored
| and/or not updated if it ceases to be true. You want your
| test methods fine grained (many methods that each check
| one variation, instead of one method that checks a whole
| list of them) and every extra redundancy (method naming
| vs the variation of data actually passed vs
| documentation) increases the the chance of those
| redundancies getting out of sync.
|
| In fact I've occasionally found myself writing reflection
| code to parse the test method name as input just to avoid
| that problem altogether (for name and data, not for
| documentation). And that was in plain Java even, the
| pattern could be far more useful with that kotlin naming
| freedom.
| grapesodaaaaa wrote:
| The test frameworks typically output the passing/failing
| function names. Adding spaces like this make them more
| human readable.
|
| expectInternalServerErrorOnBadInput
|
| Vs
|
| expect internal server error on bad input
| NitpickLawyer wrote:
| Isn't this breaking Jakob's law of the rest of the
| tooling though? I can se flows borking with something
| like "x failed at expect" in a majority of reporting
| tools not specifically meant to deal with this spaces in
| functions stuff.
| wiseowise wrote:
| So that programmers have one more bikesheddibg reason,
| obviously.
| irunmyownemail wrote:
| It reminds me of Spock tests written in Groovy. I have to
| help maintain a code base like that now at work where a
| Groovy zealot (who has moved on) convinced the teams to
| write tests in Groovy instead of Java.
|
| When a test fails, the method name describes what it was
| supposed to do written out like a sentence enclosed in
| double quotes which seems like a win but not much of one.
|
| When you need to add a new test or analyze if an existing
| test needs to be changed, you have to eyeball all the
| code in the test class because even with methods named
| with spaces, it's not always indicative of what it does.
|
| With Java, I can sort a list of method names and have a
| better idea immediately what needs to be updated or
| added.
| thaumasiotes wrote:
| > 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 wrote:
| While 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 wrote:
| The best part about lots of languages being around is
| that you can pick the one that resonates most with you :)
| wiseowise wrote:
| Right. You have selection of Kotlin and Kotlin in
| Android/Kotlin heavy company.
| coldtea wrote:
| If that's the case, it doesn't sound there was much will
| to work to begin with...
| int_19h wrote:
| Why do you hate fun so much?
| RedComet wrote:
| Agreed. Obviously `func` wasn't going to happen because
| it is already so similar to Swift, but `fn` at least
| should be an option.
| aembleton wrote:
| I like it for unit tests. Makes naming them easier
| coldtea wrote:
| > _Eugh, that is a turnoff._
|
| That's because you're too used to C/Algol style languages
| usrusr wrote:
| As 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 wrote:
| > 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)
| wiseowise wrote:
| > Considering Kotlin came from JetBrains, IDEs are most
| likely already in the Kotlin community's DNA.
|
| Idea understands and performs dramatically better with
| Java.
| jeroenhd wrote:
| I my experience it performs quite similarly, but Kotlin
| code can be a lot denser so similar files don't look
| similar at first glance.
|
| It also _really_ doesn 't like Java with generics for
| some reason. Still beats any other Java IDE I've seen.
| eptcyka wrote:
| This also means that JetBrains will never write a
| language server for Kotlin, locking you into their
| ecosystem.
| int_19h wrote:
| It doesn't lock you into their ecosystem given that other
| people can (and have) written language servers for
| Kotlin.
| eptcyka wrote:
| Which 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.
| wiseowise wrote:
| Name is wrapped in ``, so it's not "true" use whatever you
| want. You also have to use `` on call site.
| paulddraper wrote:
| The better benefit is that you can use the right name for
| something instead of tiptoeing around reserved keywords.
| jeroenhd wrote:
| The 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 wrote:
| If 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 wrote:
| fwiw 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 wrote:
| I also really like conditionals like switches and ifs
| returning values.
| overhead4075 wrote:
| Java 14 introduced switch expressions.
|
| https://docs.oracle.com/en/java/javase/17/language/switch-
| ex...
| bberrry wrote:
| _try_ statements being expressions is also especially
| lovely
| akoboldfrying wrote:
| Honestly, 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 wrote:
| Out of curiosity, what are you wanting that autoboxing
| doesn't resolve?
| kjeetgill wrote:
| Stripping 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 wrote:
| I 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 wrote:
| Scala solves the primitives-in-generics, and it
| significantly improves on the array-hates-generics.
|
| So it's possible.
| haspok wrote:
| 10+ years in the making, at this year's Devoxx Brian Goetz
| said that they are almost ready with the design of Project
| Valhalla and can start JEP-ing it in future JDK releases.
| No timeline yet, so we probably will not see it until the
| next-after-next LTS release (29?)... But Java, like Cobol,
| is not going anywhere, so the wait will be worth it.
| akoboldfrying wrote:
| Great, though is that perhaps orthogonal to my
| complaints? My vague understanding is that Valhalla is
| about transparently allocating local objects on the stack
| instead of the heap when possible (i.e., when escape
| analysis confirms that they can't "get out" of the method
| that declared them), the way primitives are now.
| haspok wrote:
| But these are the same problems! I'm not intimately
| familiar with the current state and internals of project
| Valhalla, but they were proposing `primitive classes`
| backed by primitive types, allowing said class to be used
| as a type in generic code. Moreover, primitives would
| become ValueObjects, so you would have your int[] which
| would also be an Object[]. In other words, the difference
| between primitives and objects would be much smaller in
| terms of the language.
|
| Bottom line is, you could have your cake and eat it too -
| have an int[] that looks like a List<Int>, and vice
| versa, while retaining the performance characteristics of
| an array.
| akoboldfrying wrote:
| Thanks, I'd thought that the goal was to reimplement
| aspects of the compiler+JVM to preserve existing language
| semantics but be more performant, but from what you've
| written I take it that the goal is actually to expand the
| language semantics themselves, in a way that would bring
| primitive types and objects (and thus generics) closer
| together.
| yarg wrote:
| Valhalla is what you want, at least for some of it.
|
| https://openjdk.org/jeps/402 interface
| Box<T> { T get(); void set(T
| val); } interface IntBox extends
| Box<int> { int get(); void
| set(int val); }
|
| https://openjdk.org/projects/valhalla/
| throwaway494932 wrote:
| It is also about value types. I think the talk parent is
| talking about is [this], a bit long but worth watching
|
| [this] https://inside.java/2024/12/16/devoxxbelgium-
| valhalla/
| bberrry wrote:
| Kotlin _does_ improve on the primitives /boxed situation.
| For example in Kotlin there is just "Int", not both "int"
| and "Integer". The language will use stack-allocated
| primitives wherever possible and boxed objects when
| necessary (in Collection generics or when you've explicitly
| opted into nullability). The distinction is abstracted away
| from you as a programmer. Sounds like the consistency you
| want.
| haspok wrote:
| > * 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) 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 wrote:
| > 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 wrote:
| Kotlin 2.1 has added "Guard conditions in when with a
| subject" as an opt-in feature
| https://kotlinlang.org/docs/whatsnew21.html#guard-
| conditions...
| unscaled wrote:
| Java 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.
| stickfigure wrote:
| Lombok supports `@With` on records, which adds _wither_
| methods. And there are ongoing JEP discussions on how to
| support this natively in Java.
|
| Lombok is so ubiquitous today that I effectively consider
| it part of the language. And even with Lombok, the Java
| toolchain is so much faster, easier to use, and more
| stable than Kotlin.
|
| Kotlin is a great language, marginally better than Java,
| but I'm not sure it's worth enduring the toolchain. And
| Java keeps improving.
| mrudolph22 wrote:
| If you think Kotlin is marginally better than Java, you
| probably have a superficial understanding of Kotlin.
| Kotlin is vastly better than Java, which isn't surprising
| because Kotlin was designed 15 years later with the
| explicit goal of being a better Java and fixing as many
| of Java's design mistakes as possible. For example, the
| designers of Kotlin went through the book "Effective
| Java" and tried to avoid the listed pitfalls by design.
|
| Java will never get close to Kotlin because even though
| Java can, and thankfully does, still improve, it's too
| late to revise many of it design decisions, and large
| language features often need to be considered in a
| language's design from the start.
|
| On Android, Kotlin is an even bigger win because Android
| uses an old Java version and has become Kotlin-first.
|
| In my opinion, Java will remain the best choice for
| libraries that target multiple JVM languages. For
| everything else, I use Kotlin without thinking twice.
| Kotlin 2.0 laid the groundwork for toolchain
| improvements, which have indeed been a long-standing pain
| point.
| stickfigure wrote:
| Nah: If you think Kotlin is vastly better than Java, then
| you have a poor grasp of Java. I offer the same evidence
| you did.
|
| Having worked professionally in both, I find that good
| programmers can write excellent code in both languages;
| bad programmers can write terrible code in both
| languages. The average cultural practice of the Kotlin
| community is perhaps better than the average cultural
| practices of the Java community (which huge and defies
| averaging anyway). But Java code which emphasizes
| immutability, uses Optional instead of nulls, uses
| streams, etc is pretty indistinguishable from Kotlin.
| jeroenhd wrote:
| > This will hopefully be finally resolved by one of the
| subprojects of project Valhalla
|
| I think we'll see them come in through
| https://openjdk.org/jeps/8303099 although I'm not a huge
| fan of the approach chosen (tri state nullability:
| explicitly nullable, explicitly non-nullable, legacy code
| that should just be treated as nullable).
|
| Except for native support for reification, almost all of
| Kotlin can be reimplemented by Java if you wait long enough
| and stack enough class annotations. It's all stylistic up
| to a certain point, but the classic Java style combined
| with the glacial improvement process is one reason why some
| people want to use a different language.
|
| I think I'll have an easier time convincing someone to
| consider Kotlin than I'll have convincing someone to add
| Immutables+Manifold to the dependency chain. You end up
| writing Java that's not really Java like, but also not
| something that there's a good standard style for, and that
| usually ends up in a mess.
|
| I'm glad with pattern matching, Java is now pushing Kotlin
| to improve rather than the other way around. I'll hope to
| use those features one day, when companies finally upgrade
| from Java 11 to Java 17 in five or ten years.
| usrusr wrote:
| When 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 wrote:
| I 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 wrote:
| This is the biggest issue with investing in Kotlin IMHO.
| The stewards of the language have a conflict of interest in
| democratizing the tools.
| wiseowise wrote:
| Not 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.
| fnord123 wrote:
| > 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 wrote:
| I 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.
| spankalee wrote:
| As long as they're already writing new code in Kotlin,
| translating the existing code makes a ton of sense, if they can
| do it cost effectively (which is sounds like they did).
|
| One of the huge problems with a language migration is that
| you're left with old and new and all the parallel tooling,
| context switching, and impedance mismatches. There's often a
| claim that the existing code will be migrated eventually, but
| IME that doesn't actually happen with large code bases. Then if
| there's ever a third migration, you're left with three
| languages in play.
|
| It's much better to aim for 100% migration, as close to 100%
| automated as possible. Then when you're done, you're really
| done. Maintenance, training, and the next migration will be
| easier.
| chasil wrote:
| Is Oracle a factor?
|
| Does a Kotlin codebase have more safety from a legal
| perspective?
| nradov wrote:
| The legal issues around Java between Alphabet and Oracle are
| settled at this point and no longer a risk for third-party
| software vendors. But it's pretty clear that Android is
| moving away from Java, so anyone with a strategic commitment
| to that platform has to plan around that reality.
| retrodaredevil wrote:
| It's safe to say that Android is definitely moving away
| from Java in terms of new language features. I mean, if you
| want to support older Android versions and use modern Java
| features or newer parts of standard libraries, you'll
| usually have to rely on desugaring or making sure you're
| using classes that are supported in Android.
|
| IMO, Android is moving away from modern versions of Java.
| Java and its underlying standard library will always play a
| big role in Android development.
|
| The way I see it, Kotlin makes a lot of sense for Android
| development because Kotlin can introduce new things in its
| standard library that make older versions of Java look
| ancient. It's not like you can use new Java features in
| Android, so using Kotlin makes people not care as much
| about new features of Java that are only available in
| modern versions of Java.
| pjmlp wrote:
| Android folks were forced to acknowledge modern Java,
| otherwise they would lose access to Maven Central
| ecosystem, as everyone adopts newer Java versions.
|
| Hence ART is updatable via Play Store since Android 12,
| and is currently on Java 17 LTS.
| wiseowise wrote:
| Is it even full Java 17?
| pjmlp wrote:
| Of course not, it is Android we're talking about.
|
| It is good enough Java for relevant libraries to work on
| Android.
| pjmlp wrote:
| It is hard to move away from Java, when the whole JetBrains
| tooling, Gradle and Maven Central depend on Java ecosystem.
|
| Including the main sales pitch of Kotlin, its
| Interoperability with Java.
| chii wrote:
| unless you're not using the jvm (which is owned by oracle,
| despite being opensource), you won't have any difference
| between kotlin and java from a legal perspective tbh.
| a57721 wrote:
| > unless you're not using the jvm (which is owned by
| oracle, despite being opensource)
|
| It's not "the JVM"; JVM is a spec that has many
| implementations, you are probably referring to Oracle
| JRE/JDK.
| halfmatthalfcat wrote:
| I would argue it was Scala, not Kotlin, that has contributed to
| the push to make Java "better".
| desiderantes wrote:
| Scala and Groovy were big pushes for Java 7/8. Their hypes
| died down after that release.
| marwis wrote:
| Where do you see pattern matching in Kotlin?
| totallykvothe wrote:
| In its pattern matching feature
| wiseowise wrote:
| Kotlin has no pattern matching. Their bootleg 'when' with
| guards is no match (no pun intended) for true pattern
| matching.
| jghn wrote:
| I would argue that Scala drove Kotlin. And over the last 10
| years at least, it's been Kotlin driving Java.
|
| What I saw happen was Kotlin taking over the mantle of
| "better java" from Scala, and aiming for an 80/20 type
| language compared to Scala. And for the most part, it's those
| 80% that are finding their way into Java.
| mrudolph22 wrote:
| Many of Kotlin's profound improvements will never find
| their way into Java because it's 25 years too late to do
| so. Java improves where it still can, which is the right
| thing to do. Sometimes Java even manages to improve on
| Kotlin because now it can learn from Kotlin and other
| languages. Nevertheless, it's impossible for Java to catch
| up to Kotlin, which was designed 15 years later with the
| explicit goal of fixing as many of Java's design mistakes
| as feasible for a JVM language.
| bdangubic wrote:
| post back when kotlin is in top-8000 :)
|
| https://www.tiobe.com/tiobe-index/
| nradov wrote:
| Meta operates at such a large scale that the engineering
| management decision process becomes qualitatively different
| from smaller organizations. They can justify enormous
| investments in keeping their code base fresh for small
| improvements in productivity and quality.
| benatkin wrote:
| It isn't fresh though. Java has improved a lot and the
| benefit of Kotlin is dubious.
|
| Maybe it has a more PHP-like feel to it. No accounting for
| taste at that company.
| aembleton wrote:
| > benefit of Kotlin is dubious
|
| What's dubious about it. Kotlin has a more comprehensive
| dx, and has features like extension functions that aren't
| on the java road map.
| m0zzie wrote:
| The value in the conversion of existing code in this particular
| case isn't 100% clear to me either, but I think calling Kotlin
| a weaker choice than Java at this time is naive, particularly
| when preceding that with "there are a mountain of tools" that
| you can bolt on to Java to give it features that are built in
| to Kotlin.
|
| What makes Kotlin such a strong choice for many orgs today is
| its batteries-included multiplatform capability. We are able to
| write data models, validation logic, business logic, etc just
| once and compile to JVM, WASM, and native targets. For orgs
| with very large codebases and frontend applications (web + iOS
| + Android) this is an attractive capability because we can have
| a single codebase for a ton of core functionality, and have
| each frontend import a library which is native to its own
| platform.
|
| Of course many technologies with this promise have come and
| gone over the years, but this is the first one with a strong
| backing that has allowed us to _natively_ interoperate with
| each target platform.
|
| I believe these are all driving factors that have been pushing
| well known companies, that were previously Java shops, toward
| Kotlin. If you speak to a broad range of people in the industry
| you'll find many more orgs moving from Java to Kotlin than from
| Kotlin back to Java. We can simply get more work done with less
| code and ship to all our frontend platforms, and unless Java
| can do the same, I don't see the industry moving in that
| direction.
| sebazzz wrote:
| > What makes Kotlin such a strong choice for many orgs today
| is its batteries-included multiplatform capability. We are
| able to write data models, validation logic, business logic,
| etc just once and compile to JVM, WASM, and native targets.
|
| Not familiar with Kotlin but how does that work? Does it come
| included with a PAL? Because it you want to be platform
| agnostic, you can't for instance use a Java RegularExpression
| in your platform agnostic code.
| rnentjes wrote:
| The PAL (Platform Abstraction Layer I assume) is just the
| stdlib that is provided. The stdlib is not the same for all
| platforms, as can be seen in the documentation. A regex
| implementation is provided for all platforms, but is not
| quite the same on all platforms:
| https://kotlinlang.org/api/core/kotlin-
| stdlib/kotlin.text/-r...
|
| In shared code you can define interfaces that have to be
| implemented by any platform you use.
| wiseowise wrote:
| You forgot that you need to have a whole infra team that is
| going to maintain all the shitty Gradle configuration KMP
| requires.
| hinkley wrote:
| It's like marriage. Yes there are tools that can give you
| most of the same rights and privileges as marriage, or you
| could just get married and get all of that for the cost of
| writing one check and signing some papers. No lawyers. Done.
| Move on with your life.
|
| The question of optional things is always laid out as if the
| choices of my coworkers do not exist. Are you expecting me to
| work solo, or to be a bloody tyrant who pushes through all of
| my own ideas over the objections of an entire team? These are
| some of the most antisocial people in any debate on software.
| No I don't get to just chose to use or ignore a tool in an
| ecosystem. That's why picking a system with batteries
| included is a simpler transaction. I can go to a new company
| and have expectations, not arguments.
| needlesslygrim wrote:
| There are, at least in my opinion, many more reasons to use
| Kotlin than null-safety and data-classes/records, especially on
| Android (Jetpack Compose).
| utbabya wrote:
| There are a lot of nice things I enjoyed when I was still
| working with Kotlin extensively. Null safety, data class,
| sealed class, exhaustive when, top level functions, object
| class, higher order function, extension functions etc. They
| fundamentally change the way dev think, producing safer,
| lighter and more maintainable code.
|
| Contrary to the popular notion of dismissing certain syntax
| differences as sugar, I consider it one of the most important
| factors simply because we spend more time reading than writing
| code. To me Java has always been verbose and dreadful to read,
| there's something fundamental wrong if you need your IDE
| generate so much then force to train your eyes to skip over
| most of them while reading.
|
| I find Kotlin to be more elegant and fluent especially with
| native syntax support of the above features. I can read it at
| least 25% faster than Java. Perhaps which one is better is
| personal taste, but I'd maintain syntax is very important, just
| like natural languages.
| pjmlp wrote:
| Especially because outside Android, Kotlin Virtual Machine will
| never happen, it will always be a guest language on the Java
| ecosystem.
|
| Nothing on Kotlin will ever matter on the decisions taken by
| Oracle, IBM, Amazon, Azul, PTC, Aicas, microEJ, Microsoft, Red-
| Hat,.... on their JVM/JDK implementations and related tooling.
| graemep wrote:
| > I'm skeptical of the value in doing this.
|
| Its Meta. They have enough money to spare not to need to worry
| too much about whether there is a good RoI on rewriting some
| mobile apps.
|
| I very much doubt FB's mobile apps are written for any sort of
| efficiency, (either in engineering or financial terms) - 18,000
| classes in the apple one!
| https://quellish.tumblr.com/post/126712999812/how-on-earth-t...
| einsteinx2 wrote:
| Yeah Facebook was (in)famous for autogenerated code in their
| apps and frameworks. In fact early on they had to do some
| hack on Android since they had more classes in their FB app
| than was supported by the operating system lol.
|
| So super inefficient binaries, but I guess more efficient to
| develop (or I assume that was the idea)?
| LegNeato wrote:
| You are getting the details wrong (I was there). This was
| the single DEX limit, and Google would just bump it in AOSP
| every time their own apps hit it (as their apps didn't
| support older OS versions). FB at the time was supporting
| back to froyo, which had a much lower limit than "modern"
| apps needed. See this note for more info:
| https://www.facebook.com/notes/10158791578712200/
| einsteinx2 wrote:
| Thanks for the clarification! Yeah I only vaguely
| remember the story from reading about it when it was new,
| so it's been a while haha
| ignoramous wrote:
| > _was supported by the operating system_
|
| By the _Dalvik Virtual Machine_ (DVM). 65k method limit is
| what Facebook hit. tbf, DVM was engineered to run on
| embedded systems with 64MiB RAM (as a replacement for
| J2ME).
| unscaled wrote:
| The nice thing about null-safety in Kotlin is that it is built-
| in and it requires no extra annotations or added tooling. Not
| having @ProxySingletonAbstractJunkFactoryFactoryBean sprinkled
| all over your code does it ever so slightly more readable.
|
| But if built-in null safety and lower verbosity was all that
| Kotlin had to offer I doubt it would have won. Kotlin offers a
| lot more features that Java does and most probably _will not_
| offer in the next 10 years:
|
| - Extension methods: No more terrible FooUtil or BarHelper
| classes.
|
| - Context parameters (preview feature)
|
| - Coroutines (they are not just about concurrency - you can use
| them to write generators as well[1]).
|
| - Keyword arguments: This makes using constructing data classes
| possible without generating builders, and in general lets you
| deal with multi-argument methods in a safer and more readable
| way. It also cuts down the boilerplate of defining 20 different
| overloads that call each other.
|
| - Interface Implementation by delegation: This feature makes it
| easy and painless to follow the motto "composition over
| inheritance". Java makes implementation inheritance 50 orders
| of magnitude easier than composition with manual delegation, so
| it's pretty natural that the vast majority of Java code- bases
| overuse inheritance in very bad ways.
|
| - Properties: This reduces the need to worry about direct field
| access causing API breakage in the future, and removes the need
| for the absolutely massive boilerplate associated with getters
| and setters in Java. It's true that records remove the need for
| that, but records only work for purely immutable data classes
| (and right now they are only practically usable with a small
| number of fields).
|
| - Delegated Properties: Not something I use every day, but it's
| very useful when I do use it.
|
| - Unsigned integers (specifically bytes): Writing any byte-
| wrangling code in Java is a downright nightmare.
|
| - Reified Generics: Java may get something equivalent to that
| with Project Valhalla, but I'm not sure how comprehensive it
| would be.
|
| - If expression: Java made switch an expression with JEP 361,
| but if is still a statement. This leads to a lot of bloated and
| somewhat unsafe code where you have to define a variable before
| the if and then assign to he variable in each branch.
|
| - Expression Bodies for function: This is a very small feature,
| but it's pretty nice to cut down boilerplate and make functions
| more readable when you need it.
|
| DSL Features ------------
|
| Kotlin is perfect for DSLs thanks to features like:
|
| - Closure blocks: Kotlin lets you pass the last closure
| argument to a function as a block of code inside curly braces
| that follows the function call. This features lends itself very
| well to readable DSL. In Java you would need to embed the
| closure inside the function argument list and add an extra
| parentheses. This gives you _some of_ (see the next couple of
| points) the DSL capabilities of Kotlin, but the DSL becomes
| very hard to read and use when a lot of blocks are involved.
| There is a good reason why Kotlin DSLs are based on blocks,
| while Java DSLs are based on the less-flexible fluent interface
| pattern: block-based DSLs are just too hard to read and write
| in Java.
|
| - Inline functions: Inline functions allow the compiler to
| perform some optimizations in advance that may be harder for
| the JIT to do (namely inlining the provided block closures),
| but the real kicker is that you can use flow control statements
| (break, continue and return) that affect the calling scope.
|
| - Multiple "this" in context. You can have multiple values for
| this inside a nested scope. The compiler manages to find the
| right reference for the "this" alias based on your usage, but
| in case of ambiguity (where the deepest "this" wins), you can
| disambiguate your choice. This feature sounds overly complex
| and unnecessary at first, but it allows a lot of power for the
| Kotlin DSL system.
|
| - Closures with this receivers: Using the multiple this values
| from above, you can have closures that receive their own "this"
| to introduce DSL methods. Being able to introduce these methods
| without shadowing the "this" from the parent context is crucial
| for powerful DSLs.
|
| - Infix functions and operator overloading: Needless to say,
| these features make DSLs even nicer.
|
| I've probably skipped a couple of features I can't recall right
| now, but I hope that it shows that Kotlin is a lot more than
| just "Java with null-safety and data classes" as some people
| think.
|
| [1] https://kotlinlang.org/docs/sequences.html#from-chunks
| int_19h wrote:
| > Interface Implementation by delegation: This feature makes
| it easy and painless to follow the motto "composition over
| inheritance". Java makes implementation inheritance 50 orders
| of magnitude easier than composition with manual delegation,
| so it's pretty natural that the vast majority of Java code-
| bases overuse inheritance in very bad ways.
|
| While we're on this subject, I'd like to rant for a bit. Why
| is this not a standard feature in _every_ OO language today?
| The adage that composition should be preferred to
| (implementation) inheritance is itself older than Java, and
| was already fairly common wisdom 20 years ago - yet PL design
| has seemingly not reflected this.
| wiseowise wrote:
| Say thanks to Google who basically stopped developing stuff
| with Java in mind.
| npalli wrote:
| Most important reason for the rebirth of golang (after it's
| initial dip in early '10s) and wide spread adoption of Kotlin
| is the ownership of Java by Oracle. It doesn't matter what fine
| print exists, but everyone knows what kind of a*holes Oracle
| and Larry Ellison are, they will find a way to squeeze you.
| Everyone is going to sprint away from Java as soon and as much
| as possible. For someone like FB, Kotlin being a nicer language
| is just cherry on the cake.
| smusamashah wrote:
| But doesn't Kotlin compile to Java?
| Cyph0n wrote:
| No, it compiles to Java bytecode that runs directly on the
| JVM.
| jillesvangurp wrote:
| Java did improve over the years. But it still defaults to doing
| basically everything wrong by default. Parameters are non
| final, classes are open, things are mutable, etc. It's unsafe
| by default. And it's hard to fix because it breaks backwards
| compatibility. Kotlin doesn't have that problem and it has been
| doing the right thing by default for a long time. It's still
| getting better.
|
| I think on Android the choices are either to start from scratch
| or to migrate to Kotlin for Facebook. Sticking with Java on
| Android just makes everything harder. All the new frameworks
| are Kotlin centric. Most Android developers they'd be hiring
| would have been using Kotlin for years. Etc. So, I can see why
| Facebook is making the effort to keep their code base alive and
| future proof. Android is more Kotlin focused and has been for
| years. And that's only going to be more the case now that
| compose multi platform is a thing.
|
| Btw, most of the stuff you mention is probably more applicable
| to server side Java and less to Android. IMHO, Spring + Kotlin
| is a very nice combo on servers. Very well supported by Spring
| and they bundle a lot of convenient things for Kotlin. And I
| don't need any of the tools you mention because it does the
| right thing by default.
| Tainnor wrote:
| > And I don't need any of the tools you mention because it
| does the right thing by default.
|
| I mostly agree with you, but Spring+Kotlin does require the
| allopen plugin, so it's kind of hacking Kotlin to do the
| wrong thing (all classes open) in order to support an
| arguably bad design choice by Spring.
| bberrry wrote:
| Can't blame Kotlin for that. And it's a very minor sin
| frankly.. set-and-forget.
| Tainnor wrote:
| I don't blame Kotlin for it, I blame Spring for it.
| yearolinuxdsktp wrote:
| all-open plug-in is the only sane way to operate Kotlin.
| fngjdflmdflg wrote:
| >I think Kotlin helped push Java in the right direction, but at
| this point it seems like a weaker choice.
|
| Nobody wants to use a mountain of tools just to achieve basic
| feature parity with other languages. Also java syntax is awful.
| neeleshs wrote:
| The newer version of Java has much better syntax.
| irunmyownemail wrote:
| Personally, I love Java syntax, or did before Java 8. It's
| still better than Kotlin though. At least it gets the type
| and name in the correct order.
| int_19h wrote:
| What makes it the "correct" order?
| RedComet wrote:
| It is probably more that Kotlin's order breaks with the
| most common ordering, and at the cost of more characters.
| Not to mention the needless variation that has come along
| with it (e.g. : vs ->)
| wiseowise wrote:
| Arrow is a lambda, just like in Java.
| RedComet wrote:
| I'm referring to the burden when changing languages.
| Swift and Rust use -> for the return type.
| eikenberry wrote:
| How do they compare tooling wise? Kotlin's K2 compiler targets
| more platforms than the JVM which seems like an advantage.
| zahlman wrote:
| This article absolutely _reeks_ of ChatGPT to me. For example:
|
| >With this in mind, we set out to automate the conversion process
| and minimize interference with our developers' daily work. The
| result was a tool we call the Kotlinator that we built around
| J2K. It's now comprised of six phases:
|
| followed by a list of descriptions of the "phases" which only
| sort of make sense for the name given to them, and are utterly
| incoherent as actual phases in a process (and grammatically
| inconsistent). For example, one of the cited "phases" is...
| "headless J2K". In other words: they have one piece of software
| that wraps another, and it - gasp - _doesn 't_ use the wrapped
| software's GUI. Aside from being entirely unremarkable, that's
| neither a phase in a process _nor a component of a tool_. It 's a
| _fact about_ the component.
|
| LLMs write like this all the time - and it's clear evidence that
| they do not, in fact, do anything like _reasoning_ , even if they
| can sometimes be manipulated into generating a second piece of
| text that resembles an analysis of the first one. The resulting
| description is so weird that I question whether the authors
| actually checked the LLM's output for accuracy.
|
| Any human writer who _gives a damn about good writing_ and has
| any skill, would not allow "it" to refer to "the conversion
| process" two sentences back when "a tool called the Kotlinator"
| has been introduced in the interim (or, if that were the intended
| referent, would notice that tools are not "comprised of phases").
| Such a writer would also not come up with abominations like "the
| conversion process is now comprised of six phases" where "we now
| use a six-phase conversion process" would be much clearer.
| Certainly, a six-point bullet list produced by a competent writer
| would label them in a grammatically consistent way
| (https://en.wikipedia.org/wiki/Parallelism_(grammar)) - not with
| an abstract noun describing an action, two participles, two
| concrete (well, as concrete as software ever is) nouns and a
| command (who, exactly, is being told to "build" the "error-based
| fixes" - whatever that means - here?).
|
| I'm starting to feel like Mark Twain.
|
| ----
|
| On the other hand, I was cynically expecting some mention of
| using AI for the _actual task_ , and that doesn't seem to be the
| case.
|
| (Also, the "reactive" web design is broken. The page overflows
| horizontally for some range of window widths, without causing a
| horizontal scrollbar to be added.)
| amelius wrote:
| > cynically expecting some mention of using AI for the actual
| task
|
| Well, you could combine AI with correctness preserving
| transformations, so you get the best of both worlds (i.e.,
| correctness AND a translation that keeps the resulting code
| close to what a human would write).
| LegionMammal978 wrote:
| Calling it a 'phase' doesn't seem that weird to me? For each
| file, they go through a number of steps to translate it, and
| one of those steps is to run the J2K tool on it. The next
| section is just describing how they implemented that step: the
| J2K tool is normally enmeshed into the rest of the IDE, but
| they managed to jerry-rig a solution to run the relevant code
| by itself, without running the rest of the IDE with it every
| time.
| zahlman wrote:
| It could possibly make sense if the phases were described as
| e.g. "performing a deep build, preprocessing, running J2K,
| postprocessing, linting and applying error-based fixes"
| (i.e., all participles). But then the descriptions should be
| about how those phases are implemented (i.e., _this_ is the
| place to mention the work of setting up a headless version of
| J2K so that it could be run in an automated pipeline) and how
| they contribute to getting the desired result. The
| description "The J2K we know and love, but server-friendly!"
| is utterly useless here, and also practically the archetype
| of what ChatGPT writes in "promotional material" mode.
| spankalee wrote:
| What's not a "phase" about running J2K?
| zahlman wrote:
| The phase is, as you say, (the act of) _running_ J2K - not a
| property (being headless) of the J2K implementation used.
| Philpax wrote:
| You are tilting at windmills. The article exhibits the kind of
| English I'd expect from someone sharing a technical development
| in an acceptably-perfunctory style for a company blog.
| mardifoufs wrote:
| It's as if chatgpt got its style from somewhere... For a hyper
| sanitized LLM like chatgpt, it's not surprising that it will
| sound like a sanitized corporate blog (that I still personally
| liked).
| spullara wrote:
| This seems like a huge waste of time unless they expect Google to
| deprecate Java on Android - which isn't impossible.
| politelemon wrote:
| Some of the newer material libraries are kotlin only. It does
| seem to be happening.
| wg0 wrote:
| Kotlin can't be called from Java land?
| senorrib wrote:
| It can.
| kalind wrote:
| Jetpack Compose cannot be written in Java because it relies
| on a Kotlin compiler plugin to transform composable
| functions.
| jillesvangurp wrote:
| With some limitations. Mostly writing Kotlin code that is a
| used friendly enough for Java developers requires a bit of
| extra effort. It's not something that a lot of Kotlin
| developers waste time on.
| lawgimenez wrote:
| You can't use Jetpack Compose with Java.
| keyle wrote:
| I have a genuine side question... Why does Meta have 10M lines of
| Java for their Android code base? What's in it?
| t-writescode wrote:
| Java's how you wrote Android apps before Kotlin came out. I
| expect they have __all their existing Android code__ in Java.
| 10MM lines doesn't seem out of line for a very, very
| established company with 100k developers across several
| products. It's one of the 3 main platforms that people interact
| with Facebook on and so they'd want it to be as good and as
| fast as possible, especially on older phones for the time when
| Android phones were new.
| wg0 wrote:
| Why they wouldn't use React Native?
| t-writescode wrote:
| * Facebook Messenger came out on Android in 2011 [0]
| * React Native came out in 2015 is written in C++, Java,
| JavaScript, Objective-C, Kotlin [1]
|
| [0] https://en.wikipedia.org/wiki/Messenger_(software)
|
| [1] https://en.wikipedia.org/wiki/React_Native
|
| So, even if they did use React Native, they still have 4+
| years of code in the original language; and, React Native
| doesn't stop the use of Java
| lawgimenez wrote:
| Most importantly, why was Threads not written in React
| Native?
| Yiin wrote:
| Because Instagram wasn't, and Threads is pretty much a
| copy pasted Instagram codebase (for good reasons).
| rycomb wrote:
| I'm pretty sure wg0 was being facetious.
| keyle wrote:
| I'm well aware of the history of Android, Kotlin and Java.
| Still my question stand...
| cowsandmilk wrote:
| Meta doesn't have close to 100k developers.
| aithrowawaycomm wrote:
| There's a lot of subtlety in what exactly a "line" is,
| especially for Java and especially for a legacy enterprise
| codebase: hard to say that Meta's 10M is actually twice as big
| as someone else's 5M.
|
| I have no clue what's in their code, but I would expect a lot
| of "almost redundant" stuff around specific Android versions,
| manufacturers, etc, which can really pile up.
| smrtinsert wrote:
| Really the only question I have on this post. So many of their
| non ai updates make me roll my eyes
| Too wrote:
| All those AbstractContextFizzProviderMetaFactoryBuilderInjector
| StreamManager quickly add up.
| incrudible wrote:
| That is mostly a meme. What really adds up is putting every
| little thing into its own file and having an interface and a
| (usually trivial) implementation for everything.
| optymizer wrote:
| (Android dev at Meta here, though not involved with the Kotlin
| migration. Opinion below, completely my own)
|
| We have: public and internal apps, tests for those, tons of
| wrappers around Android APIs, autogenerated infra code, did I
| mention the API wrappers?, custom layout engines, duplicate
| code that people wrote because they couldn't be bothered to
| search the monorepo, code that was copied without much thought
| because people searched the monorepo and found something, app
| architecture tools like dependency injectors, annotation
| processors, custom build tooling, etc
|
| If you can think it, someone has probably committed Java/Kotlin
| or native code for it already.
| keyle wrote:
| That makes sense. Thanks for the answer.
| 59nadir wrote:
| > duplicate code that people wrote because they couldn't be
| bothered to search the monorepo, code that was copied without
| much thought because people searched the monorepo and found
| something
|
| This is also a very common way in Object-Oriented code bases
| to ensure you're not messing anything up by re-using classes.
| Concatenating yet another class to the code base is the
| safest and laziest way to ensure you're not possibly changing
| the behavior of anything else when you inevitably need to
| add/change something in the class.
| optymizer wrote:
| We move fast and break things ;)
| redditor98654 wrote:
| Why is this a OOP problem and not a problem in large code-
| bases in general? I can easily see it happening in
| functional or imperative languages where one creates an
| almost identical copy of a function instead of reusing and
| modifying an existing one.
| elAhmo wrote:
| Wouldn't it make more sense to do a massive refactoring given
| the situation is as you described? And, if needed, rewrite to
| Kotlin later. This would just cause the same problems to be
| reproduced in a different language.
| onlyrealcuzzo wrote:
| No, the translation is mostly automated.
| antirez wrote:
| A rewrite, too, would take less than years, would have a
| better end result. Honestly the FB application is not
| exactly rocket science, and the massive amount of code they
| have points more on the direction of broken internal
| process and a total lack of simplicity in the design and
| choices.
| phyrex wrote:
| As a consumer you're only ever seeing the tip of the iceberg of
| Meta apps. There are at least 3 major user groups: The
| consumers, the producers, and the advertisers, and each of them
| is at least as complex as the others. Then you have to consider
| the global audiences, and that e.g. ads are handled very
| differently in the EU than in North America, and that needs to
| be accounted for.
| redleader55 wrote:
| I don't think people realize that "Android" at Meta is not just
| the "Facebook" app, but also: WhatsApp, WhatsApp for business,
| Instagram, the whole Oculus layer on top of AOSP, whatever they
| use for Ray Bans, etc.
| gerdesj wrote:
| "Android development at Meta has been Kotlin-first since 2020,
| and developers have been saying they prefer Kotlin as a language
| for even longer."
|
| Not one link to an opinion piece or two regarding: "kotlin vs
| java". The nearest thing I found was "What makes Kotlin
| different".
|
| This sounds somewhat like a debate about which Germanic language
| is best. German, Dutch and English are all "Germanic" but which
| is "best"?
|
| Obviously: That's the wrong question to ask and so an answer is
| doomed to failure.
|
| In the end, does your generated machine code implore the CPU and
| associated hardware to do what you want it to more efficiently in
| some way that is not an abstraction?
|
| Pissing contests rarely excite me. Why did you do this?
| gerdesj wrote:
| Blimey, DV'd within seconds!
| troad wrote:
| I think a pissing contest is precisely what they were hoping to
| avoid by not linking to some "Kotlin v Java" blog post. That
| their developers prefer writing in Kotlin is a basic premise
| for the rest of the article, not its thesis.
| kelnos wrote:
| > _Why did you do this?_
|
| You literally quoted the "why": their developers prefer writing
| Kotlin over Java for Android development. That's it. They don't
| need further justification. They didn't need a "Kotlin vs.
| Java" comparison, and they're not really evangelizing Kotlin
| all that much. They're simply stating a fact _for their
| organization_ : Kotlin is a better fit for their developers
| than Java is.
|
| > _In the end, does your generated machine code implore the CPU
| and associated hardware to do what you want it to more
| efficiently in some way that is not an abstraction?_
|
| Most shops don't care about this too much. The most important
| thing is developer productivity.
|
| (And yes, this is why we have bloated garbage like Electron
| these days; sometimes some people value developer productivity
| to unhealthy extremes.)
| gerdesj wrote:
| So why bother posting on HN if it was inevitable?
| erik_seaberg wrote:
| Seems to me the article focused on how they did this big
| job, rather than why.
| occz wrote:
| The target audience for this kind of article - Android
| engineers - do not need any more convincing on why Kotlin is
| superior to Java. This is a debate that has been settled in the
| Android community since a long time ago. I'd be willing to bet
| money on there only being a rounding error of Android engineers
| advocating the use of Java over Kotlin these days.
| neocron wrote:
| Ah, here we go again with HHVM and Hack ...
|
| The only reason fb is able to do this, is the billions of $
| behind it... For everyone else this is just pure idiocy
|
| Sure if you like Kotlin, use it for new software, but rewriting
| milliona loc for some marginal gains... that how businesses fail
| more often than not
| forgot_old_user wrote:
| I think its great for recruiting. This signals to the world
| their investment in making Devs happier (one of top two reasons
| mentioned was "devs were happier with Kotlin")
| phyrex wrote:
| I don't have any numbers, but we know that the Meta family of
| apps has ~3B users, and that most of them are on mobile. Let's
| assume half of them are on Android, and you're easily looking
| at ~1B users on Android. If you have a nullpointer exception in
| a core framework that somehow made it through testing, and it
| takes 5-6 hours to push an emergency update, then Meta stands
| to lose millions of dollars in ad revenue. Arguably even one of
| these makes it worth to move to a null-safe language! I know
| your point is that you need to have that sort of crazy scale to
| make it worth it and that's true, I'm just annoyed at the
| comments suggesting that the move to Kotlin is just to pad
| resumes or because Meta let a bunch of bored devs run amok.
| valenterry wrote:
| Crazy project.
|
| Personally I find that it's an interesting indicator of the
| capability of the programming languages. Moving from language A
| to B can be extremely easy if B is as powerful or more powerful
| in terms of expressiveness than A. It can be an absolute horror
| if it is less powerful.
|
| Being not null-safe in fact brings additional expressiveness. I
| guess most would argue that it's not a good type expressiveness.
| Nonetheless it is a type of expressiveness that can cause trouble
| during such a transition.
|
| In general it feels like Java is making faster progress than
| Kotlin nowadays. I wonder where Kotlin would be if it weren't for
| Android. I hope those folks don't have to migrate back before
| they even finished.
| 0cf8612b2e1e wrote:
| Without Android, Kotlin would just be Cool Alternative Language
| #4721. Java has been a safe, non-controversial pick for
| decades. Who is going to endorse writing their hot new project
| in it just because some IDE uses it? When Google says they
| support a technology going forward, that gives the project some
| cache it otherwise never would have received.
| wiseowise wrote:
| Not even support, now they've completely migrated all Android
| libraries to be Kotlin-first/Java-never.
| nutanc wrote:
| I am surprised they did not use LLMs like Claude or maybe even
| train their own Llama version to do this. In my experience LLMs
| have been very reliable in translating code.
| lazide wrote:
| There is zero chance they'd end up with a functional code base
| after attempting to do this.
| snovymgodym wrote:
| It seems pretty obvious to me why deterministic code
| translation is preferable for something like this.
| hitekker wrote:
| At my last job, the management greenlighted a full rewrite in
| Kotlin in order to attract/retain developers bored with Java and
| Python. The actual business project was boring since all the
| important design work was already finished by the architect. No
| language rewrite, no interested devs. So management made a quiet
| trade with ICs where everyone got what they wanted at the cost of
| future maintenance.
|
| I learned that social whims (developer fun, preferences ,
| dopamin) are weighted as much as technical rationales
| (performance, maintenance)
| azemetre wrote:
| How would you say it panned out? Were you able to hire people
| easily and did retention go up?
| hitekker wrote:
| Initially, Kotlin attracted mid-level folks to transfer. I
| recall a roaming staff engineer who lead the project for a
| bit, and then wisely rotated outside of the org.
|
| Long-term, the folks who remain are stuck and unhappy. The
| business got what it needed and moved on, leaving a system
| half in maintenance-mode, half feature-complete. Any Kotlin-
| only changes are mostly just bug-fixes or glue work with
| other team's SDKs. Any new features carry a lot of risk
| because the few people motivated to drum up new business (and
| write up requirements) left or quiet-quit.
|
| In a weird way, the project naturally selected for people who
| would get stuck maintaining the artefacts of the project.
| It's a paradox that I can't fully comprehend.
| MrDresden wrote:
| Sounds to me that the situation was caused by problems
| entirely unrelated to the programming language that got
| chosen.
| lowbloodsugar wrote:
| On the contrary. The fact that there are two languages
| that "coexist" means that now we can have politics. The
| same would not be true if the choices were Java and, say
| Go, because then it's a complete rewrite. There would
| still be the possibility of politics but the engineering
| decision would be so one sided as to make it difficult to
| leverage. With Java vs Kotlin, disingenuous folks pretend
| they are the same thing.
| fnord77 wrote:
| yup, a company I worked at allowed Scala and Clojure to make
| different developers happy
| whoisthemachine wrote:
| Interesting that they didn't use one of their AI models to assist
| them...
| onlyrealcuzzo wrote:
| The process is mostly automated...
| werdnapk wrote:
| Why does fb.com always erase your history so the back button no
| longer works once you click on the link to go there?
| rrr_oh_man wrote:
| For the same reason that casinos don't have windows.
| earth2mars wrote:
| Wait, no AI is used ? Amazon claims big about their code
| conversion from Java 8 to 17 using Q developer (GitHub Copilot
| equivalent). Why not use Llama3 models here? Can't they help
| doing such?
| yeahwhatever10 wrote:
| This is an application where LLMs should be the obvious choice,
| it is Machine translation the thing they are supposed to excel
| at. Why not use them? Likely a lack of data. You would need
| lots of Kotlin data (I'm sure lots of Java data exists), and
| the data would need to overlap so the LLM could understand the
| mapping.
| yellow_lead wrote:
| Why use something that works 90 times out 100, but blows up ten
| times, versus an automated process that can be provably correct
| all the time?
| roschdal wrote:
| Why? Oh God why?
| thdhhghgbhy wrote:
| >Developers prefer Kotlin over Java
|
| Why? Bit of substance here would be nice. Otherwise it's just
| another "we migrated to $coolLanguage" post.
| brabel wrote:
| Does it matter why? They asked their devs and got an answer.
| Kotlin is not just another cool language, it's now the main
| Android language. Staying with Java if you're on Android
| definitely should feel like staying behind... I only write
| backend Kotlin code, lots of it, and we have freedom to choose
| Java or Kotlin, the code base is mixed. Nearly everyone uses
| exclusively Kotlin for new code. Sometimes they go to the
| trouble of even converting some existing Java code to Kotlin
| before working on it. If you need to ask why devs prefer
| Kotlin, you probably don't have any experience with the
| languages.
| irunmyownemail wrote:
| I view this as great news. It will attract those would rather
| code in Kotlin for whatever reason, to FB, leaving more Java
| opportunities for the rest of us who like and prefer Java, even
| after 29 years with it.
| mightyham wrote:
| Kotlin's null safety is a huge win, but the language has it's own
| set of flaws such that I try to avoid using it.
|
| The language's "declarative style lambda syntax" makes code
| overly-complex. Every library is basically it's own DSL and every
| lambda context has it's own set of specialized keywords. If I
| write `test { somthing(value) }`, depending on the context,
| `somthing` could be invoking a higher-order function, calling a
| method on an object that the lambda is extending, or calling a
| static method. The muddling of data/declarations and procedures,
| makes jumping into new codebases confusing and time-consuming.
| Rich Hickey has pointed out in numerous talks that syntax itself
| is complex because rules and order are complex, but in languages
| we generally trade a little complexity for terseness. Kotlin
| encourages this trade-off far too much in the direction of
| complexity, and the language would be almost unusable if not for
| it's IDE support.
|
| Getting to the root of the previous problem is that method
| extensions in general feel like an anti-pattern. Without
| introspecting a method call, it's not possible to tell where that
| functionality is coming from. It's a huge amount of added
| cognitive strain to have a classes functionality split into
| various files, possibly across various code bases.
|
| Another problem is coroutines (oh joy, another new DSL to learn).
| By now, it should be known, from languages like Go and Erlang,
| that preemptive lightweight threading is almost always going to
| be better than cooperative. It avoids function coloring, keeps
| throughput of applications more consistent, and is generally
| easier to reason about. Java also now has preemptive lightweight
| threading via virtual threads, but because much of the Kotlin
| ecosystem is reliant on the coroutine API, it don't get any of
| the ergonomic benefits.
| can3p wrote:
| One of the things that surprised me in the article was their
| usage of J2K. They've been using it as part of IntelliJ, alright,
| but why did they have to run it headless? They've even mentioned
| that it was open sourced. And later they've said that they were
| not able to do much improvements because it was on maintenance
| mode at Jet Brains.
|
| I mean, with the ressources meta has I'm sure they could have
| rewritten the tool, made a fork or done any other thing to
| incorporate their changes (they talk about overrides) or
| transformed the tool into something better fitting their
| approach. Maybe it has been done, just not clear from the article
___________________________________________________________________
(page generated 2024-12-22 23:02 UTC)