[HN Gopher] From zero to 10M lines of Kotlin
___________________________________________________________________
From zero to 10M lines of Kotlin
Author : binkHN
Score : 271 points
Date : 2022-10-25 12:19 UTC (10 hours ago)
(HTM) web link (engineering.fb.com)
(TXT) w3m dump (engineering.fb.com)
| tannhaeuser wrote:
| What's the story with Android and iOS cross development using
| Kotlin? Any major benefit over Java (which used to be a thing at
| least in the days of j2objc)?
| JamesSwift wrote:
| KMM (kotlin multiplatform mobile) just hit Beta status. Its a
| really unique value proposition compared to other cross
| platform options in that it doesnt run via a VM (either
| Javascript or e.g. Mono for Xamarin). It compiles to native
| LLVM on ios, and as such you can write your UI natively if you
| want.
|
| I was holding off on KMM before, but I've started looking
| lately and its extremely promising. There is still a lot of
| ecosystem that needs to be built out (e.g. you need to find
| cross platform / pure kotlin implementations of URI or Color),
| but it is shaping up to be the leader in the space IMO.
| kaba0 wrote:
| Why would anyone use it if you can't take advantage of the
| vast Java ecosystem? Why would I choose it over Graal for
| example, which has much bigger backing, stable and is
| language-agnostic.
| JamesSwift wrote:
| You can take advantage of Java in the next layer up, but
| you lose out on sharing that portion of code/logic then.
|
| There are actually 3 layers in play for each platform: The
| pure kotlin shared layer, the "native" kotlin shared layer,
| and the native-native layer. That second layer (the native
| kotlin shared layer) is platform-specific kotlin. So on JVM
| platforms thats the normal Kotlin you are used to, and as
| such it has access to Java. On iOS that second layer is
| Kotlin/Native, and you actually have access to native
| _bindings_ to the native layer (i.e. I can call into UIKit,
| but in Kotlin code). If you put your "native" code in the
| second layer instead of the native-native layer (which on
| iOS is Swift/objective-c), then you can move that into the
| innermost layer if/when it makes sense over time, and the
| frontend is none the wiser.
|
| Here is a good visual and explanation (the rest of the
| presentation is a good overview as well, but I think this
| slide is the best part of the video):
| https://youtu.be/2yd6rVJdICU?t=1749
|
| EDIT: I should also note that nothing prevents you from
| creating "glue" bindings in the pure kotlin layer using
| either expect/actual or an interface, and then reifying
| that using some JVM thing in the second layer, and writing
| the other platforms more from scratch to fulfill the
| contract.
| andrekandre wrote:
| > I can call into UIKit, but in Kotlin code
|
| just a note for those who've never used kotlin native:
| its generating obj-c code when compiling for ios, so you
| cant use any swift-based apis that arent exposed to objc
| from apple
|
| uikit isnt going anywhere for a long time probably, but
| its an important caveat
| jillesvangurp wrote:
| Well there is kotlin-native which allows you to write kotlin
| libraries that compile to IOS and Android. Which you can than
| link to objective C or flutter based UIs. Or even react native.
| That allows you to share a lot of code between different
| platforms. A growing number of Kotlin libraries are multi
| platform meaning you can use them on IOS, the JVM, and in
| browsers.
|
| Java doesn't have that and it's kind of an increasingly dead
| language for mobile development. Some older android projects
| still use it. But Meta is late to the game of migrating away
| from it. Many companies did that years ago and the vast
| majority of new Android applications is using either Kotlin or
| Flutter/Dart.
|
| I have good hopes for Jetbrains extending the jetpack
| compose/compose desktop/compose web ecosystem to IOS at some
| point as well. That would create some interesting possibilities
| in terms of targeting just about any platform with kotlin from
| a single code base. It's a logical next move for them and
| they've been laying the groundwork with their multi platform
| compiler strategy for a while now.
| gavinray wrote:
| I wanted to post that ktfmt, the FB Kotlin formatter, is much
| less well-known than ktlint.
|
| IMO, it produces the most (subjectively) readable code, and is
| the only one that doesn't leave room for you to inject personal
| style in certain places. (ktlint will let you get away with one
| of several ways of formatting code, so long as it falls within
| some guidelines, which can lead to inconsistent formatting).
|
| It's a superior formatting tool IMO.
|
| https://github.com/facebook/ktfmt
| [deleted]
| jillesvangurp wrote:
| These two formatters both suffer from the flaw that what
| intellij does when it autoformats is different from what either
| of those two do and can only be controlled through plugins.
| Especially when it comes to controlling imports this stuff is
| just broken in Intellij. The settings for this are not actually
| part of the code formatting settings.
|
| Most sane code formatters & code standards: "don't use import
| wild cards!" Intellij's default since forever: "wildcards all
| over the place; please jump through hoops to get rid of them".
|
| I've given up on having code formatters in my kotlin builds for
| this reason. Just not worth the hassle of trying to make both
| sides just do the same thing by default so I don't have to
| think about it. And then having to explain to every new team
| member how they have to customize their intellij setup so it
| isn't broken. I just gave up on it. These days I tell people,
| auto format your code, leave the settings alone. Try to only
| format the code you modified to avoid endless formatting
| related diffs.
|
| The fix would be for Jetbrains to finally fix their IDE to have
| proper formatting that includes the behavior of organize
| imports and is perfectly in sync with whatever your build file
| says is the code style rather than whatever manual or built in
| stuff. Any IDE settings for this should IMHO just be removed as
| they are completely and utterly wrong in the presence of a
| build file that says how things should be formatted. Just
| default to whatever your build file says is the code standard
| with some sane default that just comes with the kotlin
| compiler. This should not be optional. You want to override it:
| do it in your build file.
|
| Auto format on save in intellij. CI build verifies that nothing
| is mis-formatted because the IDE did it right because it does
| whatever the build file specifies needs doing without second
| guessing that. Have a githook to format before commit
| (optional). Zero manual fixing of anything ever related to
| formatting. It should not have a chance to go wrong and break
| the build unless somebody forgot to format or have a commit
| hook to do so. Just import the project and everything does the
| right thing. That would be the goal. IMHO it's not technically
| hard but it would require addressing what is likely to be quite
| a bit of technical debt related to this in intellij. And it's
| about time they did that.
| BoorishBears wrote:
| I had it act generally "weird" when adding it to our codebase
| and ripped it out.
|
| Sometimes it'd hang for several minutes, memory usage would
| spike from time to time.
|
| Didn't have time to bother debugging when ktlint just worked
| immediately.
| strulovich wrote:
| When was that? IS that a big codebase? I fixed a memory leak
| issue a few months ago that would have a big effect when
| running over hundreds of files at once.
| BoorishBears wrote:
| More than a few months ago, and a fairly large codebase
| (~1000 files).
|
| I might give it another try for some personal projects
| since I did like the anti-bikeshedding angle with respect
| to configuration, but yeah linting can be a hard sell once
| build performance starts to suffer for it
| strulovich wrote:
| Most likely this fix would make a big difference then: ht
| tps://github.com/facebook/ktfmt/commit/6ea9e8f461853c3217
| 7...
| voganmother42 wrote:
| "In recent years, Kotlin has become a popular language for
| Android development. So it only makes sense that we would shift
| our Android development at Meta to Kotlin as we work to make our
| development workflows more efficient."
|
| I like Kotlin, but this was pretty funny to me: I imagined
| walking into a meeting and trying to tell colleagues we needed to
| move to X because it was popular, then yeet out the ole
| "efficient", mic drop & moonwalk out
| hdjjhhvvhga wrote:
| It happens all the time. I remember when AWS wall all the rage
| my boss came up and told me we need to use S3. Why? "Because
| everybody is using it!" I tried to reason, I did a cost
| analysis - all for no avail. The same boss a few years later:
| "Why are we paying so much for storage?!" He apparently forgot
| he insisted on it in the first place.
| einpoklum wrote:
| I'm 100% sure there's a Dilbert strip with exactly this
| scenario.
| belmont_sup wrote:
| I read it more as they now have kotlin and want to simplify new
| project decisions to just kotlin.
|
| I find this similar to how rust is being added to the Linux
| kernel.
| washywashy wrote:
| Happens so much more often than you think. Have actually seen
| it with the exact same language (Java->kotlin) on an existing
| service. I don't really recall any valid reasons being given
| for the switch (better support for concurrency etc). I think
| often times managers allow this bc they don't want certain
| engineers to get bored and leave, which is odd to me since who
| knows why/when they will leave and they won't take the services
| with them.
| [deleted]
| davidatbu wrote:
| I'll bring up the Kotlin LSP[0] every time I see Kotlin on HN
| because I really hope the LSP takes off (which would make it
| viable to use Kotlin with a non-IntelliJ editor).
|
| Kotlin as a language looks really cool, but I don't want to give
| up terminal-based, modal editing (which I'd have to in order to
| use IntelliJ).
|
| Along those lines, I once tried diving into using Gradle outside
| IntelliJ, and I couldn't find any good resources to help with
| that. If folks have hints/links-to-blog-posts with regards to
| that as well, that'd be great!
|
| [0] https://github.com/fwcd/kotlin-language-server#this-
| reposito...
| LinXitoW wrote:
| I'm sure you're aware it exists, but the Vim plugin for
| IntelliJ is actually good enough, imho. Might be worth a try.
| valenterry wrote:
| I think the LSP for Scala works really well. It's not Kotlin,
| but you might want to try it out.
| davidatbu wrote:
| Thanks for the tip!
|
| I keep reading on HN and elsewhere that Scala's feature-full-
| ness encourages complex/unmaintainable code, but I gotta
| check out myself.
| justplay wrote:
| I thought that they were using react native. Isn't that true now?
| rapsey wrote:
| No the entire app is not react native. Only parts of it.
| david_allison wrote:
| The native modules still need to be written against Android
| (these are typically either Java or Kotlin, plus maybe some
| native code).
| denismurphy wrote:
| That app needs to go on diet.
|
| iOS 310.6 MB
|
| Android 367.7 MB
| [deleted]
| Macha wrote:
| How much is kotlin vs high res assets or shipping every
| experiment to turn them on/off with feature flags? I suspect
| the language contribution is actually pretty minimal
| [deleted]
| auraham wrote:
| The only thing that prevents me from using it is the license that
| shows up during installation. Has anyone read the license? The
| same applies to Dart (Flutter).
| DeathArrow wrote:
| Ye still use good ol' PHP on yer backend?
| [deleted]
| moreira wrote:
| According to them[0], Facebook's primary languages are C++,
| Java, and Python, and they're even embracing Rust now. In
| general, teams have the freedom to choose what languages and
| technologies they want to use. (quoting from the linked video)
|
| They might've started with PHP, but even that stopped being a
| thing once they switched to Hack, their home-grown language,
| ~10 years ago.
|
| [0]: https://engineering.fb.com/2021/04/29/developer-
| tools/rust/
| hu3 wrote:
| Not quite. According to a more recent article, Facebook's
| PHP, Hack, is still a primary language:
|
| > For business logic and relatively stateless applications,
| the Hack ecosystem has the highest level of automation and
| support at Meta and is the recommended language.
|
| On a related note, their Rust usage has grown significantly:
|
| > For performance-sensitive back-end services, we encourage
| C++ and Rust. Rust is a new addition to this list. There's a
| rapidly increasing Rust footprint in our products and
| services, and we're committing to Rust long-term and welcome
| early adopters. For CLI tools, we recommend Rust. This is a
| new recommendation for this year.
|
| https://engineering.fb.com/2022/07/27/developer-
| tools/progra...
| [deleted]
| david_allison wrote:
| One of the things they don't mention is that J2K makes you pick
| between:
|
| * A conversion in 1 commit: complicating/breaking the 'follow'
| behaviour of 'git blame'
|
| * A conversion in 2 commits: the first 'rename' commit doesn't
| compile, complicating/breaking 'git bisect'
|
| I hacked up a script which makes the 'rename' commit compile
| (when I was working with a ~100KLOC Kotlin conversion). This may
| be useful for others:
|
| * https://github.com/ankidroid/Anki-Android/blob/937a6560913ec...
|
| * https://github.com/ankidroid/Anki-Android/blob/937a6560913ec...
| hit8run wrote:
| Delete Facebook.
| fiejvs72iwbev wrote:
| I am pretty sure, people who build Facebook or Messenger apps for
| Android does not use the app. If you use Facebook or Messenger
| for more than 10 minutes, you would find at least 2 very
| fundamentally wrong bugs. I would have fired most of the
| developer if I were the CEO of Facebook. They are not competent
| to work at Facebook
| [deleted]
| hardware2win wrote:
| ~~Microsoft's Java~~
|
| Jetbrains' C#
| [deleted]
| dr_faustus wrote:
| I'm currently working on a project which has both Java and Kotlin
| and I really have to say that I like working on the Java parts
| much better than on the Kotlin parts. I find coroutines a really
| strange and leaky abstraction (and the prevalence of suspend
| methods in libraries which you have to wrap all the time just to
| call them synchronously is really annoying).
|
| With streams and the var keyword, Java is also not that much more
| verbose anymore than Kotlin and the code completion, error
| detection and refactoring capabilities are much better in Java.
| In Java I can also be sure that if I directly access a property
| on a class, there will be no side effects or expensive operation
| while if I use a getter, there might (and I dont have to write
| them either due to code generation or Lombok). So the parts where
| Java is still more verbose actually add clarity (and again, due
| to the IDE, you rarely have to type any of it): I dont really get
| why I would leave out the explicit types in the source code, only
| to be added again as non-editable, weirdly positioned text by the
| IDE (which is not there if just wanna have a quick look at the
| code on GitHub).
| mcv wrote:
| > With streams and the var keyword, Java is also not that much
| more verbose anymore than Kotlin
|
| I have no experience with Kotlin yet, but I recently did some
| Java after years of js/ts, and was nearly driven mad by
| constantly having to convert different kinds of collection.
| String[], Array, List, Iterable, Stream... and every library
| expects or returns something else, so you're constantly
| converting these things.
|
| Any of them would have been perfect if only it had been
| supported by everything, but because of Java's long history of
| constantly inventing newer and better ways of doing things,
| libraries written at different times support different kinds of
| collections and you constantly have to convert them.
| vbezhenar wrote:
| In your own code you should always use one of collection
| classes, usually Iterable, Collection or List, depending on
| which features you need.
|
| Stream usually is not used other than for call chains. Like
| list.stream().map(...).toList();
|
| I write Java for many years and I can't really say that this
| was source of pain for me. I agree that streams could be
| implemented with better ergonomics, but Java designers wanted
| to provide us means to use parallel computations with one
| extra word, so here we are. I've yet to find a place where
| I'd want to use that.
|
| I used collection classes in Java 1.4 and I'm using them in
| Java 19 and I don't think that anything changed in that
| regard. Collections are the same.
| mcv wrote:
| > In your own code you should always use one of collection
| classes, usually Iterable, Collection or List, depending on
| which features you need.
|
| Yes, but every library I use requires or returns a
| different one.
|
| > list.stream().map(...).toList()
|
| But why not list.map(...)?
| kaeruct wrote:
| In this specific case I think it is because stream
| operations can be implemented lazily - they only run once
| you call toList()
| taeric wrote:
| I'm curious what libraries you are dealing with that are so
| opinionated on what collection type you send to them? In my
| years of working with Java, I think I see List. And... yeah
| List. That is about it.
|
| I have had some internal teams try to use Iterable or arrays,
| thinking they needed to be optimized. Almost without fail,
| those are from teams that stall out and never actually
| finished what they were doing.
|
| I have seen case studies of giants that actually needed to
| optimize down to arrays or buffers, but this is often not the
| case. I'd imagine unless you are trading or gaming, you can
| get more than enough mileage out of List. (Specifically
| ArrayList. LinkedList is usually a sign of premature
| optimization without having actually benchmarked what was
| running.)
| dr_faustus wrote:
| I agree to some extent, however, IDEA often helps you with
| that (e.g. by converting arrays with Arrays.asList(array)).
| And I have to disagree: Any of them would not have been
| perfect. An array is sometimes significantly more performant
| and requires less memory than a list.
|
| In the different collections, you see a history of 20 years
| of developer experience improvements coupled with an almost
| religious emphasis on backwards compatibility in the language
| and standard library.
|
| In every (long term) JS/TS project I worked on, about 20% -
| 50% of the development time went into upgrading libraries and
| keeping everything running on the current node version. It
| was maddening. Stuff like the different types of collections
| are a very small price to pay, IMHO, if you can be sure that
| your current Java project will with very high probability
| also run on a current JVM 10 years from now.
| mcv wrote:
| > Any of them would not have been perfect. An array is
| sometimes significantly more performant and requires less
| memory than a list.
|
| That's actually why I prefer List, because a List is an
| interface and can be an ArrayList or another type of List
| and I don't care about the implementation, as long as it's
| a List. But Array is an array that's not a List, and
| Iterable is also an interface, and I think a List is also
| an Iterable, but I'm not sure, and I suspect not every
| Iterable is a List. And then there's Stream which should
| have been a set of convenient functions that are part of
| List or Iterable right from the start, but they're not. And
| what the hell is a Spliterator and why do I need one to
| turn an Iterator into a Stream?
|
| I understand that there are reasons for this, and I totally
| agree that the js/ts dependency situation is far from
| ideal, but it's still maddening to have so many different
| collection types, when js/ts just has an array that's not
| even an actual array, but it still works fine, and all the
| new stuff just gets added on top of it.
|
| One of these days someone should invent a new programming
| language that finally gets all of this right once and for
| all, but I bet people will find ways to improve it again.
| foobarian wrote:
| I don't find coroutines that helpful, but the syntax sugar and
| standard library in Kotlin is pretty awesome. The Elvis
| operator alone is worth the switch. Say you have some container
| with 3 levels of nesting. In Java, you have to null-check every
| level vs. 3 "?." dereferences.
|
| In theory this is possible to approach with annotations but I
| found it hard to keep up in a large codebase.
| gosukiwi wrote:
| If you need 3 levels of null-checks that's a red flag though
| jillesvangurp wrote:
| This sounds like you are trying to shoehorn asynchronous kotlin
| code into synchronous Java code. Which would be doing it wrong.
| The problem is trying to make asynchronous code synchronous:
| don't do that. The whole point of asynchronous is to do it end
| to end and isolate the remaining synchronous bits and pieces
| that you have on separate threads so they don't end up blocking
| all the asynchronous bits and pieces that you have.
|
| Use a proper asynchronous framework and then the only thing you
| need to worry about is avoiding calling synchronous code on
| your main thread (i.e. dispatch it to some thread pool backed
| co-routine context). Not that hard. And you can get rid of a
| lot of that stuff by gradually switching to non blocking
| versions of whatever you are using.
|
| If you are exposing class properties without accessors in Java,
| that's not necessarily a great thing. Especially if your state
| is non final (i.e. mutable). In Kotlin, you'd use vals (or vars
| if you really have to) and by default they just behave like
| they have getters/setters. But you don't have to spell it out.
| And you can override the getters and setters. Just like you
| would in Java. It's just the distinction is not there. It's
| basically a less hacky Lombok.
|
| The weirdly positioned text that your IDE adds are called hints
| and you can turn them on or off as you please. They are there
| to help you. Type inference is a nice thing: it means you can
| read the hints without having to spell out what is what. Java
| has type inference too but it's a bit more limited and more
| verbose. There is no uncertainty about what the type of
| anything is in either language: exactly what you specified (but
| just once in Kotlin's case).
| [deleted]
| kotlin2 wrote:
| > I find coroutines a really strange and leaky abstraction.
|
| I've only used Kotlin on Android, but from what I remember co-
| routines are not necessary to use. If you don't like them, then
| don't use them.
|
| Kotlin has a number of advantages over Java. The biggest of
| which is built-in optional typing. It's also really nice that
| everything is expression instead of a statement. Library
| functions like `let` also make code a little nicer to write.
| And stuff like data classes and better property initialization
| are icing on the cake. In my opinion, you can write Kotlin
| _exactly_ as you would Java, but the development experience is
| much more polished.
| sorokod wrote:
| > built-in optional typing
|
| Typing is not optional, everything in Kotlin is typed. What
| the language has is type inference. The following lines have
| the exactly same types: val teens =
| people.filter { it.age < 20 }.map { it.name } val
| teens: List<String> = people.filter { p: Person -> p.age < 20
| }.map { p: Person -> p.name }
| kaba0 wrote:
| Just for comparison's sake, java is not significantly more
| verbose. final var teens =
| people.stream().filter(p -> p.age <
| 20).map(People::name).toList()
| LinXitoW wrote:
| Keep in mind, you can use Kotlin in any JDK8 project and
| instantly get all those features. What you're proposing
| requires upgrading to a new JDK.
| origin_path wrote:
| Well, the new Android UI framework (Compose) is fully based
| on Kotlin and coroutines.
| afavour wrote:
| > I find coroutines a really strange and leaky abstraction (and
| the prevalence of suspend methods in libraries which you have
| to wrap all the time just to call them synchronously is really
| annoying).
|
| I think the point is to be calling them asynchronously.
| Unfortunately async programming is kind of contagious and
| difficult to shoehorn into sync stuff but if it's written
| asynchronously there's usually a reason.
| bottled_poe wrote:
| Is it? Seems to me that most instructions are naturally async
| or can be refactored as such. I'm probably wrong, just a
| feeling.
| anthlax wrote:
| Sure, but the one thing Kotlin has that makes me never look
| back is null-safety. Java has optional and non-null annotations
| and whatnot, but you have to be vigilant and put the right
| annotations everywhere. Kotlin you get this for free.
|
| The extra sugar on top is super nice too - listOf, mapOf, x to
| y, apply... I think it just makes code that much cleaner. None
| of these are make or breaks but together they work amazing. A
| lot of what I work on professionally is still on Java 8 or 11
| so I don't get any of the cool features like record types.
|
| Most of the OSS I do is Kotlin bedsheets I just enjoy writing
| Kotlin. I don't feel that way with the older versions of Java
| (I'm starting to with the newer ones).
| treis wrote:
| How does this work in a SOA situation? Like do you have null
| checks + default values at every HTTP boundary for your
| application?
| anthlax wrote:
| Most frameworks give 400 bad inputs. If the client gives a
| null but null is not allowed in the type, it will auto
| respond with 400 before it ever invoked the handler.
|
| Java spring does the same thing: if you use an unboxed type
| (int instead of Integer) and the client passes in null, the
| handler will never be invoked.
| taeric wrote:
| But if you have an evolving API, you are back to what was
| asked. Either you are a bit of a jerk to all of your
| existing clients, or you have default values at the
| boundary.
|
| I've found myself with this a lot on "progress" data
| classes where I will be building up a set of data over
| several expensive calls. I /could/ make a new type per
| current state of that, such that I never have nulls. I
| /could/ make it so that every field is Optional. Or, I
| could work on a convention that fields are filled out in
| order, and after the first null, nothing is available. In
| many years, this has not been where null pointers hit me.
| treis wrote:
| To add to this I had a specific scenario in mind. At
| @current_job they bolted on a immutable struct library
| and wrote validations. We are responsible for sending out
| renewal notices and we get the renewal price from another
| system. In certain scenarios we were getting back a null
| price and our validations dutifully caught the null and
| threw an exception.
|
| Theoretically everything worked. However, the end result
| is (1) the customer didn't get their renewal notice and
| (2) we got a validation error instead of (maybe) a NPE
| somewhere. So what exactly are we accomplishing here is
| my broader point.
| anthlax wrote:
| To be honest, this is more of a question about how best
| to handle errors in asynchronous event handlers (not
| handlers marked as async, I mean like send an email at
| xyz time). Imo best way to solve this is to get notified
| of an error in sentry, be it an NPE or validation error.
|
| In a case where the client expects an immediate response
| (http GET) getting "400 validation error: foo is not
| allowed to be null" is a lot more meaningful than "500
| Null pointer".
|
| In general I try not to model invalid states - less
| mental overhead (no one has to tell you xyz can't be null
| it just cannot be null).
|
| Ofc this is a matter of opinion and the lines get blurred
| as soon ad you move stuff to runtime.
| acchow wrote:
| I believe the standard practice (as popularized by Google)
| is that all fields are optional. This allows you to
| deprecate fields in the future while still support older
| (non-updated) clients.
| treis wrote:
| Yeah, my question is more about what you do as a
| consumer. How do you get back null safety if every field
| in the response is optional? Even moreso, in a SOA
| situation where 90% of what you work with comes across a
| HTTP boundary.
| acchow wrote:
| I'm not sure I understand the question. If you have only
| Optionals and Null does not exist, a NPE is impossible.
| The Optional type forces you to handle the empty case, so
| null safety is enforced by the type system.
| treis wrote:
| The question is how do you handle the empty case for the
| hundreds of fields you pull from other systems.
| acchow wrote:
| You handle it how you would have handled fixing a NPE
| which shows up in production. Except now you handle it
| _before_ an NPE ever shows up because the type system
| forces you to.
| LinXitoW wrote:
| While I also love many things about Kotlin, the one thing
| that always sticks out like a sour thumb is error handling.
|
| While Javas checked exceptions had a lot of problems, at
| least there was a way to declare the output (errors are
| ouput) of a function on a type system level.
|
| With Kotlin, that's just gone. You can fiddle with Result
| type (or make your own), but you lose a lot of the ease of
| "bubbling up" errors.
|
| How do you handle errors? (I wished Kotlin had error handling
| like Rust, which is the best that exists, imho)
| krzyk wrote:
| And with records you mostly don't need Lombok (unless you
| really like builders and can't wait for withers in Java).
| bdangubic wrote:
| Records not being extend(able) is the reason why Lombok is
| still mostly needed...
| kaba0 wrote:
| Why would you need extend over implements? I found sealed
| interfaces with records really cool.
| vbezhenar wrote:
| JPA requires mutable classes.
|
| Records ergonomics is terrible if you want to replace data
| classes with records, even if immutable is OK. You need to
| write builders. You can't really write code like
| new Person(id, null, null, null, lastName, firstName, null,
| null, null, null, null, null, null, age);
|
| Withers can help with that, but they're not even in any kind
| of experimental shape right now, so we have many years to
| wait for it.
|
| Right now records are only fine for very simple use-cases
| like Point(x, y). Or if you want to write or generate
| builders. But at this time you don't really save anything, if
| you can generate a builder, you can generate a class as well.
| krzyk wrote:
| Yeah, I don't like JPA because of lack of support of
| immutable types (records or my own classes that don't have
| setters, only constructor).
|
| If you have data class with more than 5 fields then you
| have it wrong. Builders are like lombok and like field
| injection: hide poor class design.
|
| If using a class hurts, it is badly designed and should
| hurt until it is refactored/split up into consumable parts.
|
| I use records extensively, but those are in most cases
| converted classes which were small and immutable. JPA being
| one of the exceptions (a stuck in the past spec)
| vbezhenar wrote:
| Some of database tables I worked with had over 100
| columns.
| kaba0 wrote:
| Why not have it like new Person(name, new Address(...))?
| Nesting is allowed.
| Matthias247 wrote:
| I think coroutines is probably the best implementation of
| cooperative multitasking (async/await) that is is available in
| any language: They build on structured concurrency and thereby
| allow to prevent a few common concurrency problems like runaway
| tasks. You can run them on different threading systems, like UI
| threads, threadpools, etc. And they default to run the
| continuation on the correct thread.
|
| However as any async/await implementation it will obviously
| still have challenges. The "colored" world of functions means
| users need to know the differences between suspend functions
| and other functions, and using something wrong can lead to
| performance issues.
|
| One thing to note is that with the upcoming of virtual threads
| (Project Loom) in Java itself, the need for using coroutines
| might become much smaller. You might just end up using them for
| UI work, and everything else could use virtual threads. That
| could simplify a lot of things.
| jillesvangurp wrote:
| Loom will just slot into co-routines without requiring many
| (if any) code changes. It's still going to be nicer to use
| co-routines from an API point of view and they'll just use
| the loom stuff underneath pretty much transparently when it
| is available. A virtual thread is basically just yet another
| thing that you can wrap with a co-routine. There are many
| such things across the jvm, js, and ios-native platforms that
| are supported via Kotlin already.
|
| And since it is API compatible with things that are already
| supported by co-routines, pretty much all you need to do is
| change your custom co-routine contexts to be backed by
| virtual threads rather than actual threads. This should just
| work even without explicit support for this in the co-
| routines library (it's just another thread pool). But they
| obviously will add explicit Loom support as well as it makes
| sense to make co-routines be virtual threads pretty much
| always.
|
| When that ships, all current kotlin code that uses co-
| routines will be using virtual thread on a Loom capable jvm.
| It already has structured concurrency and all the rest so all
| of that will continue to work. And some of the blocking Java
| stuff that you currently need thread backed co-routine
| contexts for, will stop being blocking so you can stop doing
| that. But it will still work of course.
| mariusmg wrote:
| >I dont really get why I would leave out the explicit types in
| the source code
|
| One my pet peeves, shit like this sucks :
|
| var f = MyStupidMethod();
| mcv wrote:
| > One my pet peeves, shit like this sucks :
|
| > var f = MyStupidMethod();
|
| Yeh, but so does: List<MyWeirdoFooClass>
| myWeirdoFoos = new ArrayList<MyWeirdoFooClass>();
|
| Sometimes it's clear what it is. Sometimes you don't really
| care. Sometimes you do. You can still make it explicit when
| you need it to be explicit.
| dalyons wrote:
| Why? The compiler knows what the type is, the ide can tell
| you the type if you need to know - it's redundant for you to
| have to type it out.
| Iwan-Zotow wrote:
| nonsense
|
| this line has zero readability
|
| you're not writing code for compilers, you're writing code
| for people
| dalyons wrote:
| > you're not writing code for compilers, you're writing
| code for people
|
| i agree, thats why i don't want to clutter my code with
| annotations designed for the compiler, not humans. Type
| inference is a _good_ thing for readability.
| Larrikin wrote:
| You can just the type hints in the IDE for bad code like
| the above example. But glancing through my code, that is
| never an issue in practice because code reviews should
| have caught the poorly named variable and method.
|
| Since the actual size of the code base isn't an issue in
| the modern world, I personally like that the Kotlin
| ecosystem discourages the use of esoteric names and non
| obvious abbreviations. Once you write and read enough of
| it you stop making poor choices.
| bottled_poe wrote:
| The era of strong vs weak typing debate has passed. Adopt
| strong typing, like a professional, or fade into the 90s
| web. Harsh but fair.
| 3836293648 wrote:
| Noone is arguing for weak typing. They're arguing for
| type inference. They're not even slightly the same thing
| jeremyjh wrote:
| The era of not knowing the difference between static
| typing, strong typing, and type inference is past. I'm
| the sort of professional who likes to learn computer
| science.
| dalyons wrote:
| practically all modern strongly typed languages are
| adopting or already had type inference from day one,
| allowing you to do things like var. They give up nothing
| in terms of strong typing to do so. Forcing people to
| write manual boilerplate does not equal professional,
| what a strange take.
| bottled_poe wrote:
| The engineering trade-offs are paid somewhere, better in
| an objective space than a subjective one.
| dalyons wrote:
| i dont know what you mean by this?
|
| Fundamentally, this is a story of technology getting
| better (type inference in compilers) so humans can do
| less work. We're not pushing the work to some other human
| place. We're not losing anything in safety, and we're
| gaining in readability, boilerplate and expressiveness.
| Its progress!
| wiseowise wrote:
| Nonsense is doing compiler work yourself, even bigger
| nonsense is duplicating for zero reason.
| toqy wrote:
| I prefer inferred types when available. Then an IDE and
| compiler can get together to provide further details when
| needed. Honestly f: MyStupidInterface = myStupidMethod();
| doesn't tell me much more.
| ivanche wrote:
| Now do the code review in GitHub. Ooops!
| RhodesianHunter wrote:
| Never have this issue. I'm not being hyperbolic either. I
| review Kotlin PRs every day and am never lost for context
| on a type.
| wiseowise wrote:
| I do code review on GitLab all the time, what's the
| issue?
| jeremyjh wrote:
| Yes but that isn't real code. If you see something like:
|
| > var conn = openDatabaseConnection();
|
| Are you actually confused about what conn represents? Does it
| matter what the exact type is, if you already know what it is
| and what you can do with it?
| kevmo314 wrote:
| Yeah it does, I don't really know what I can do with it. A
| type annotation would be useful to search for.
| LinXitoW wrote:
| I mean, you could just search for the method called, if
| you're REAAALLLLLYYY averse to using any IDE or editor of
| the last 10 years. Which would be an odd choice to base
| language decisions on.
| wiseowise wrote:
| Maybe you need to start using IDE, instead of programming
| in nano.
| kevmo314 wrote:
| Maybe you need to go work for GitHub to fix their code
| search references, instead of trying to act superior to
| random people on the internet.
| wiseowise wrote:
| I'm using Intellij, VSCode and Code Search for searching,
| why would I use GitHub for it?
| MajimasEyepatch wrote:
| In practice, the return type is often obvious. You can write:
| val foo = new MyReallyLongUglyFactoryClass()
|
| instead of: MyReallyLongUglyFactoryClass foo
| = new MyReallyLongUglyFactoryClass()
|
| And you never _have_ to use type inference. If you have a
| method where the return type isn 't as obvious, you can
| always annotate it explicitly: val foo: Int =
| doSomeThing()
|
| Do people exercise judgement about when to make the type
| explicit? Eh, depends on the team. But if you combine type
| inference with established conventions in a particular
| codebase (e.g. I/O calls always return IO[Foo]), you will
| rarely be left wondering what the type of something is.
| sorokod wrote:
| > With streams and the var keyword, Java is also not that much
| more verbose anymore than Kotlin
|
| In general Kotlin is more concise, checkout these comparative
| examples:
|
| https://stackoverflow.com/questions/34642254/what-java-8-str...
| nu11ptr wrote:
| Every time I think I maintain large code bases I just need to
| remember that someone else has a LOT bigger one. Wow, that is a
| LOT of Kotlin code.
| naikrovek wrote:
| can someone explain how Meta's code is so large?
|
| the tradeoff for high level languages is _supposed to be_ that
| you gain a lot of expressivity (requiring fewer lines for a
| developer to express their intent) and you lose performance
| because of the multiple layers of abstraction required.
|
| 10 million lines of code for an Android app, or family of apps,
| feels like the tradeoff has definitely not born fruit.
|
| operating systems written in Assembly have far fewer lines of
| code than this.
| david_allison wrote:
| Past discussion on why Uber's app is so big, many of the points
| are relevant:
|
| https://news.ycombinator.com/item?id=25376346
| naikrovek wrote:
| I feel like 10 million lines is still massive, given all of
| the points mentioned in that comment.
|
| UI pages must be immense in terms of lines of code.
| jrvarela56 wrote:
| This comment is a gem. Every HNer who has thought 'why do
| they need 100 engineers, I could do that in a weekend' should
| go read this now.
| criddell wrote:
| > why do they need 100 engineers
|
| You're off by an order of magnitude. Hundreds of
| developers? Sure. But Uber has _thousands_ of developers.
| jrvarela56 wrote:
| I think the point stands: the amount of complexity
| involved in each little piece of app is huge when taking
| into account dozens of countries and customizations by
| city.
|
| If it still doesn't seem worthy of 'thousands of engs',
| imagine breaking down every point in the list to the
| level of detail the author broke down payments. And then
| apply the logic in the top comment mentioning backend
| systems + teams to support other processes (and internal
| tools needed).
|
| Edit: sorry too much caffeine got me edgy.
| awinter-py wrote:
| interesting how much of this is glue -- like if mobile had
| better support for inter-app handoff, these flows could be
| entirely delegated to external provider's app (paypal, venmo,
| support saas)
|
| (though hard to generalize to other parts of the app, bc
| payments is inherently glue-y)
|
| constantly wonder what kind of support layer would make UX
| integration user-friendly, but also developer-friendly
| TillE wrote:
| Whoa. At first I didn't blink at 10M lines of code, but you're
| right they're talking strictly about Android.
|
| You have to factor in Instagram and WhatsApp, but
| still...that's a lot of code.
| naikrovek wrote:
| it really is. a sibling comment of yours points out some info
| posted by a former Uber engineer about why, and even
| considering that, 10 million lines seems extremely high.
|
| Windows XP is smaller than the Facebook app for Android...
| Kukumber wrote:
| If i were to do JVM related stuff, it'd use Kotlin without
| hesitation
|
| That language, just like with Swift and Haxe, they remind me of
| the good old Flash/ActionScript 3, i loved that language so much
|
| It's imo the best form of a programming language one can come up
| with, very easy to learn, read and write
|
| I wish kotlin-native story was better, it's a shit show, super
| slow to compile, and they decided to go with Gradle... it is on
| the same level of confusion and bloat as CMake, a pure mistake
| seanalltogether wrote:
| I've found that migrating all your trunk code (data and
| infrastructure classes) to kotlin is the biggest win, and you can
| leave your old leafs (fragments and view models) in java if you
| want do a low risk migration. If a view isn't broken, you don't
| need to fix it, but getting nullability annotations in your data
| models and REST commands is a huge win for newer views and
| business logic going forward.
| yotamoron wrote:
| How come we are reading content from this horrible corporation?
| fn1 wrote:
| Off-topic, but how the Facebook, Messenger or Instagram-app need
| _a million_ lines of code is absolutely beyond me.
|
| I had a few encounters with facebook's opensource code (mostly
| around react-native) and it is generally subpar in my opinion.
| aeyes wrote:
| Facebook is primarily a message and photo sharing application
| but it also has group boards, dating, live video streaming, a
| marketplace, browser games and probably more features. Then
| there are all the features for targeted ads, tracking, payment
| and so on. All of this is available almost all around the
| world.
|
| How do you implement these features for more than a billion
| active users in less than a million lines of code? Even 100
| million sounds like a low estimate.
|
| Why does the Linux kernel have more than 30 million lines of
| code?
|
| You could ask if these features make sense. But in the end it
| is their business decision to make.
| gpderetta wrote:
| how does the number of active users affect the size of the
| application?
| isbvhodnvemrwvn wrote:
| You need to support a huge range of devices and cultures.
| aeyes wrote:
| Aside from the technical challenges of running a system
| with such a massive amount of data:
|
| translations (left to right text and layout: https://sy-
| sy.facebook.com/), different laws depending on
| jurisdiction; for example privacy/moderation/takedowns,
| taxes/payment/invoices if you are selling anything,
| accessibility
|
| If you ever start a company and you have the long-term goal
| to offer your service in multiple countries I would advise
| you to launch in at least 2 countries, preferably
| supporting different languages.
| tantalor wrote:
| This happens with "everything" apps that have hundreds of
| features you have never seen, each serving a tiny fraction of
| the userbase who somehow stumbles on them and justifying the
| PM/eng resources to keep them chugging along, or abandoned and
| left to rot until these migrations come along.
| mkl95 wrote:
| My guess is that it's an extreme case of Conway's law, with
| many teams that produce mountains of code hidden behind some
| API. Not to mention codebases provided by external firms, which
| could amount to a large % of all those KLOC.
|
| I'm interested in how they avoid "Roman empire syndrome", as in
| owning more software than they can maintain while actively
| expanding it.
| barbariangrunge wrote:
| Rome held on to its land for a while. More like napoleon or
| Alexander syndrome
| [deleted]
| strulovich wrote:
| Hi HN! I'm the author of this post. I'd be happy to answer
| questions here on this subject!
| peterkelly wrote:
| Why does meta have 10 _million_ lines of code just for Android?
| wiseowise wrote:
| > just
|
| Where did this come from?
| [deleted]
| strulovich wrote:
| There's many reasons, so I'll give it a try:
|
| - There's a few apps here. Plus a bunch of tools.
|
| - The Facebook app is huge in terms of features. Just look at
| the menu with more things. I use very few of them, yet
| they're all pretty popular and justify themselves.
|
| - Instagram is smaller than Facebook, but still has a lot in
| it.
|
| - A lot of our code was optimized over time in many ways that
| add a lot of edge cases: internationalization, accessibility,
| optimizations for dealing with media, loading and data. It's
| can be easy to write something with much less code that looks
| pretty good at first sight, but all those extras really make
| the experience better and pay off for users.
|
| - We build new features all the time, some code may be
| unreleased, some is in A/B testing and so you can have two or
| more pieces of code that do the same.
|
| - A lot of test code.
|
| - Not that much dead code. Trust me. I love deleting code!
| And I will happily spend time removing bloat. There's
| definitely a lot of dead code to remove, but it won't change
| those top line numbers by much.
|
| (Also, it's 10M Kotlin lines of code, we have much more)
|
| (I would love to know how many lines of code the other really
| big companies with big mobile apps have for comparison)
| bottled_poe wrote:
| I too would like to know how this is justified.
| [deleted]
| nowherebeen wrote:
| > Today, our Android apps for Facebook, Messenger, and
| Instagram each have more than 1 million lines of Kotlin
| code, and the rate of conversion is increasing. In total,
| our Android codebase has more than 10 millions lines of
| Kotlin code.
|
| Probably 1000 engineers working on an app with each writing
| 1000 lines of code. I am not surprised Facebook app has >1
| million lines of code. The app is bloated with features
| that it's user _unfriendly_.
| kyawzazaw wrote:
| I have parents that are pretty not tech literate (they
| didn't how to save contact or send SMS) but they have no
| trouble navigating Facebook app for the core set of
| features they use.
| hu3 wrote:
| 1) Is that a mono repo?
|
| 2) If not, how many LOC is the largest Kotlin repo?
|
| 3) How do you tackle challenges of large codebases like
| language servers/synthax highlighting crawling to a halt in
| IDEs?
| loeg wrote:
| I don't know about this area in particular but almost all FB
| code lives in a handful of very large monorepos.
| strulovich wrote:
| 1 & 2) Yes, almost all of the mobile code lives in one repo,
| and the 10M number quoted is all in one mercurial repo.
|
| 3) There's a lot of different things we do to work around
| such issues. Some things that come to mind right now: - We
| have plugins for Android Studio to avoid loading all the code
| at once that help. - We had forks for the Kotlin plugin for
| Android Studio to deal with some issues that were worse for
| our repo. (especially around module loading) - We also worked
| with JetBrains by pushing some fixes and they fixed a lot of
| the issues over time. - We do a lot of work as async jobs
| that run on the repo without you waiting for them, so you
| don't have to wait for such tools.
| billjings wrote:
| Hi! Congrats on the huge accomplishment.
|
| Is that list of disadvantages really accurate? Reading them, I
| get the impression that the "popularity gap" between Kotlin and
| Java was a major reason FB was behind the industry on
| converting to Kotlin. (For context for non-Android engineers
| reading this, Kotlin has been the first party recommended
| language for 3 years now, and has been supported for 5 years) I
| can't imagine y'all were interviewing Android candidates in
| Java? And while certainly the Kotlin ecosystem as a whole is
| smaller than the Java ecosystem, the Java _Android_ ecosystem
| is miniscule.
|
| My recollection from my time in the building at IG was that
| build times and binary sizes were the two heaviest lifts,
| almost to the exclusion of anything else. Am I misremembering,
| or did the conversation change? Or does that list of tradeoffs
| reflect a realization by your team that you'd need to convert
| _everything_ to Kotlin, not just the Android code?
| strulovich wrote:
| > Is that list of disadvantages really accurate?
|
| I think this is a good depiction of our worries. Our biggest
| is and always was build times.
|
| > I can't imagine y'all were interviewing Android candidates
| in Java?
|
| We let people choose their preferred language for a while
| now. Also, while this blog is celebrating some milestones in
| the conversion, some smaller apps and new code was using
| Kotlin for a while now.
|
| > My recollection from my time in the building at IG was that
| build times and binary sizes were the two heaviest lifts,
| almost to the exclusion of anything else. Am I
| misremembering, or did the conversation change? Or does that
| list of tradeoffs reflect a realization by your team that
| you'd need to convert everything to Kotlin, not just the
| Android code?
|
| Binary size has generally not been an issue. Build times are
| an issue. We migrated and migrating some optimizations we
| have to alleviate that. We're also crossing fingers for more
| wins from the new Kotlin compiler JetBrains is working on.
| billjings wrote:
| I hear that KSP makes a huge difference, as you call out.
| Not an easy task to get rid of kapt, though, so - good
| luck! And again, congrats. :)
| [deleted]
| johnwheeler wrote:
| I know it's not the NYT, but just curious how it feels to wake
| up and see your work on the front page of HN
| strulovich wrote:
| It's pretty nice. :)
|
| This post is the (pretty short) summary of a lot of work
| which took us a long time to do. So it's nice to get any kind
| of validation.
|
| Personally I read HN a lot and it's my main source for
| interesting articles nowadays. So that makes me appreciate HN
| upvotes even more.
| [deleted]
| throwaway123f wrote:
| pantulis wrote:
| For us hackers, it's _better_ than the NYT!
| AnimalMuppet wrote:
| Yeah. NYT reporters don't show up here to answer our
| questions.
| david_allison wrote:
| Have you released the source code for the following (primarily
| running AS in headless mode). It's something I've wanted to
| look into adding into our CI:
|
| > As part of this step, we also apply our autocorrecting
| linters and apply various Android Studio suggestions in
| headless mode.
| strulovich wrote:
| No. It's pretty coupled with a bunch of our pipelines.
|
| I'll check again with the people who built it and see if it's
| doable to open source it.
| david_allison wrote:
| Thanks! If you manage to get it out in the open, could you
| send me a ping (email is on my profile). Happy to put in
| the effort to get it usable.
| zerr wrote:
| What's the share of React Native in your apps and where it is
| used? Also, what about Obj-C/Swift?
| strulovich wrote:
| I'm not the right person to comment on the React Native part.
| (There's definitely quite a bunch of React Native in the app
| on top of the Kotlin)
|
| Other people are also working on Obj-J/Swift, but from my
| superficial knowledge I think it's a much harder migration to
| do. I really think the Kotlin team did amazing language and
| tool design which makes Java to Kotlin migration easier than
| almost any other language migration I could think off. Kudos
| to them.
| bmc7505 wrote:
| Having used Kotlin on and off for the better part of a decade,
| the one thing I can say is that their editor support is unrivaled
| by any other language today. While Kotlin's build tools leave
| much to be desired (looking at you, Gradle), their focus on
| building a "toolable" language was the right thing to lean into.
| You can add all the fancy type system features you want, but if
| the IDE does not understand them, convincing users is going to be
| a hard sell.
|
| Whenever I try to get into another language today, the lack of
| language-aware editing tools are my main source of frustration -
| specifically, I expect navigation, refactoring and completion to
| work flawlessly. I know of no other programming language that
| puts as much effort into context- and structure-aware refactoring
| - if another language does one day replace Kotlin, it will need
| to offer a comparable editing experience.
| baby wrote:
| Back when I was doing audits, the only languages that really
| had good IDE support for that were objective-C / swift using
| XCode. You could get a caller hierarchy and get some sort of
| recursive dropdown menu to go through the entire call stack, it
| was magical.
| purplerabbit wrote:
| Have you tried TypeScript? My impression having used it in both
| JetBrains and VSCode is that it achieves basically what you're
| describing.
|
| I similarly get irritated using anything else now.
| randy909 wrote:
| I've used both and Kotlin was a better overall experience for
| me. TypeScript has weird typing problems far more often due
| to the underlying runtime being dynamically typed.
| purplerabbit wrote:
| What problems in particular have you run into? Genuinely
| curious.
| lf-non wrote:
| While I like TS and it is my primary language currently,
| having worked with Kotlin in past I find the dev
| experience with kotlin to much better, esp. if you steer
| clear of libraries that lean heavily on bytecode weaving,
| compiler hooks etc.
|
| Kotlin's type system is nominative and so while it is not
| as flexible as typescript (no intersection types,
| conditional types etc.) it also means that you don't run
| into those multi-page long type errors which need 5 mins
| of debugging to figure that some deeply nested object is
| null where undefined is expected.
|
| It is particularly funny when the language server
| truncates the errors and it becomes impossible to infer
| the actual issue from the message. Every now and then I
| find myself extracting things out of objects and adding
| type annotations to simplify the errors. It is doable,
| but never needed in Kotlin.
| bmc7505 wrote:
| Types in TS are Turing Complete [1], so any static analysis
| you build ontop of that language is bound to be unsound or
| undecidable. You could argue this rarely occurs in practice,
| but I would prefer a type system that is incomplete but sound
| and decidable. Incidentally, this issue also affects Java,
| which is both unsound [2] and undecidable [3]. Kotlin does
| have a fairly complicated subtyping relation [4], which has
| caused similar issues in languages like Scala [5], however
| whether the same issue affects languages based on mixed use-
| site and declaration-site variance like Kotlin is still an
| open question and requires further investigation.
|
| [1]: https://github.com/microsoft/TypeScript/issues/14833
|
| [2]: https://io.livecode.ch/learn/namin/unsound
|
| [3]: https://arxiv.org/abs/1605.05274
|
| [4]: https://kotlinlang.org/spec/type-system.html#subtyping
|
| [5]: https://arxiv.org/abs/1908.05294
| srcreigh wrote:
| Have you used TypeScript? Not only is it better type system
| than Kotlin, it has great IDE support in VSCode, AND there's a
| language server so you can get IDE support in Emacs/vim.
| ctvo wrote:
| Kotlin has one of the poorer LSP implementations out of the
| popular JVM languages. Last I tried it was buggy, and slow.
| Developers are pushed into using JetBrains products directly or
| indirectly (Android Studios) I suspect leaving the wider
| ecosystem poorly supported.
| Rapzid wrote:
| Last I was looking into Kotlin (couple years ago) they seemed
| hostile towards efforts to bring a similar level of support to
| editors outside the Idea family; basically they weren't going
| to do or support anything that threatened their "walled" garden
| of Kotlin + Idea. Is that still the case?
|
| As a huge fan of Jetbrains products (I maintain a personal IDEA
| Ultimate subscription) this was still a huge turn off to me.
|
| > I know of no other programming language that puts as much
| effort into context- and structure-aware refactoring
|
| Do you mean JVM language? TypeScript, C#, and F# at least come
| to mind.
| bmc7505 wrote:
| > Do you mean JVM language? TypeScript, C#, and F# at least
| come to mind.
|
| As I mentioned in another comment [1] on this thread,
| soundness and decidability are non-negotiable for me. Types
| in C#, F# and TS are all Turing Complete [2], and therefor
| these languages are tooling-adverse in the sense that static
| analysis is fundamentally unreliable.
|
| [1]: https://news.ycombinator.com/item?id=33329509#33332183
|
| [2]: https://3fx.ch/typing-is-hard.html
| wiseowise wrote:
| Literally majority of languages are either unsound,
| undecidable or both in the link that you've provided. The
| only exceptions are Haskell, Idris, ML and Go (given the
| date of the post, this was pre generics which would
| probably exclude it also).
| bmc7505 wrote:
| That's certainly a design choice they're free to make.
| Undecidability itself is less of a deal-breaker, although
| I would argue that a statically-typed language which is
| unsound defeats the purpose of having static types in the
| first place.
|
| Ideally, you want type inference to terminate in the
| amount of time it takes to type a few keystrokes to get
| realtime assistance, so decidability is still an over-
| approximation from a tooling standpoint and in practice
| anything strongly super-linear is not a fun experience to
| use.
| wiseowise wrote:
| I still don't follow how you came from
|
| > I know of no other programming language that puts as
| much effort into context- and structure-aware refactoring
|
| To soundness and decidability.
|
| Was there some study done where soundness and decability
| of Kotlin is provided?
| bmc7505 wrote:
| > I still don't follow...
|
| The premise was "toolability" in language design, which
| is one of Kotlin's main design principles. To do type-
| safe completion, navigation or refactoring, you need
| soundness, and to do it rapidly in the context of a live
| programming environment, you need to be able to resolve a
| type with keystroke latency. Rapzid asked [paraphrasing]
| "why not TypeScript, C#, or F#?" to which I responded
| that I do not consider these languages "toolable" because
| type checking is essentially broken (i.e., it might take
| forever, or give the wrong answer). > Was
| there some study done...?
|
| No, not that I am aware of. If you find one, I would be
| keen to read about it.
| koyote wrote:
| Have you ever used VS/Resharper/Rider with C#?
|
| I don't understand how you can come to the conclusion
| that type checking is broken and the language is not
| toolable? Can you give an example of where Kotlin's
| tooling achieves something that is not achievable at the
| moment in a C# IDE?
|
| (I've not used Kotlin much but I have never felt that the
| tooling for C# was lacking, so I am genuinely curious)
| jbellis wrote:
| I was actually very disappointed to find the kotlin
| refactorings lagging what for Java in IntelliJ. A few examples:
|
| https://youtrack.jetbrains.com/issue/KTIJ-12496/Provide-inte...
|
| https://youtrack.jetbrains.com/issue/KTIJ-10606/Support-movi...
|
| https://youtrack.jetbrains.com/issue/KTIJ-5063/Extract-prope...
| thomascgalvin wrote:
| I attribute this to the fact that Kotlin was developed by the
| same team that created IntelliJ, and fantastic IDE support was
| a requirement from day zero.
|
| A big part of why Kotlin works is _because_ IDE support is so
| fantastic now. And likewise, a lot of the reasons Java ties
| developers ' hands is because there was no guarantee about the
| IDE they would be using.
|
| As a trivial example, declaring variables. In Java, you have
| `final String foo = "bar";` while in Kotlin you can just say
| `val foo = "bar"`. They type is implied, but if you aren't
| sure, you can hover over `foo` and the IDE will tell you what
| the type is, so there's no longer a reason to type it out every
| time.
|
| Also, you can now have multiple classes in a single file. When
| Java was created, the one-class-per-file rule made _finding_
| the source code to a file easy; just do a `find` for
| `Classname.java`. But with a modern IDE, you can just command-
| click an instance and be taken to the source code
| automatically.
|
| Java's boilerplate is meant to make code discoverable, but the
| Kotlin IDE does that work for you, allowing developers to be
| more flexible.
| vips7L wrote:
| Perfectly valid Java for the last 4 years:
| var foo = "bar";
| pwdisswordfish9 wrote:
| Java supports curly quotes?
| vips7L wrote:
| iOS got me again!
| mathisonturing wrote:
| that's not final though, like val in Kotlin
| spullara wrote:
| we talked about having val as well in java but it just
| wasn't that interesting. if for some reason you think you
| need final you can use final var.
| danudey wrote:
| > As a trivial example, declaring variables. In Java, you
| have final String foo = "bar"; while in Kotlin you can just
| say val foo = "bar". They type is implied, but if you aren't
| sure, you can hover over foo and the IDE will tell you what
| the type is, so there's no longer a reason to type it out
| every time.
|
| This is something I've learned about Groovy that I really
| like. You can declare variables in multiple ways (terms are
| my own):
|
| foo = 1 # normal assignment
|
| var foo = 1 # declared assignment
|
| int foo = 1 # typed assignment
|
| A lot of our current code used the first "normal assignment"
| that you would see in shell scripts, Python, whatever.
| There's nothing interesting about this.
|
| I started using the second kind consistently. The "declared
| assignment" says "I am creating a new variable foo and its
| value is 1". If you are _not_ creating a new variable (i.e.
| if the variable exists already) your program fails. This is a
| great way to ensure you 're not overriding variables from
| earlier in the program or from another scope. My experience
| tends to be that this throws errors "now" for mistakes you're
| currently making (at this point in the control flow) by
| overwriting a variable that existed before.
|
| The last is a "typed assignment", where you're not just
| saying "I am creating a new variable", but specifically the
| type of variable is important. This errors if you ever try to
| misuse a variable down the road, and helps with ambiguity. It
| solves the "somestring = somestring.split()" issue of
| discounting a variable as the potential issue due to "it
| can't be this one, that's a string" being right for a while
| and then wrong for a while (or vice-versa).
|
| Anyway, all that to say: not having to specify data types is
| nice in some circumstances, but I've been leaning into adding
| data types to my code just to make absolutely sure I know
| what everything is all the time. Not having to in Kotlin
| sounds nice, but I hope there's a way to be explicit about
| everything.
| spullara wrote:
| You realize that Java has either released or has in preview
| most of the Kotlin features? Your example in Java 10+ is:
|
| var foo = "bar"; // you can add final if you feel like it
|
| You could always have multiple classes in a Java file as long
| as there was only one public class.
| Alupis wrote:
| > but the Kotlin IDE does that work for you
|
| So long as everyone on your team uses IntelliJ, then no
| problems. But not everyone uses IntelliJ, and now you've
| written code that is only easy to parse in a particular
| IDE...
|
| For this reason, and being able to read my own code outside
| of just my IDE (say, in Github, etc), I've found it more
| necessary to be explicit with my typing in Kotlin for all but
| the most trivial snippets.
| Jenk wrote:
| This is not a compelling argument. I'm not going to stop
| using a powersaw to cut beams just because another
| contractor refuses to use anything but his handsaw.
|
| Besides, reading implicit types has _never_ been an issue
| on any team or collaboration effort in the 30 years of my
| programming experience and I find it _really_ hard to
| believe anyone that claims it is a bonified problem for
| readability. In fact the complete opposite is true for me,
| personally, that too much information in front of me
| becomes noise and the signal gets lost.
| derefr wrote:
| They're not talking about someone using a hand-saw,
| they're talking about someone using a powersaw from a
| different manufacturer. Or, y'know, a table saw, or a CNC
| machine. Kotlin has tight integration with _one
| particular_ IDE, not with _all_ IDEs; let alone with
| things that are powerful in ways orthogonal to the ways
| IDEs are powerful, e.g. Emacs.
| psd1 wrote:
| "bonified" is a particularly satisfying bone apple tea
| Jenk wrote:
| yeah I've no idea why I spelled it that way.
| vkou wrote:
| Eclipse has feature-parity with IntelliJ in this space, it
| just has questionable usability and performance.
| LinXitoW wrote:
| Considering that many people willingly work with languages
| like Python and JavaScript, which make ANY IDE/Editors job
| of completion horribly difficult, the worst case is you end
| up with an editing experience on par with other languages.
| armchairhacker wrote:
| This is funny because the other language I think of which
| wouldn't be nearly as popular without an IDE, is Java.
| Especially older versions of Java.
|
| Java is way too verbose to be workable if I have to write out
| all of the class declarations and anonymous classes and
| "equals/hashCode/toString" boilerplate and
| "ExtremelyLongClassName foo =
| bar.extremelyLongMethodName(...)"; and there are too many
| pitfalls like comparing with "==" instead of "Object.equals"
| and implicit null. Except that I don't have to write out
| anything or worry about any pitfalls (well, implicit null
| still hits me sometimes, but @NotNull and @Nullable make it
| much less common) in IntelliJ. IntelliJ has such powerful and
| seamless analysis, it does aggressive code folding on Java 7
| so that you are looking at code with "var"s and lambdas. It
| also has built-in support for popular libraries like Spring
| and Lombok.
|
| IntelliJ single-handedly turns Java from a verbose, legacy
| language into _something I could actually recommend and start
| new projects on_ (although at that point I usually go with
| Kotlin). And Eclipse, NetBeans have very deep Java analysis
| as well. Java may have started off without expecting IDE
| support but now IDE support is responsible for a large part
| of its popularity.
| kaba0 wrote:
| Do you think the same for Go as well? Because Go is by all
| means much more verbose than Java.
|
| (But I do agree actually, a good IDE is much better
| investment than a minimal syntax revision)
| JAlexoid wrote:
| Yes. You either have a language that is easy or you have
| tooling to make it easy.
|
| If I cannot access documentation for a library/function at
| a mere tap of a button - that language isn't going into my
| toolbelt. I have to code in like 5 languages at my dayjob,
| that's at least 3 different types of semantics for ==.
|
| Java, and Kotlin, are great at that. It's the major pitfall
| for Scala(and a laundry list of others), on the other
| side(hey implicits and converters, that make even IntelliJ
| go "wut?"). Those long names in Java are actually a
| godsend. Give me "int indexInTheArray" over "int x" anyday.
| Explicitness of Python is also a pleasant thing to work
| with.
|
| People forget that most software is boring website
| backends, business processes and similar tools. Most devs
| don't have mental capacity to devote to "the one and only"
| language+platform+ISA.
| LinXitoW wrote:
| It's not just the tooling. Having tried to work with
| Python in Intellij, the lack of typing means you
| literally have to GUESS what any non-primitive object can
| do.
|
| It might also be an unhappy coincidence, but the library
| I was playing around with (scrapy) also had HORRENDOUSLY
| documented code. With Java/Kotlin, you can just click
| into any method/class and you'll get a useful doc string
| 99% of the time. With Python, I had to read the
| (incomplete) documentation.
| taeric wrote:
| This sort of flies in the face of how many people reject
| lisp systems, though. I could almost see that python is
| doing this, but the number of python users I have met
| that don't know how to use "help()" is... impressive.
| t-writescode wrote:
| I would argue that C# and Visual Studio (and maybe Rider) has
| as good, if not better tooling integration compared to Kotlin,
| especially considering nuget and sln files solve the "build
| system leaves things to be desired" part of your comment.
|
| This isn't to say that Kotlin isn't absolutely incredible, but
| I do not want to undersell the pleasure that C# is to work in
| with its tooling.
| jahewson wrote:
| > I expect navigation, refactoring and completion to work
| flawlessly.
|
| Same, but this was the case for C# in Visual Studio 20 years
| ago.
|
| > I know of no other programming language that puts as much
| effort into context- and structure-aware refactoring
|
| TypeScript + VSCode do all this and more.
| williamdclt wrote:
| what do you have in mind about refactoring support with
| Typescript and VSCode? Maybe I'm missing something obvious
| but the only "refactoring" functionalities that VSCode
| provides me are "rename this variable", "rename this file"
| and "move this export to a new file" (can't move to an
| existing file, and can't even chose the name of the new file)
| IshKebab wrote:
| Dart is also extremely good from a tooling point of view.
| goto11 wrote:
| C# also have great IDE support in VisualStudio _especially_
| with the ReSharper extension. Which is also developed by
| JetBrains.
| hansonkd13 wrote:
| Jetbrains and rust have brilliant refactoring. No idea how it
| compares to kotlin, but I can confidently move methods to other
| modules and files, rename anything, navigate to definition with
| no fear. Auto complete / auto import is also insanely good and
| is almost to the point where I'm auto completing almost every
| symbol because the IDE knows what I want precisely.
|
| I can't recommend jetbrains rust support enough.
| radicalbyte wrote:
| That's a JetBrains thing - they added loads of fantastic
| refactoring options to Visual Studio for C# which have now
| largely been integrated into the IDE directly. I've had an
| all-products subscription for close to a decade now and it's
| money well spent.
| bitL wrote:
| ReShaper was what kept JetBrains alive 10+ years ago and
| Microsoft couldn't release a new version of Visual Studio
| until ReSharper was ready for it due to how many people
| used/depended on it.
| einpoklum wrote:
| latenightcoding wrote:
| I'm interested in exploring Kotlin for backend development. But,
| most Kotlin projects, articles and anecdotes center around mobile
| apps. I imagine companies hiring Kotlin developers would mostly
| get applications from people with mobile dev experience
| fhd2 wrote:
| Maybe it's the wrong circles? Pretty much all the Kotlin
| developers I know (like four) do backend work.
| jillesvangurp wrote:
| There's very mature and widely used Kotlin support for Spring
| Boot. They've been actively supporting Kotlin for years and
| it's a well documented and well supported option in that space.
| Same for many other Java frameworks (e.g. Quarkus, Vertx,
| etc.). The reason is that it's so easy to integrate just about
| any Java framework from Kotlin and make it nicer by adding a
| few extension functions, turning builder soup into more
| readable Kotlin DSLs, getting rid of all the getter/setter
| madness or silly hacks like Lombok. I've converted a fair bit
| of Java code to Kotlin. You almost always end up with better
| code. Certainly less of it.
|
| The notion of Kotlin being a mobile only thing emerged out of
| the happy accident that the need to get rid of Java was simply
| felt so deeply in Android that developers were all over Kotlin
| even before it was released properly. Backend developers waited
| a bit longer.
|
| As a drop in replacement for Java it made a lot of sense there.
| Google at the time had the whole platform stuck on Java 1.6
| while they were engaging with Oracle in the courts. So a lot of
| the nice stuff in 1.7 an d 1.8 was not usable and forget about
| all the stuff that was added to Java and still is being added.
| Most of that you could get with Kotlin right then and there.
| So, people jumped on it.
|
| For the same reason, people have been using Kotlin with Spring
| since about the same time. Google and Spring made it official
| around the same time as well with Google outright labeling it
| as the preferred language for Android (while not cutting off
| Java) and Spring just adding an enormous amount of Kotlin
| specific features and extensions starting with Spring 5 and
| Spring Boot 2. At this point both have documentation for both
| Java and Kotlin. There are really no downsides to using Kotlin
| on the server. You can do everything you could do with Java and
| you gain access to a lot of easier to use stuff than the Java
| equivalent.
|
| I've been using it since before Spring supported any of Kotlin.
| Worked fine then and it only got better since. The language
| alone is worth switching and once Spring started actively
| supporting it, it only got better. I write asynchronous co-
| routine code with Spring by default. Mostly it just looks
| exactly like synchronous code. The only way you can tell is
| that my controller functions are suspend functions. Spring
| takes care of the rest. That makes everything easier: more
| readable logic, error handling, etc.
| melling wrote:
| "Shorter code: Kotlin's modern design makes its code shorter."
|
| How much shorter? How large would the code be in pure Java?
| usrusr wrote:
| A nice, simple kotlin left-to-right access deep into a nullable
| nested object tree can quickly be four lines of java for each
| and every '?.something', for as many of them as fit into your
| preferred line width. In java, this often leads to either
| skipping more null checks than you really want to skip, or
| calling getters more often than necessary.
|
| Kotlin might seem a little weak to someone returning from a
| scala deep dive, but where it really shines is in creating a
| large overlay between the convenient path and the pedantic
| path. It removes many "in the small" tradeoffs that you just
| take as a given in java. It's the "better java" that groovy was
| not.
| kaba0 wrote:
| If you have more than 2 levels of nested null-checks I would
| wager you are doing something fishy. You should probably go
| with mapstruct or similar libs (which are absolutely cool and
| a must for data conversions).
| ackfoobar wrote:
| > Kotlin might seem a little weak to someone returning from a
| scala deep dive
|
| I dismissed Kotlin for this very reason years ago. But after
| seeing bad Scala codebases, Kotlin feels like a breath of
| fresh air.
| david_allison wrote:
| Expect a 10-30% reduction with J2K, maybe another 5% once
| manual refactorings are made.
| belmont_sup wrote:
| What's pure Java?
| dr_faustus wrote:
| They should switch to Perl and replace 80% of the code with
| punctuation
| strulovich wrote:
| We actually made this number public in the post. It just
| appears laters around the conclusions sections.
|
| > On average, we've seen a reduction of 11 percent in the
| number of lines of code from this migration.
| melling wrote:
| I was hoping for more but 11% is still significant.
|
| So that's an extra million lines of code that didn't need to
| be debugged.
| kaba0 wrote:
| An extra million lines of {, @NotNull, .stream(),
| .toList().
|
| Hardly any code that would actually have bugs.
| strulovich wrote:
| We have a consistent braces style, so the lines that are
| removed are rarely those.
|
| A lot of the saves come from `?.` replacing null check
| chains. Many more from the shorter constructor and field
| initialization syntax (you can get a bunch of things in
| one short statement). A bunch more from usage of standard
| library lambda taking functions (`first`, `single`,
| etc.). Some more just comes from shorter lines due to
| less explicit types. These are all more some guesses due
| to conversions I've seen, and not the result of accurate
| analysis.
|
| We also use very little Java streams. A combination of
| Java 8 arriving late to Android code, and the preference
| to avoid extra allocations and inefficiencies streams can
| cause for shorter lists.
| krzyk wrote:
| I wonder how much of this could be reduced if they used
| records in Java.
| jillesvangurp wrote:
| There's also the line length to consider.
|
| I've seen the same on my own converted Java code. Less lines
| of code. But you also get lots of a really short lines. And
| some formatting actually spreads things out over multiple
| lines for readability. E.g. I use intellij's build in "put
| arguments on separate lines" a lot. Especially with named
| arguments, this is just nicer to look at. It's the same or
| less code but more lines. But less dense code.
|
| A more interesting metric might be simply the byte size of
| the source files. I would expect that to be slightly better
| than 11percent. Maybe closer to 20-25%.
| cies wrote:
| We're transitioning to Kotlin. And our main problem with it is
| slow compilation.
|
| With only Java is was <2mins and we're touching 10mins now.
|
| I'm not sure what exactly the problem is as we still have to
| investigate. Our use of Kotlinx.html (which we absolutely LOVE as
| HTML templating tech) seems to be a part of the problem, but we
| have not gone to the bottom of it yet.
|
| Nothing against the language, everyone on the team loves it (when
| Java is what we consider normal). The extra type safety we get
| out-of-the-box or have put some effort into (using KFunction all
| over the place) is really paying off.
| [deleted]
| mpweiher wrote:
| Interesting that they were able to quantify the reduction in
| source code length very precisely (11%), but when it came to the
| regression in build times ... nada ... just talk about how they
| plan to mitigate the issue.
| strulovich wrote:
| We don't have numbers around this because the numbers are
| actually really hard to make sense of.
|
| This probably sounds a bit weird, and it surprised me at first.
|
| Unfortunately measuring build times is extremely noisy:
| different people build different things. They do so at
| different times. On top of it we have incremental builds (so
| only some part, depending on the modularity and some external
| and in-house optimizations, gets rebuilt). The incremental
| builds depend on cached artifacts that need to be downloaded,
| and many more complications.
|
| The result is that if you look at the graphs the values jump up
| and down based on time, days, moods, network, and many more
| causes, plenty of which we have no idea what they are.
|
| I have not yet seen a successful attempt at cleaning this data
| up so that some number would be worth publishing. We could try
| building some toy example that we separated. But that won't be
| useful to guide our work on build times, nor do I think that it
| will be valuable to share with the community.
| peheje wrote:
| Same thought. We can only speculate but I'm guessing the
| compile time is much worse.
| peter_retief wrote:
| Good idea, I learnt Kolin to avoid having to use Java for android
| development. Only for one app it was still worth it
| jdhzzz wrote:
| why does navigating to this document, open a new tab, close the
| old tab. The result being there is no history that the "back"
| button (FireFox here) can get to. Seems like a lot of trouble to
| go to just to annoy me.
| ahahahahah wrote:
| More likely a big in Firefox... But sure just imagine it's
| whatever nefarious thing you want.
| commitpizza wrote:
| One thing that Kotlin got going for it is the tooling. I mean,
| the creator of Kotlin creates some of the best programming tools
| out there so I'd imagine (without actual experience of Kotlin)
| that it has great tooling.
|
| Sometimes, the tooling is even more important than language
| features IMO. It makes developers move quicker, find bugs easier
| and so on. I like the idea of Kotlin, that it can compile to jvm
| bytecode, javascript and native.
|
| So in essence, I can use the same language everywhere in the true
| meaning of the word.
| kramerger wrote:
| Obviously kotlin has great tooling, coming from an IDE company.
|
| But I think the main strength of Kotlin is it being so damn
| developer-friendly compared to Java and Scala.
| commitpizza wrote:
| Do you know of any good backend web frameworks for Kotlin? I
| would wish for something like FastAPI for python. Kotlin may
| actually be a great fit for a service I want to build and I
| hadn't really thought of it as an option until now.
| pfarrell wrote:
| A few years ago, I used dropwizard for both a service that
| ran locally and for the cloud backend at a startup. Kotlin
| meshed very well and we never encountered any issues with
| either. Also just worked on a project that used micronaut
| which was less mature and not very intuitive, but did
| support Scala and Kotlin (a goal in that project).
| arein3 wrote:
| Spring Web MVC
| treis wrote:
| That this has 5 different answers in 30 minutes is the
| problem I have with the Java/Kotlin ecosystem. There's just
| so much to figure out before you write a line of code.
| commitpizza wrote:
| Personally, I like that I have lots of options available.
| Compare it to .NET and it's "Microsoft way or the high
| way".
| pfarrell wrote:
| Agreed. Having to the ability to make those decisions is
| a feature of Java development, not a bug. YMMV.
| hardware2win wrote:
| Both approaches have pros and cons
|
| I prefer having one decent tool thats used across almost
| all projects like asp net for web
|
| instead of 5 things with their own quirks and pros cons
|
| Its annoying to have to relearn boring things on company
| change
|
| Like orms, web frameworks, etc.
|
| When you need custom solutions then you gotta put effort
| anyway
| kaba0 wrote:
| Well, spring is pretty much exactly that, and is probably
| used more than all the other mentioned projects combined.
| danieldisu wrote:
| Micronaut, http4k
| xwowsersx wrote:
| Ktor https://ktor.io/
| dotdi wrote:
| Nobody mentioned this yet: Vert.x
|
| It has great Kotlin support, including Coroutines. I've
| introduced it into our team for a major rewrite and we are
| very happy about 18 months in.
| malsanton wrote:
| Javalin https://javalin.io/
| piaste wrote:
| If you want something old and battle-tested, Spring Boot
| works just fine in Kotlin. I found the extreme OO design
| kinda off-putting, but once I got over it I had a great
| time with it.
|
| KTor [0] is the 'native' web framework for Kotlin, and
| there's also a full-stack framework built around it that
| just hit version 1.0, KWeb [1].
|
| [0] https://ktor.io [1] https://kweb.io
| commitpizza wrote:
| Well I care more about simplicity and easy to develop in
| rather than battle-tested. Something like the Javalin or
| http4k would probably suit me the best.
|
| Of course, I have checked Ktor before, but I don't know
| if I particularly fancy the way they are structuring
| stuff.
|
| My main issue with the java ecosystem is that it's way to
| enterprisy for my taste. Everything is so unnecessary
| complex and hard to reason about, but I will take a good
| hard look at Kotlin before making my decision. The thing
| is that I am really interested in the native compilation
| that Kotlin offers that would be very beneficial for me
| and the only reason behind picking Python otherwise would
| be that it is a nice language and already installed on
| the linux environments it will run in.
|
| Basically I will have a big api and drop (preferrably) a
| single binary to some machines that will talk to the api.
| These machines will generally be outside of my control. I
| have looked a bit on Rust but it seems a bit too low
| level and hard to work with. I have looked at Deno
| because it can compile down to a binary but using
| javascript for this project seems like a bad choice. So I
| chose Python at first because it seemed easy to get going
| with, had great tooling and is already installed in the
| environments I will be dropping a script in.
| [deleted]
| halfmatthalfcat wrote:
| There's been a lot of work in Scala land to improve tooling,
| see Mill as an SBT replacement.
| barrenko wrote:
| If only Kotlin had Scala's frameworks.
| JAlexoid wrote:
| > Sometimes, the tooling is even more important than language
| features IMO.
|
| That would be always. Tooling makes or breaks pretty much every
| language. Language itself is just a syntax that you write in.
| SpaghettiCthulu wrote:
| Have you ever actually tried kotlin native? Compiling a "Hello
| World" program takes at least 5 seconds. That's absolutely
| absurd.
| barbariangrunge wrote:
| The biggest advantage of a statically typed language over a
| dynamic one is the tooling. Refactoring statically typed code,
| after working with JavaScript for a few years, feels like magic
| because the tools just make it work
| [deleted]
| nordsieck wrote:
| > Sometimes, the tooling is even more important than language
| features IMO. It makes developers move quicker, find bugs
| easier and so on. I like the idea of Kotlin, that it can
| compile to jvm bytecode, javascript and native.
|
| The only thing I'd worry about is Java overtaking it.
|
| Do you remember Coffeescript? There was a point in time where
| it had impressive adoption, and quite a bit of buzz. But then
| Javascript added features, and all of a sudden the tooling
| burden associated with Coffeescript just didn't make sense any
| more.
|
| With Oracle's 6 month release schedule, that's a distinct
| possibility. Especially since Java can no longer rest on its
| laurels as a language (if Oracle doesn't want it to become
| Cobol 2).
| draw_down wrote:
| commitpizza wrote:
| This kind of happened to Groovy, but I think Kotlin was the
| killer in that case.
| JAlexoid wrote:
| Groovy was too much of a "scripting feel" to it, maybe
| because the primary project was Gradle.
|
| Scala had a massive much more prominent project to rely on
| - Spark.
|
| Kotlin is getting traction because of Android.
| RhodesianHunter wrote:
| > Kotlin is getting traction because of Android.
|
| Kotlin is seeing major adoption on the server.
| jillesvangurp wrote:
| Don't forget about WASM as another platform; it's coming as
| well. An experimental version actually ships with 1.7; it's
| just a bit unstable and under documented and very much a work
| in progress.
|
| I think Oracle is catching up slower than Kotlin has been
| evolving in terms of new language features. Most of the stuff
| they add to Java (including most of the stuff they are
| talking about adding), Kotlin has been doing for quite some
| time. Kotlin is pushing out minor releases about every 3-4
| months and major ones pretty much every year. Basically, they
| do 2-3 minor versions in between major ones. The pace is
| relentless.
|
| If anything, Kotlin could use an LTS release because it's
| actually getting hard to keep up with the ecosystem.
|
| A slower pace might be helpful with that. The main issue with
| frequent releases is that many libraries take weeks or even
| months to update and don't necessarily work well (or at all)
| with newer Kotlin versions. I've had repeated issues with
| e.g. code generation plugins requiring specific version of
| Kotlin breaking because some other library suddenly requiring
| something newer. So that then starts blocking a lot of
| library updates. We've actually put some effort in unblocking
| some of this for some of the dependencies we have by creating
| pull requests.
|
| But I'm excited about the next 1-2 years. I expect Kotlin
| native to stabilize and grow beyond just being a thing for
| IOS. I also expect wasm support will become usable in that
| time frame. I hope to be able to use it with WASI for edge
| networking or serverless stuff. And maybe even some command
| line tools. IMHO Kotlin has potential for data engineering as
| well. There is actually jupyter support for Kotlin. And some
| machine learning frameworks. It's becoming a proper full
| stack language.
| valenterry wrote:
| Yes that's right. In fact, Kotlin really works well with the
| IDE. But they didn't spend as much time in creating a
| language with a good and sound theoretical foundation. This
| works in the short time but shows its flaws later. Java is a
| bit better here (but quite slow though).
|
| So yeah, I can see Java potentially overtaking Kotlin.
| ajkjk wrote:
| Wasn't it Typescript that made CoffeeScript obsolete? Not
| better JS
| smt88 wrote:
| CoffeeScript never became popular in the first place. I
| stopped seeing it anywhere even before TypeScript caught
| on.
| MajimasEyepatch wrote:
| It was a thing for a hot minute in the early 2010s,
| before ES6, TypeScript, and the React/Angular/Vue
| trifecta came along and solidified what JavaScript would
| be from ~2015 onwards.
| hinkley wrote:
| I ran into Coffeescript code on GitHub for the first time
| in years last week. Oh, Coffeescript, I remember that
| used to be a thing.
| treis wrote:
| It was the default for a while for Rails apps and Wiki
| tells me GitHub & Dropbox adopted it before moving to
| Typescript. I think for Rails shops it was popular and
| there was a brief time where it looked like it might
| become the thing to do on the front end. But I don't
| think it ever got the interop with existing JS right.
|
| Ultimately, improvements to JS came along and took the
| wind out of CoffeeScript's sails. Then TypeScript came
| along and killed whatever interest remained.
| yamtaddle wrote:
| "Our codebase is in CoffeeScript" tended to draw grimaces
| for years before Typescript came around.
|
| And no, they serve totally different purposes. Coffeescript
| tried to make JS syntax and variable scoping behavior non-
| shit, while Typescript adds static typing while changing
| very little about the core language syntax.
| tentacleuno wrote:
| Really, it was a combination of both.
| Betelgeuse90 wrote:
| IIRC the main appeal of CoffeeScript was syntactic sugar
| like lambda expressions etc that were missing in ECMAScript
| 5. I think ECMAScript 6 made most of the appeal of
| CoffeeScript obsolete
| jgalt212 wrote:
| The availability of lodash made us dump any ideas our
| shop had about widespread coffeescript use.
| tinco wrote:
| When CoffeeScript came out, I vowed never to write plain
| Javascript again. I kept to that vow for a couple years,
| but eventually broke it when ECMA 6 came out. Really the
| only thing that put real technical justification behind
| CoffeeScript was the double arrow function, and maybe the
| neat class syntax. Beyond that CoffeeScript is just
| prettier. Even though I was in charge of choosing the
| technologies, you got to skate where the puck is going,
| and the puck was clearly not staying with CoffeeScript.
|
| ECMA 6 copied all the good parts out of both CoffeeScript
| and jQuery, effectively obsoleting both. Modern
| JavaScript is almost unrecognisably different from what
| it used to be, and that's a very good thing.
| sergiotapia wrote:
| You are correct. Typescript killed any momentum
| coffeescript had.
| ohgodplsno wrote:
| Kotlin is plenty safe for now.
|
| * Android is a massive platform, and Android is basically
| stuck on JDK8 (or JDK11 with desugaring, wooo).
|
| * iOS compatibility-ish. KMM is not ideal and mostly
| generates ObjC compatible objects (so generics are mostly
| screwed for Swift and writing iOS code is not ideal, but even
| being able to define common and enforced contracts is cool.
| iOS benefiting from projects like SQLDelight is super cool)
|
| * Jetbrains hedged their bets, and Kotlin/Multiplatform is a
| solid option. Coupled with Jetbrains Compose for UIs as well
| as having the entire Java ecosystem available is very solid.
| Compilation for so many platforms, directly to native
| executables is cool.
|
| * Java is still very slow to evolve. Kotlin has had data
| classes for a long time, Java recently added records. Inline
| classes offer some nice type safety at basically zero costs.
| Coroutines and structured concurrency are a beautiful way to
| work, and Project Loom would only build the foundations of
| that. Context extensions (while terrifying in the potential
| for spaghetti code they offer) are a useful feature, reified
| generics have some great potential.
|
| Now, Kotlin has its disadvantages too. Compilation times are
| not that great (hopefully K2 fixes this partly), but it's
| relatively safe and is kind of more than just a JVM language
| by now.)
| mbStavola wrote:
| I agree with everything you said except for "Java is still
| very slow to evolve."
|
| New Java versions are cut every six months since 2017 and
| since then has added a significant amount of new features,
| syntactical sugar, APIs, et cetera. Not only that, but
| they've also have been pretty aggressive IMO in deprecating
| and removing legacy. Very very different than the Java I
| remember working in years ago.
| quantified wrote:
| In HN a while back, an Oracle dev pointed out that the
| evolution is slow for a reason. Which confirmed slow. New
| releases every 6 months, but not that much in the way of
| changes. This isn't criticism of the fact of it or going
| into why it is or whether it should be that way. It's
| just a statement of fact.
| Alupis wrote:
| > New Java versions are cut every six months since 2017
| and since then has added a significant amount of new
| features
|
| And yet, the overwhelming majority of the Java community
| are still using JRE8 with none of these new features.
|
| There are some that love this new pace of language
| development, but very few are actually using new features
| in production code.
| yardstick wrote:
| The hesitancy in jumping beyond JRE8 is the large
| backwards compatibility road bumps in JDK9-11, and now
| again with 17/JavaEE->Jakarta. I wish Java would continue
| to add new features but be a lot more considerate of
| avoiding, completely, migration headaches.
|
| We are migrating Java 8 -> 17 now and it's been a right
| royal pain. I'm glad we didn't jump to 11 LTS, and
| instead make one big leap. It might be a very long time
| before we do another LTS upgrade if they keep making poor
| migration choices.
| kaba0 wrote:
| The only relatively bumby migration was 8->9. After that
| it is a very smooth ride, and that bumpiness was the
| price for the accumulated tech debt/slow down from the
| end of the Sun era.
| Alupis wrote:
| Well, my understanding is (but I have yet to personally
| experience) the migration from 17 -> 18+ is rough because
| of all the javax.* packages being renamed jakarta.*
|
| Which likely means touching a pretty significant portion
| of your codebase for the upgrade, and then who knows what
| 3rd party libraries you depend on are expecting...
|
| So it may be as simple as Find/Replace for some folks,
| for others, it might be a deep dark rabbit hole.
|
| Not breaking things used to be Java's MO. Yes, that means
| a ton of legacy cruft built up over the years... but we
| used to be able to depend on Java to "Just Work".
|
| Perhaps some of this is necessary. After all, the C#
| folks seem to have no problem breaking everything to add
| new features... but I'd assert the Java community as a
| whole is much less tolerant of breaking changes and rapid
| deployment of features.
| weego wrote:
| You're correct of course, but to back up the parents
| comment, they do have a habit of implementing things
| other than the low hanging fruit that developers are
| frustrated not having, leading the drive towards other
| jvm langs
| mbStavola wrote:
| What are some examples of those low hanging fruits?
| origin_path wrote:
| Just browse through the Kotlin standard library. It's
| basically just a set of mappings to the Java standard
| library with a whole lot of extension functions to make
| it easier to use.
| ohgodplsno wrote:
| Functional/SAM interfaces (transforming interfaces with a
| single method into a simple lambda), pleasant usage of
| lambdas (last lambda parameter can be put outside of the
| call like(this) { ... }, leading to a language that lends
| itself really well to building a DSL, coroutines were not
| a low hanging fruit but absolutely are infinitely more
| pleasant to use than RxJava, operator overload including
| invoke(), ranges that are pleasant to use (0 ..
| 10).forEach { }, or when (floatVariable) { in 0.0f ..
| 1.0f -> ... }, pattern-ish matching with when (not quite
| full on functional language powerful, and I believe that
| Java is not only catching up to it but making their
| switch quite a bit better), a standard lib that is packed
| full of extremely useful and consistently named methods,
| extension functions, delegation (if you inherited a SDK
| that has a piss poor interface, you can simply make a
| SDKWrapper(val internalSdk: SDK): SDK by internalSdk,
| which means that it will automatically implement it, and
| you can then have your wrapper do whatever around it
| (logging, better functions, DI, etc.)))
|
| Kotlin is truly a pleasant language, both when you don't
| know it (although it can look a bit symbol soup-y at
| times for juniors), and when you fully know it.
| kaba0 wrote:
| > iOS compatibility-ish
|
| I don't know how well it works, but we have seen these
| kinds of projects, and they seldom work as is. Not sure how
| well Scala Native works, even though it predates Kotlin's
| try. (Though scala.js is surprisingly good!)
|
| But do you really think that a relatively young language
| like Kotlin with minuscule adoption (compared to java) will
| be better at this game then Java?
|
| Java has a _very_ good compiler to Js maintained and used
| heavily by Google (j2cl, part of their closure compiler
| toolkit), which can also output obj-c code. These are /were
| used heavily for porting their shared libs between
| basically all platforms.
|
| For native, Graal is a very cool way forward benefiting all
| JVM languages (as well as scripting languages, its polyglot
| features are insane).
|
| > Java is still very slow to evolve
|
| Is it a problem? The majority of developers don't like
| running after the language, even though it may seem so
| based on online hype circles.
| ohgodplsno wrote:
| >I don't know how well it works,
|
| Well enough, provided you stay within the known bounds.
| Hell, some people at Touchlab even went as far as porting
| Jetpack Compose to work on iOS (which, uh, I would not
| recommend in its current state), and it technically
| works. I probably wouldn't recommend writing all of your
| app logic in Kotlin, but being able to share the data
| layer is amazing.
|
| >But do you really think that a relatively young language
| like Kotlin with minuscule adoption (compared to java)
| will be better at this game then Java?
|
| It depends on where you're looking. Most modern android
| development will most likely be done in Kotlin. Backend
| work, for things started relatively recently, Kotlin is
| not surprising. But mostly, Java does not make iOS
| compatibility a goal. Java tell you "get a JVM and run
| our shit" (or get GraalVM and have basically an embedded
| JVM). Kotlin has two sides, and Kotlin/Native does not
| depend on the JVM.
|
| >Java has a very good compiler to Js maintained and used
| heavily by Google (j2cl, part of their closure compiler
| toolkit), which can also output obj-c code. These
| are/were used heavily for porting their shared libs
| between basically all platforms.
|
| j2cl still brings in a light JVM to the Web. Kotlin does
| not. It provides interop to the JS APIs as well as its
| own tech, but it's not meant to take your Kotlin code and
| immediately run it on the web (which is an awful, awful
| idea). You're still meant to write your browser specific
| code, your android specific code, your x86 specific code,
| etc. In any language you want, even! Write it in
| Kotlin/JS, or let your typescript consume the Kotlin/JS
| bindings. However, you can have a common base that'll
| work everywhere.
|
| > For native, Graal is a very cool way forward benefiting
| all JVM languages (as well as scripting languages, its
| polyglot features are insane).
|
| Graal is an extremely cool project, but with different
| goals. Write once, run everywhere is a lofty goal, but it
| only works on very similar platforms (Windows/Linux/OSX).
| Kotlin has taken a Write once, specialize what is needed
| approach.
| andrekandre wrote:
| > but being able to share the data layer is amazing.
|
| why not just use swagger/openapi + auto generated models?
|
| adding kotlin native adds huge depenencies relative to
| the tiny benefit of a datamodel that can be auto
| generated to native code imo
| kaba0 wrote:
| > even went as far as porting Jetpack Compose to work on
| iOS
|
| Well, Gluon promises the same for JavaFX apps and there
| is a sample app actually downloadable from the AppStore.
|
| > j2cl still brings in a light JVM to the Web
|
| Not at all, it compiles to _very_ optimized Javascript.
| Oh, and I forgot to mention that there is also teavm,
| which is not a VM contrary to its name -- this latter
| transforms java byte code so it works with guest
| languages as well.
| bitexploder wrote:
| Do languages really need new features every N months to
| stay relevant?
| ohgodplsno wrote:
| Depends. Is stuff like context receivers
| (https://nomisrev.github.io/context-receivers/) needed ?
| No, although it's a fun experiment. Are multiple
| receivers needed
| (https://youtrack.jetbrains.com/issue/KT-10468/Multiple-
| recei...) ? Not really, but when you are dealing with the
| JVM, nested class hell is a very common thing, and
| cleaning up your code is always pleasant. Implicit
| namespacing ?
| (https://youtrack.jetbrains.com/issue/KT-11968/Research-
| and-p...) Fun thing to get.
|
| The thing is, they're all optional. You're never going to
| use any of these features if you don't need them. Your
| code can stay as a nested list of calls. But put them all
| together, and you can have code that is super explicit
| about what it needs to do, without having to re-pass
| things that are already there.
| kaba0 wrote:
| No, but fortunately Java doesn't do that. They have long
| running projects, when one is nearing completion it will
| be put in preview in the upcoming release. No rush to
| make it into anything, it's ready when it's ready. (Which
| should be copied by the rest of the industry as well)
| AnimalMuppet wrote:
| Depends. Are the features making things better, or just
| more complicated?
|
| Even if it makes things better only for, say, 10% of
| users, but doesn't make it worse for the other 90%... the
| users will take that every N months for as long as the
| language authors can do it.
| nordsieck wrote:
| > Do languages really need new features every N months to
| stay relevant?
|
| I think a fixed N month release schedule is much
| healthier than what Java did before, which was wait until
| everyone was on the bus in order to ship, which resulted
| in multi-year delays.
| yCombLinks wrote:
| Slow to evolve and long-term backwards compatibility are
| selling points.
| biztos wrote:
| I'm not a Kotlin user, but this struck me as ambitious:
|
| > having the entire Java ecosystem available
|
| and, in the same point:
|
| > Compilation for so many platforms, directly to native
| executables
|
| Does this mean you can compile pretty much any Java
| libraries to non-JVM executables?
| MrPowerGamerBR wrote:
| No, if you are targeting a different platform you can't
| use JVM libraries.
|
| If your target is JavaScript, you can use JavaScript
| dependencies (sort of: they won't have any type bindings
| so you will need to code then yourself) but you can't use
| any JVM libraries on it.
| slively wrote:
| No, if you use Kotlin native you do not get access to
| Java libs.
| ohgodplsno wrote:
| As other said, yep, you do not get the Java ecosystem if
| your target is native executables (or JS). there are
| alternatives like kotlinx-datetime, kotlinx-
| serialization, the kotlin stdlib. However, if you know
| you're going to stay on a JVMable target, feel free to
| not use Kotlin/Multiplatform, but regular JVM Kotlin
| libraries
| zendist wrote:
| I don't know about that comparison. CoffeeScript transpiled
| to JavaScript- Kotlin doesn't transpile to Java, it compiles
| to JVM bytecode.
|
| So in a sense, from a tooling and compiler perspective,
| they're orthogonal products, similar (I guess) to C# and F#
| on the .NET CLR VM.
| dima_vm wrote:
| As for me the greatest appeal of Kotlin is that it doesn't need
| its own tooling that bad, it feels like just syntactic sugar
| over Java.
|
| Both Scala and Kotlin can reuse Java tools, but with Scala it's
| awkward (and some tricky generics simply don't compile with
| Scala).
|
| E.g. if I need to parse something, I search for "how to parse
| that in Java", not "... in Kotlin".
| hocuspocus wrote:
| > and some tricky generics simply don't compile with Scala
|
| What? Do you have any example that wasn't fixed years ago?
|
| Any non-trivial Scala app will consume dozens if not hundreds
| of Java libraries, without any issue.
___________________________________________________________________
(page generated 2022-10-25 23:01 UTC)