Skip to content

Fixes issue #912: Executes liftF effect twice in a product composition#914

Merged
sloshy merged 1 commit intoxebia-functional:mainfrom
Lost-Fly:fix-product-repeated-execution
Jan 22, 2026
Merged

Fixes issue #912: Executes liftF effect twice in a product composition#914
sloshy merged 1 commit intoxebia-functional:mainfrom
Lost-Fly:fix-product-repeated-execution

Conversation

@Lost-Fly
Copy link

Fixes issue #912

When combining a Done fetch with a Blocked fetch in product/productR/map2, the previous implementation would call product(fa, c) or map2(fa, c)(f), causing the already-completed effect fa to be re-run.

The fix uses the already-computed result value instead of re-running the entire fetch:

  • product: use c.map((a, _)) instead of product(fa, c)
  • productR: use c or c.as(b) instead of productR(fa)(c)
  • map2: use c.map(b => f(a, b)) instead of map2(fa, c)(f)

Added unit tests to verify that side effects are executed exactly once.

@Lost-Fly
Copy link
Author

@AntonioMateoGomez @fedefernandez Could someone from the maintainers please take a look when you have a moment?

sloshy
sloshy previously approved these changes Jan 16, 2026
Copy link
Contributor

@sloshy sloshy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spent some time trying to see if this was representative of a behavior regression by running your tests on older releases from 5+ years ago, but no, I believe that this behavior was just never tested for before. Good find, and I'll double-check with some other Xebia people to see if they concur but I believe this can and should be merged.

@sloshy
Copy link
Contributor

sloshy commented Jan 16, 2026

@Lost-Fly if you can run sbt scalafmt for me on this branch I'll get it merged ASAP and hopefully cut a release soon!

@Lost-Fly
Copy link
Author

@sloshy I`ve done scalafmt on tests, check it please

@sloshy
Copy link
Contributor

sloshy commented Jan 21, 2026

Currently waiting on #915 and then this can be updated with main, and should be good to go after that.

@sloshy
Copy link
Contributor

sloshy commented Jan 21, 2026

@Lost-Fly seems like it'll work again once you update the branch from main. I'd do it but then it'd associate me with the commit, and I believe that would mean I'd need someone else to review it.

…oduct composition

When combining a Done fetch with a Blocked fetch in product/productR/map2,
the previous implementation would call product(fa, c) or map2(fa, c)(f), causing
the already-completed effect `fa` to be re-run.

The fix uses the already-computed result value instead of re-running
the entire fetch:
- product: use c.map((a, _)) instead of product(fa, c)
- productR: use c or c.as(b) instead of productR(fa)(c)
- map2: use c.map(b => f(a, b)) instead of map2(fa, c)(f)

Added unit tests to verify that side effects are executed exactly once.
@Lost-Fly Lost-Fly force-pushed the fix-product-repeated-execution branch from 2b34a93 to 815dcb0 Compare January 22, 2026 03:56
@Lost-Fly
Copy link
Author

I've done rebase onto main. Please run the tests now

@sloshy sloshy merged commit 7301be1 into xebia-functional:main Jan 22, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants