4 ms·
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 vigi
by anthlax 4y ago
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 4y agoHow does this work in a SOA situation? Like do you have null checks + default values at every HTTP boundary for your application?
- anthlax 4y agoMost 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 4y agoBut 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 4y agoTo 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 4y agoTo 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 4y agoI 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 4y agoYeah, 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 4y agoI'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 4y agoThe question is how do you handle the empty case for the hundreds of fields you pull from other systems.
- acchow 4y agoYou 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 4y agoWhile 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)
- lmm 4y agoYou might like Scala (possibly enhanced by something like Monadless or Each , but personally I find the explicit for/yield approach very worthwhile).