I think I’m encountering a bug in `Resource.parZip...
# arrow
p
I think I’m encountering a bug in
Resource.parZip
when `parZip`ing a `parZip`’d resource 🙂
Copy code
suspend fun main() = int(1)
    .parZip(int(2), Int::plus)
    .parZip(int(3), Int::times)
    .use { println("using $it") }

private fun int(n: Int) = resource {
    n.also { println("acquiring $it") }
} release {
    println("releasing $it")
}
outputs
Copy code
acquiring 2
acquiring 1
acquiring 3
using 9
releasing 3
and never releases 1 and 2
s
Ouch, that is strange..
Resource#parZip
was rewritten to be build on top of the
resource { }
DSL in 1.1.0. Can you give that a shot there?
p
same code (including deprecation) on
1.1.2
results in this:
Copy code
acquiring 2
acquiring 1
acquiring 3
using 9
releasing 1
releasing 3
releasing 2
s
That looks better 😄
p
indeed - I was waiting for the release notes / change-log for 1.1.x before making the switch. I came across this when looking to write a
Iterable<A>.parTraverseResource
method but can get away with
traverseResource
for now to unblock my task and look into an upgrade to 1.1.x next 😉
s
You can safely do this;
Copy code
resource {
  listOf(..).parTraverse {
    resource(it).bind()
  }
}
For doing
parTraverseResource
p
With the new
resource { }
DSL, sure - that’ll be my go-to replacement once I’ve made the jump. 🙏
s
If you look at the new implementation of
Resource#parZip
it's also simply
resource
DSL + the regular
parZip
operator. The goal of Arrow is to make all its functional DSLs and constructs interchangeable.
p
I can definitely see the move to that with the
effect { }
block 🙂 - I assume most/all usage of the old computation blocks will still work in 11.x but I’d rather switch them all to
effect
as part of upgrading
s
1.1.x has nothing weird or special that is required for the transition. TL;DR it adds resource DSL and a better abstraction for
either {}
. Which you can migrate by finding and replacing
arrow.core.computation
to
arrow.core.continuation
and the API usage will not break anywere.
Yes, there is no breakage anywhere in the API and you can thus safely just find and replace the package.
We ran into some weird issues with Github Actions that we need to figure out, thee release post will happen asap.
p
I did notice that
Resource.tap
is broken (removed the unnecessary
<B>
type argument, which was seemingly always required to invoke it) I had a few
.tap<Nothing> { … }
that would need updating.
s
Ah yes, that indeed needs updating
There was no way for us to fix that in a non-breaking way 😞 At least the binary is not breaking, but the Kotlin API is. It requires you to indeed manually change from
.tap<Nothing> {
to
.tap {
So at least it's still backwards compatible
p
I wonder if something like
Copy code
@Deprecated(message = "Use `tap(f)`", replaceWith = ReplaceWith(expression = "tap(f)"))
  public inline fun <B> tap(marker: Nothing? = null, f: suspend (A) -> Unit): Resource<A> = tap(f)
would work for maintaining source compatibility without impacting binary compatibility 🤔
wouldn’t work for
.tap<Nothing>({ … })
I suppose.