Closed TheDrawingCoder-Gamer closed 11 months ago
This seems to me like you still want default implementations in interfaces but introducing a new syntax and an entirely new aspect to the type system to achieve it. This would just be confusing, and that original feature was already rejected.
One thing that makes Rust traits so powerful is the fact that the implementation of a trait (impl SomeTrait for SomeType
) is a synactic unit separate from both the type declaration and the trait declaration. There are some consistency requirements, but it means you can enrich a type with a trait implementation after the fact, e.g. if you declare your own trait, you can add it to standard lib types. It also allows for blanket implementations, etc etc. Saying that this proposal is inspired by Rust traits is a bit far-fetched.
Adding Impl would upheave a lot of syntax... however, haskell and rust both allow defining instances in either:
Hm, perhaps for JVM and C#, a @:native
metadata will generate traits as interfaces and it doesn't allow impls, so I will be double happy.
I was recently thinking about how haxe, in it's current state, would implement type classes. I drew a complete blank, which is not very good, as type classes allow for functional programming. Traits in rust act like type classes, and haskell has typeclasses. It allows for powerful generic functions than can be implemented after the fact.
Traits are a powerful language feature, yes. They would also require massive changes to the language and the compiler to accommodate them, assuming they can even be encoded into all of our target languages without too much overhead. For example, the mangling-based encoding you describe works after all types and traits are known. This should be true when code is being generated but what about in the middle of the typing process? When the typer sees the declaration class Foo implements X
, it is known that X
is implemented, but what if implements X for Foo
is in a separate module? Typing of the module (or its dependencies) might depend on a trait being implemented. (Rust solves this kind of problem with coherence rules.) What about blanket implementations, i.e. implementing a trait if another trait is implemented on any type, or even on any type parameter of a concrete type?
Simply put, this might be too large to implement without reconsidering a lot of Haxe in the process.
There's a paper from 2004 by Bart Groot called "Implementing Traits In Java" that I think deals with some of these issues. He goes into "the flattening property" which might allow you to present traits within the current AST with a little metadata. Section 3.4 "typing traits" goes into this in detail. There's already a little juju to implement abstract
, I don't think this would be too different, especially now abstract classes are there.
I don't think this represents what a "trait" is. Someone can later make a PR about TYPECLASSES not traits.
This proposal adds traits, which are interfaces that have default implementations. It also adds implementations for traits, which can be applied anywhere.
Rendered Proposal