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.
From Java to Kotlin and Back Again
171–180 of 199 posts
Re: From Java to Kotlin and Back Again
#172Earlier 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
#173I'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,…
Re: From Java to Kotlin and Back Again
#174Ok, 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.
Re: From Java to Kotlin and Back Again
#175An article about Java's warts written with the same pettyness as the author would probably be the length of a small novel.
Re: From Java to Kotlin and Back Again
#176Earlier 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?
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
#177Below, 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
#178Re: From Java to Kotlin and Back Again
#179Earlier 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?
Re: From Java to Kotlin and Back Again
#180Earlier 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…
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.