So, in summary, if the goal is that you want to fo...
# arrow
s
So, in summary, if the goal is that you want to focus on pure constructs only, that's a good goal, but one that isn't going to work for me (not that I expect your project to focus on me only) but I do think that 99% of kotliners are coming from a Java background, and making it as accessible as possible is important. And what I mean by that is allowing impure FP as a stepping stone.
s
Fair point and not that long ago I was also in this camp. I am assuming that using something like
IO<E, A>
instead of
Either<E, A>
would also not solve this issue?
s
I'm happy to use IO
in that situation
as I can typealias to Either if I really want to
(not that I would)
but you can explain it in that way
s
Right,
IO<E, A>
will come soon
s
It's just all the boilerplate wrapping of suspending calls that won't work
Everyone is really excited to use coroutines
and if I say, well you have to use effects
"boom"
Like I say, I understand if my use case doesn't align with the goals of arrow.
s
It gives you a lot of power for free
s
Well I don't use IO in Scala even. I think it's debatable, power vs verbosity, but that's just me.
s
That’s the whole idea behind controlling effects. We can guarantee resource safety including for combinations of complex scenarios cancelation/async/exception.
s
in Scala returning IO in every class just ends up polluting every method.
s
I don’t see the difference with any other type.
s
And to be fair, I don't really understand why wrapping a side effect in IO is good.
s
That’s what I thought 😄
s
Here is my side effect dangerous function. If you wrap it in IO you still have the side effect. Just later.
s
No, that’s not the point.
s
You still can't test it without running it.
s
Wrapping a single effect seems meaningless indeed.
s
Anyway, I don't want to get into a debate on IO as I'm not knowledgable enough to debate it. I don't really understand why it's good and I'll accept that's a limitation of what I know.
But I've been doing scala for 8 years, I consider myself a half decent programmer, so if I'm confused by it, I'm pretty sure half the Java guys will be as well. Unless I'm just thick.
But getting things like functional error handling, and trying to be more functional in other ways, will be really popular on the project I'm working on I think.
s
If you’re interested in learning what the benefits are of
IO
I can send you some references. The biggest are that we can guarantee safety, and we can provide powerful combinators. Things like cancelation, resource safety with async errors/cancelation, etc are horrible to write and maintain yourself.
s
I have read about IO many times. I tried to use it on a project of mine.
I just ended up wrapping every return type in IO, and having shit loads of map and flat map everywhere
and I still didn't see the point
other than it was now "pure"
But your point on cancellation etc, are very good to consider.
you definitely don't get that with raw io
s
If you don’t use any features like
parTraverse
,
parMapN
,
raceN
, etc and have no need for async resource safety or cancellation it might seem meaningless
s
That might be why I thought it was just a waste of time then. Because I was doing some logging.
I was writing out a couple of files
and now I had IO in every single return type
s
You could’ve very easily made that processing parallel including resource safety on closing the files by using some of the operators I mentioned above.
With 0 additional code
s
well it's not 0
it's IO<MyType> everywhere
map and flatMap
and the cognitive overhead
s
map/flatMap can be replaced by
for
in Scala and
fx
in Arrow.
s
so not 0 overhead then
but yeah I see your point
Like I said I'm not arguing against it, just saying I don't really see the benefit because I'm not smart enough 😂
s
Well the cognitive overhead is subjective. Since I was in your camp and now I am on the other side.
That smart enough part is incorrect. I’d argue its your unfamiliar with the more complex use cases.
We have to levitate that pain with better docs in the future
s
But you can't give this style of app to a random developer and expect them to grok it immediately. And that's the benefit of Kotlin. You can give it to someone from a Java background and they won't be confused. If now every developer working on this project has to also understand IO and effects and so on, it increase the barrier to entry, and how can I justify that to management?
Anyway, more pressing is my immediate use case
🙂
s
That’s a completely different matter 😄 There is a lot of things that require a learning curve. Moving to SwiftUI for iOS, or Compose for Android, Reactor for Spring etc all also come with learning curves.
s
Sure, and developers are happy with a learning curve
But I can't go from spring and hibernate to Scala style code in one jump.
I need to tackle the middle ground first
s
Everyone learns in a different way. I like diving in the deep end.
s
Ok, but I have 30 developers to consider.
So that's why I need to do some moderate changes to start with.
s
First time I introduced such a change was RxJava. Which is almost the same as
IO
.
s
Ok, so I'm not in a position to introduce IO
that's not going to change
I want to introduce FP with as little syntax overhead as possible.
s
I hope we can solve the limitation on `binding`/`fx` soon.
s
Yeah. I'm happy to wrap in runBlocking if I know some solution is coming that I'm happy with.
I might have to do what I said in the main room and just avoid binding for now
s
👍
s
I'm going to start a new topic in the room. Why is either better than exceptions:)
d
So this is the thing you need to wrap your head around, I think: An impure function that you don't invoke... is pure.
That seems like a dumb technicality up front 🤷
s
Yeah, but again that is not the point. We live in a world where everything needs to be async and parallelised etc. Doing that yourself is horrible and no matter how good you’re with concurrency there will always be bugs!
d
brb
s
But if we make everything lazy we’re effectively describing our program. Since it’s just a description of what to do, nothing happened at this point.
So we can do optimisations for you before we run, i.e. fuse
map
, eliminate excessive thread jumps
continueOn(UI).continueOn(UI).continueOn(UI).continueOn(UI)
===
continueOn(UI)
.
We can also guarantee resource safety in async programs which I can guarantee is not fun to write 😄
d
So the point of using IO is it allows you to compose effects
arrow 1
s
So in other words, in return for wrapping
IO
, or any other data type if you’re using typeclasses, we can give you a complete toolbox - batteries included- for free.
d
not just purity
s
Exactly
It allows you to compose concurrent programs
It can eliminate things like locks and other low level concurrency stuff from your code completelyt
because they’re encoded in primitives that return non blocking `IO`s
I got to run now but I’d love to continue this discussion or answer any other questions you have 🙂
d
I have scrum in 2 minutes. But let me follow up - we could describe a pure program with just unexecuted, impure functions and no monads, but the code to compose them would be manual, cumbersome and error prone
s
Yes, I'd throw DRY around a bunch here :D