Live data from Hacker News

From Java to Kotlin and Back Again

allegro.tech

171–180 of 199 posts

Re: From Java to Kotlin and Back Again

#171
post #69

Earlier quoted context omitted.

filter, flatMap etc. are provided as extension functions for collections - see http://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collectio...

Yeah, but to me not having Optional with the same interface, and instead language-level syntax for working with nullables, does smell like bad design.

To me java.util.Optional is a crutch; an afterthought. I think it would never come to exist if nullability was done right to begin with. Native approach feels cleaner... to me, of course. For starters - in the context of the quoted code example - what sense does it make to have to allocate a new object (via Optional.ofNullable) every single time parseAndInc calculation is performed?? Wrapper types always involve overhead... perfectly avoidable with a language-level, as opposed to library-level, implementation

Re: From Java to Kotlin and Back Again

#172
post #134

Earlier quoted context omitted.

Re immutable: If you're doing functional why does this matter? "true" immutable vs. just an immutable view should only matter if the object is retained by the function it's passed to, but now we're talking object state rather than pure functions. Re "command-like" objects: I'm not following, can you give an example of something you can do in Scala here that you can't in Kotlin?

> Re immutable: If you're doing functional why does this matter? "true" immutable vs. just an immutable view should only matter if the object is retained by the function it's passed to, but now we're talking object state rather than pure functions. For the same reason that being able to write val rather than var matters. With perfect discipline you can write pure functional code in any language, but in practice (and…

  For the same reason that being able to write val rather than var matters. With perfect discipline you can write pure functional code in any language, but [...]
Strongly agree with you there. This is one of the main gripes I've got with many languages. People just have a "well don't do it" attitude and refuse to see the benefit in the possibility of forbidding mutation. A very important point here is the realization that while the part about discipline might be true, it isn't just your discipline the whole codebase might hinge on, either.

This is the exact reason why making it easy to do the right thing is a very important part of API design; simply by making hacks more laborious than the sane thing to do, you effectively prevent them most of the time.

Re: From Java to Kotlin and Back Again

#173
post #169

I've said it earlier, I am saying it again. "Kotlin enthusiasts or rather PR representatives cannot stomach criticism", this is quite visible on the blog itself and here on HNews. Consult with your CEO, CTO and/or Director of Engineering before switching to Kotlin, there may be things you might not be aware of, think 20 years ahead and think objectively about the pros/cons before heeding to advice of the enthusiasts,…

I agree, very well spoken!

Re: From Java to Kotlin and Back Again

#174

Ok, so, assuming that all the things he mentioned are just nitpicky, what's the upside of Kotlin over Java 10? Lots of people would need adequate training, perhaps some new tools and rewrites. There needs to be a serious upside to get a mainstream company to a niche language.

Major thing for Android developers is that the adoption of new Android versions is so slow, we're really stuck with Java 6/7 features. While backend can happily update to Java 15 on their own terms, we're limited by Android OEMs to provide updates to their phones. This is one of the reasons Kotlin is so popular with Android -- you get new Kotlin features when you want to, not when all of your app users buy new hardware (and good luck convincing business people to ditch 10% of the users on old API versions). While we get support for Java 8 (but not 9 or 10) language features via special tool, we still don't have access to Java 8+ APIs.

Re: From Java to Kotlin and Back Again

#175
post #42

An article about Java's warts written with the same pettyness as the author would probably be the length of a small novel.

I would bet that back in 199x there would have been countless articles (more like usenet posts) about "from C++ to Java and back" telling all the downsides and gotchas with Java.

Re: From Java to Kotlin and Back Again

#176
post #147

Earlier quoted context omitted.

I must admit I don't entirely understand how your approach works, but it seems like it requires all the functions you want to use in transactions to live on MyTransaction (even if only as extension methods)? I want to be able to write normal functions including quite high-level ones that take some business objects and return MustHappenInTransaction[SomeOtherBusinessObject], and pass these return values through generi…

