8000 Bring Ref on par with AtomicInteger by erikvanoosten · Pull Request #9340 · zio/zio · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Bring Ref on par with AtomicInteger #9340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 28, 2024

Conversation

erikvanoosten
Copy link
Contributor

This change brings Refs on par with AtomicInteger and AtomicLong by implementing methods like getAndIncrement and incrementAndGet directly on Ref.

By using the Numeric type class, the new methods are actually supported for all numeric types.

This change brings `Ref`s on par with `AtomicInteger` and `AtomicLong` by implementing methods like `getAndIncrement` and `incrementAndGet` directly on Ref.

By using the `Numeric` type class, the new methods are actually supported for all numeric types.
@hearnadam
Copy link
Collaborator

I suspect these are better fitting as extension methods for specific types... Using these methods will introduce interface dispatch through Numeric and boxing via an unspecialized Ref. We should probably consider ways to introduce specialization without boxing via concrete classes...

@kyri-petrou
Copy link
Contributor

@hearnadam I agree although I think that it might be better to do what you're proposing as a separate piece of work. It will actually be really good to have concrete classes that utilize AtomicInt, AtomicLong and other AtomicX under the hood for primitives.

AFAICT the changes in this PR should be backwards compatible, where we can simply ignore the implicit Numeric in the specialized implementations.

@hearnadam
Copy link
Collaborator

Can these be extension methods instead?

@kyri-petrou
Copy link
Contributor

Can these be extension methods instead?

If we have them as extension methods we won't be able to override them when we end up implementing via concrete classes. Or maybe I'm missing something?

* Atomically increments the current value of the `Ref` by 1, returning the
* value immediately before modification.
*/
final def getAndIncrement(implicit num: math.Numeric[A], trace: Trace): UIO[A] =
Copy link
Member

Choose a reason for hiding this comment

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

Is it wise to mark them as final? I suppose a specialized version won't have the implicit argument anyway, so maybe.

Copy link
Contributor

Choose a reason for hiding this comment

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

Making them non-final is fully backwards compatible, so maybe we can start with having them as final and we can change them when needed

@erikvanoosten
Copy link
Contributor Author

Is there anything I can do?

@kyri-petrou
Copy link
Contributor

Is there anything I can do?

I was just waiting to see if there are any more comments before merging. @hearnadam do you have anything to add to this comment?

@hearnadam
Copy link
Collaborator

I don't think it's possible to avoid the boxing without deferred in-lining which I was unable to make work even in Scala 3 only.

The concrete class can at least override those methods, so you're correct that's a better approach.

@kyri-petrou
Copy link
Contributor
kyri-petrou commented Nov 28, 2024

I don't think it's possible to avoid the boxing without deferred in-lining which I was unable to make work even in Scala 3 only.

The concrete class can at least override those methods, so you're correct that's a better approach.

@hearnadam I think there are patterns in Scala 3 that could avoid the boxing, e.g.,:

extension (ref: Ref[Int]) {
  @targetName("getAndIncrementInt")
  def getAndIncrement: UIO[Int] = ref.getAndUpdate(_ + 1)
}

extension (ref: Ref[Long]) {
  @targetName("getAndIncrementLong")
  def getAndIncrement: UIO[Long] = ref.getAndUpdate(_ + 1)
}

But yeah can't think of a way to make this cross-compile to Scala 2 since we're lacking the targetName annotation

@kyri-petrou kyri-petrou merged commit d441ab0 into zio:series/2.x Nov 28, 2024
18 checks 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.

4 participants
0