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

Prior Art #9

Open
Ixrec opened this issue Jul 7, 2018 · 4 comments
Open

Prior Art #9

Ixrec opened this issue Jul 7, 2018 · 4 comments

Comments

@Ixrec
Copy link
Owner

Ixrec commented Jul 7, 2018

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
Copy link

pip25 commented Aug 9, 2018

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
Copy link

luxalpa commented Nov 1, 2021

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
Copy link

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
Copy link

isheff commented Jan 25, 2023

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/

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

No branches or pull requests

5 participants