typealias MustBeInTransaction = MyTransaction.() -> Unit fun makeObject(i: Int): MustBeInTransaction { return { /* do something with i or whatever in a transaction */ } } fun test() { var genericArray = arrayOf(1, 2, 3).map { makeObject(it) } //genericArray.forEach { it() } // fails to compile transaction { genericArray.forEach { it() } } } Like that?

It is interesting to see that is possible in Kotlin. I just learned a lot about receivers (as an aside, do you know where I can find better documentation? The best I could find was a stack overflow post).

I think this issue with this is what happens when you combine DB transactions with async queries with errors and null handling? It seems like you have to combine 4 different mechanisms in order to do this (receivers, async/await, try/catch, if(null)). Is there some way to do this all with receivers? It seems like they don't really compose.

The 'command' version in Scala could be written roughly the same way for any combination of the 4 features (the types would just change). For example you could write a Scala version of your original example as:

    def test(): Unit = {
        // update() compiles but doesn't do anything to the DB
        val helloDBOperation = for {
            _ 
This would look almost exactly the same no matter which combination of the 4 features you use.

EDIT - it looks like I somehow also accidentally replied to you with an earlier version of this comment. Unfortunately , I didn't notice until it was too old to delete or edit. Please ignore the other comment that is very similar to this one. Sorry about the confusion.

Re: From Java to Kotlin and Back Again

#177
The particularly funny thing is how the blog admin - the author himself? - censors comments not to their liking, marking them as spam : ) They clearly are a bit touchy.

Below, the comment he's deleted twice; you be the judge :) (I wouldn't normally repost, but the first time round I erroneously assumed it was due to including a link in it; apparently not).

----

The article has been commented extensively on Hacker News. I'm not pasting the link, as this gets my comment marked as "spam" (go figure), but it's trivial to find it with very basic google-fu.

Now, while I don't approve of the unneccessarily biting tone of some of the remarks posted there, I think it's been demonstrated convincingly that a large share of this Kotlin critique is highly dubious at least.

I believe that in general the longer we work, the less eager we are to learn new stuff, and we become more set in our old ways. It's only natural and human, but often we go to great trouble only to rationalize this attitude somehow. And that's what should set your alarm bells ringing. For the sake of your own development, nobody else's.

Publicly criticizing a language without even knowing its standard library (as evidenced by the "Integer.tryParse" example, which indeed runs into troubles, but only because it's outright wrong - see the comments on Hacker News for more details) seems premature, especially for a veteran programmer like the author.

----

To me there are two takeways here; more important than Kotlin. Two factors that inhibit our professional development, especially in the long run, once we're "seniors" already.

The first is what I already pointed out in the blacklisted comment, above.

The other is sort of self-evident now; and that's the ego problem. Not only we become conservative over time; we also develop an oversensitive ego, and conversely, an allergy to being corrected. I really hope I won't fall into this trap myself... I sure as hell exhibit similar signs now and then

Re: From Java to Kotlin and Back Again

#179
post #147

Earlier quoted context omitted.

I must admit I don't entirely understand how your approach works, but it seems like it requires all the functions you want to use in transactions to live on MyTransaction (even if only as extension methods)? I want to be able to write normal functions including quite high-level ones that take some business objects and return MustHappenInTransaction[SomeOtherBusinessObject], and pass these return values through generi…

typealias MustBeInTransaction = MyTransaction.() -> Unit fun makeObject(i: Int): MustBeInTransaction { return { /* do something with i or whatever in a transaction */ } } fun test() { var genericArray = arrayOf(1, 2, 3).map { makeObject(it) } //genericArray.forEach { it() } // fails to compile transaction { genericArray.forEach { it() } } } Like that?

Yeah, like that. But if code like that is permitted, is there anything that stops me writing a method that stashes a MyTransaction.() in a variable and then using it in another method long after the transaction it's supposed to represent has been closed?

Re: From Java to Kotlin and Back Again

#180

Earlier quoted context omitted.

> Optionally ignoring thread safety seems indefensible Nobody forces everything to be thread safe. That would either be suicidally complex or suicidally slow. The problem isn't so much "ignoring thread safety", it's that this: class Foo(var thing: Int?) { fun doSomething() { if (thing != null) { thing++ } } } doesn't compile and it should . It fails to compile claiming that 'thing' could have changed in the meantime,…

They can't ever prove it; even just class Foo(var thing: Int?) { fun doSomething() { if (thing != null) { thing++ } } } is unsafe as any class user could cons up a Foo t, and call t.doSomething() while racing a modification to t.thing in another thread. There either needs to be a language feature for Foo to live in a restricted threading context or the whole construct is irreparably thread-unsafe. The error is valid…

You're again asserting thread unsafe mutations as a reason. It is not. Or if it is Kotlin is just wrong. Guarding against null in an unsafe thread race is pointless to the extreme. That didn't fix anything. It's pointless to complain about it ever. It's a wrong error in that fixing the error doesn't fix the bug in the code.

There is no possibility of any kind that my snippet is null-unsafe exclusively. My code is null-safe in all situations where the resulting behavior is also correct. And the compiler could trivially prove that.

If they wanted to actually take a stab at compiler-audited thread safety they should add some annotations or such to mark what is guarded by what. Otherwise the only reasonable assumption is to assume thread-compatible. Which my code also runs correctly in.

Post reply on HN