<@U2E974ELT> I must say this article of yours <htt...
# coroutines
p
@elizarov I must say this article of yours https://medium.com/@elizarov/structured-concurrency-722d765aa952 scared me a lot about the way Kotlin is developed. All these months coroutines were out we were being convinced that the "experimental" flag is just an unfortunate naming. That they are pretty much close to being stable and fully thought out yet the article hints that you truly had no idea what you were getting into. I think the changes proposed in the article are last-minute and quite drastic. How are we supposed to be comfortable about adopting coroutines now? What if you made a huge mistake somewhere again?
Unfortunately, this example is wrong on many levels in very subtle ways.
Seriously? So all these talks were full of completely wrong examples? And you just found out? It's not like these concepts are completely new to computer science, why not take more inspiration from other languages such as
clojure.async
?
e
We constantly take inspiration from all the other languages. C#, JS, Clojure.async, F#, Erlang, Akka and many others.
But we are also trying to improve. Our original designs were mostly inspired by the above and we’ve found all those problems while playing with them.
For example, nobody really tackled interplay of parallel decomposition and boiler-plate free cancellation before
Other langs from the above list either don’t have cancelation, or it requires a lot of boiler-plate to work correctly, just like our original design did.
So, we’ve fixed it.
That’s how the forward progress works
👍 17
Just FYI, cancellation in all the future-based frameworks (like Clojure.async) is typically broken in much more horrible and even subtlier ways
k
fwiw, my reaction to the article was excitement
8
it sounded more to me like you’ve finally solved a lingering nasty edge case
p
Thanks for the follow up. I guess I would just recommend being careful about thinking you have "solved" it since nobody else really did yet. It will probably require very thorough testing in different use cases especially because it's a brand new approach.
k
perhaps at the expense of some API breakage…
cancellation and lifecycle in general has always seemed a little murky. hopefully with this new implementation and updated documentation that’s no longer the case
p
to me API breaking does not matter at all (at the moment), I am just worried about similar "realization" in 3 years when my code is full of coroutines
e
btw in Go cancellation/timeouts is pain in the ass
i like new concepts of new dispatchers and coroutine scopes, feels more intuitive
k
@poohbar I see your point, but maybe that’s the risk when adopting any new technology
you adopt it and 1) it works out, 2) it gets iterated on and fixed, or 3) it’s a failure
p
yeah
k
caveat emptor
r
@poohbar Regarding the disappointment I seem to read in your message concerning the communication around the "experimental" flag, I'm not sure where you get that from - to me, the communcation was pretty clearly "The concept is solid and coroutines are production-ready in function, but the API might still undergo some breaking changes", which is exactly what they did right now.
1
p
Robin, I just that the new changes are more than an API change.
k
i think this is less about API breakage and more about a fundamental shift in implementation and usage
p
exactly
k
this is actually the 2nd big fundamental shift I can remember since the original introduction
p
API change would be renaming
launch
to
unleash
k
to me, seems to be going the right direction each time, and the benefit i derive from coroutines far outweighs the risk
👍 1
p
And I am just saying this because I saw the Jetbrains team becoming quite agitated by the slow adoption of coroutines which they blamed on people being too afraid of the "experimental" word. Now it just looks that we were right and coroutines truly were experimental in every sense of the word.
just my 2 cents 🤔
k
that’s true, but… code I shipped using the past versions of coroutines hasn’t suddenly stopped working
i’ll update it and test it, then ship that when it’s ready. another hypothetical future shift doesn’t really matter if it works
r
I disagree - it's a rather big API change, yes, but coroutines still work the same way they did before, it's just the need of explicit scoping that's now added. Again you potentially need to do quite some work to migrate, but that's still part of the API to me, and not the actual inner workings. Or am I missing something here?
k
he’s not worried about API changes, he’s worried because JetBrains didn’t materialize a perfect design on the first try 😉
💯 3
p
We can agree to disagree, no need to dwell on this. I just wanted to voice my opinion which I did so we can carry on. 🙂
d
Also
All these months coroutines were out we were being convinced that the "experimental" flag is just an unfortunate naming.
The experimental was precisely to warn that API could change. It regularly did (cf the recent
IO
dispatcher) so we were not convinced that this API was stable. So yes, we have a lot of refactoring if you're enthusiastic like me with coroutines. But JB warned us.
e
Going forward we’ll be finalizing key parts of API. It means full compatibility for the future changes. It means that if we suddenly discover some design issues we will not be able just to fix them, but we’ll have to introduce new, better APIs, and then gradually, very gradually, migrate users to it.
That’s why we want to get it as good as we can before 1.0 release, that is why we have this “experimental” phase where we can let users play with it and give us feedback. If you actually looks at many APIs in many other languages you’ll notice lots of horrible mistakes that were made simply because designs were rolled out before letting actual users play with them
👍 21
j
It took a long time to hash out the best practices for Java development across many years, developers, companies. Some things in the language are now set in stone
I prefer JB approach
👍 1
d
Even if I don't necessarily agree (I think the experimental namespace made it clear), I'm glad that this has been brought up. Questions like these are always good and keeps everyone honest @poohbar
👍 4
j
@poohbar On the contrary, I am pleased and reassured to read this kind of article. It means they are still challenging and improving the solution, not mater how long it has been out. For someone who already learnt coroutines, Concepts of this new release are easy to grasp and are actually a great solution of problem encountered when writing code with coroutines. And migrating to the new version is just a pleasure moment. The migration is quite safe (old API is still here deprecated), and from now on it is simpler to write safer code. What more could we expect?
💯 1
d
While I don't necessarily think I like the API changes that were associated with this shift in ideology - I do think that it's good to make the changes now. The
experimental
part of the package was dropped with Kotlin 1.3-M1 - but this in itself is an experimental release. Nothing about coroutines is finalized until Kotlin 1.3 - and this is something you agree to when you use the technology. On the other hand, JB are leaving a lot of deprecated functions in the library and I wonder if they plan to remove them at all or not.
My two cents on that: It's not necessary to have backward compatibility with prior versions that were experimental - only with prior versions that were releases. Developers just need to update their source code if they update to the 1.0 release of coroutines, or just stay on the experimental ones.
e
1.0 release of
kotlinx.coroutines
is going to drop all deprecated functions.
👍 11
d
However, I do not like that
launch
and the other builder functions specifically have been deprecated in favor of
GlobalScope.launch
and the other bunch. I think this is really explicit. What do you think of keeping them as aliases?
k
launching a global coroutine should be explicit
5
e
You are not supposed to be using
GlobalScope.launch
a lot in a typical app. Before making
0.26.0
release we’ve migrated a few apps (both OSS and internal) and they were all gone
k
most of the time you’ll launch from within a scope now
r
@poohbar renaming
launch
to
unleash
is a great idea 🙂
🧌 2
k
@Ruckus first parameter name:
kraken
?
🙂 1
😂 1
d
Fair enough. How would I go about running 2 transactions in a coroutine scope? If one fails, I don't want the other to be cancelled Midway through. I want to know how to control the behavior of the scope with regards to cancelling its children. For another example, how would I limit the number of layers the cancellation propagates into children for?
k
@Dico this question might be better suited for the channel, but: if you don’t want the failure of child tasks to propagate and cancel then you need to catch and handle the failure
this isn’t really any different than before 0.26.0. it’s just that now cleanup can be reasoned about
d
Yeah, I thought it's not different. The scope is just an extra coroutine such that you make children, it makes sense. However, I wouldn't have asked the question if it weren't for the change. And yeah, probably better suited for the channel instead of this thread.
This might be the answer though
j
I got coroutines usage quite a bunch, and the transition was less then a day of work. Despite the internal changes, the API changes are not drastic. Unlike some other libs, this one has the best and the most accurate documentation ever. Having said that, IMO, realizing a made mistake, accepting it, communicating it publicly and fixing it is something giant, something big man do! No doubt Roman is one of the greatest men, a true hero. I still have all my trust to this project and its still my favorite so far. I'm very thankful for the incredible job so far!
💯 7
p
How would I go about running 2 transactions in a coroutine scope? If one fails, I don’t want the other to be cancelled Midway through.
I disagree for Deferred and suspended functions that return a value. If you’re not going to receive a value, you will be retaining resources and using hardware for an operation that’s not going to complete. This was a net win when it became the default in Scala concurrency libs. I’m happy with whatever for Job and suspend + Unit, side-effects are wrong anyway 😛