Ixrec / rust-orphan-rules

An unofficial, experimental place for documenting and gathering feedback on the design problems around Rust's orphan rules
Apache License 2.0
201 stars 3 forks source link

Prior Art #9

Open Ixrec opened 6 years ago

Ixrec commented 6 years ago

C++/Java/C#: The closest analogue to traits is interfaces and/or abstract base classes, which must be part of a type's definition, so there's simply no such thing as "orphan impls".

Haskell: Orphan impls are allowed, and you simply get an error if you ever import incoherent impls. GHC does have an IncoherentInstances language extension that permits GHC to do magic to select an impl for you, but no one should ever use that.


Obviously, this is very incomplete. Please comment if you're familiar with how any other language handles these problems

pip25 commented 6 years ago

One additional note regarding Java: version 8+ introduced default implementations for interfaces, which brought them a bit closer to Rust traits. If a class implements two interfaces which both have default implementations for the same method signature, the class must explicitly implement that method (and while doing so may choose to call one of the default methods to take care of the work).

luxalpa commented 3 years ago

In Go, interfaces are automatically implemented if the struct has matching method signatures. But you're not allowed to add methods to externally defined types, only to local ones, so a common workaround is to wrap the struct. This is roughly equivalent to the recommended workaround in Rust. Also the way interfaces are automatically implemented is practically identical to dynamically typed programming languages like Python or JavaScript.

The situation in Typescript is a bit more complicated. It uses the same syntax as C++/C#, which is interface implementation is part of a type's definition, but it also supports module augmentation, which allows one to change an externally defined type (in this case to implement an interface). However, it still checks interface implementations like Go does (which is by method signature), and so the end result is that it simply doesn't matter.

yujingaya commented 2 years ago

Swift: At the time of writing, Swift is trying to add warning for the orphan implementation, or "retroactive conformance" in Swift parlance.

SE-0364 Warning for Retroactive Conformances of External Types

isheff commented 1 year ago

The academic programming language Genus has a very expressive solution to this problem, allowing the programmer to specify which implementation of the trait they want to use:

https://www.cs.cornell.edu/andru/papers/genus/