Skip to content
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

Are newtypes always an option? #5

Open
Ixrec opened this issue Jul 7, 2018 · 1 comment
Open

Are newtypes always an option? #5

Ixrec opened this issue Jul 7, 2018 · 1 comment

Comments

@Ixrec
Copy link
Owner

Ixrec commented Jul 7, 2018

As far as I know, any time you run into an orphan rules violation, it is always possible to solve it by writing a newtype. It might be tedious to write, or not the ideal solution, but I'm not aware of a case that's impossible to solve with a newtype.

This issue is for proving me wrong.

@FrankHB
Copy link

FrankHB commented Apr 3, 2024

NO.

I don't want to detail too mach, but there should be the simple case: for a type W<A> where W is a library generic type depending on client (user-provided) type A for function right, it may be not appropriate to introduce any new types for either W, A, or W<A> because the remaining program relies on their type identity.

For example, sane language binding implementation distinguish strictly about any "newtype" and wrapped type as different ones, for clear logical reasons. A is not new type for A. W<A> is not new type for W<A>. This should be true in any nominal type systems, including Rust; and an object language will assume this, too. Then, where should W<A> be settled down?

New types cannot be introduced to resolve the problem because:

  • For W: Introducing new type implies that the library (crate) defining W cannot take the signature including W for a stable interface boundary. In some cases, concrete type W can be generalized to be a parameterized type so it won't be referenced directly in the library code whose signature containing W, but given the fact that Rust is lacking of structural typing in generics, it must come with some additional traits, say, T for one instance. Then, such trait plays the same role as W and suffers from the problem of W<A> (see below): what if T<A> is to be implemented? Where?
  • For A: Common sense: the library author cannot put arbitrary A into the library. Neither the newtype for A.
  • For W<A>: The library author also have nothing to do with W<A>. There is an extensibility issue for client code: It should be together with A. But it is not allowed. Why on earth W<A> does not qualified to be a new type for the sake of providing the implementation? Nope. It just be clashed with the orphan rule, occasionally.

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

No branches or pull requests

2 participants