Skip to content

Conversation

therealcisse
Copy link
Contributor

@therealcisse therealcisse commented Dec 3, 2020

There is a long list of people who just want to use opaque types as new types without the extra boilerplate of adding apply every time.

This example makes it trivial.

Originally proposed by @smarter here: https://contributors.scala-lang.org/t/synthesize-constructor-for-opaque-types/4616/41

Copy link
Member

@smarter smarter left a comment

Choose a reason for hiding this comment

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

I don' think we should encourage people to do that, not without large disclaimers about how these types don't behave like classes when doing type tests, etc.

@smarter
Copy link
Member

smarter commented Dec 3, 2020

Also "new type" is Haskell terminology that doesn't really mean anything by itself.

@therealcisse
Copy link
Contributor Author

I will try to come up with a disclaimer. However I don't think people expect opaque types in general to behave like classes or have an unapply method.

As for the terminology, I agree. Just can't come up with a better name.

@smarter
Copy link
Member

smarter commented Dec 3, 2020

I think it's more than a disclaimer, one has to present the pros and cons of various approaches in details. And even then I'd be worried about putting this in the documentation since it's almost an anti-pattern. And if we can't come up with a way to describe this concept, then maybe this isn't a good concept to begin with.

@smarter
Copy link
Member

smarter commented Dec 3, 2020

One thing that would be convincing is if someone came up with a realistic scenario where using opaque types as makeshift newtypes makes a significant difference in terms of performance (as measured by real world benchmarks, not micro-benchmarks) compared to using classes, but so far I've only seen people come up with hypothetical scenarios.

@therealcisse
Copy link
Contributor Author

If we can't agree on this, then you are right. It shouldn't be in the official documentation. Besides that's what stackoverflow is for 😁.

Thanks for replying and clearing things up. I will close this.

@therealcisse therealcisse deleted the feature/opaques-newtypes-example branch December 3, 2020 19:07
@japgolly
Copy link
Contributor

japgolly commented Dec 4, 2020

One thing that would be convincing is if someone came up with a realistic scenario where using opaque types as makeshift newtypes makes a significant difference in terms of performance (as measured by real world benchmarks, not micro-benchmarks) compared to using classes, but so far I've only seen people come up with hypothetical scenarios.

There have been many, many times where I need some certain parts of a codebase to be as fast as possible. I get what you're saying that usually people will look at a micro-benchmark and when really their app is just sitting around waiting for IO, but there are also plenty of other cases where performance really matters.

An example that comes to mind is in event sourcing. Say you've got a big stream of events and need to combine them all to create some kind of final model/state. It's a very common use case, often high frequency and quite common for each event stream to become very large. Sometimes it's feasible to cache intermediary states somewhere but sometimes its not. In those cases, every microsecond you can shave off per loop leads to huge real-world time savings. The reason avoiding boxing can be so impactful is that most of the boxing happens around domain data (eg BookId, PersonId, ShoeId) and each event that you apply, is spending nearly all of its time creating and modifying in-memory domain data. One might argue "hey it's a hot loop so for performance reasons it's feasible to just use primitives directly" and that's fine and very small domains, especially doing lots of arithmetic, but in nearly every scenario in which I'm going these kind of optimisations it would be completely unacceptable to use primitives directly because the domain is large, the logic is huge and complex, and "newtypes" are provide an invaluable amount of compile-time safety.

Most serious Scala projects I work on have at least one performance-critical section in them. Regardless whether it's achieved with opaque types or not, using unboxed "newtypes" is a critical ability to help me have safe and performant code.

@smarter
Copy link
Member

smarter commented Dec 4, 2020

I don't think we should be splitting the more general discussion between this PR and https://contributors.scala-lang.org/t/synthesize-constructor-for-opaque-types/4616.

@SethTisue
Copy link
Member

SethTisue commented Dec 4, 2020

that's why my tweet linked to the Discourse thread :-P

@benhutchison
Copy link
Contributor

I'm disappointed this PR got closed. I would like to see it reopened and merged. @amsayk went to the trouble of documenting a pattern that has seen wide uptake in the scala community. Newtype is probably the number one usage of opaque types in the wild. People pro newtype usage of opaque types are also clearly the majority on the thread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants