(Proposal) Concepts/Traits (enhanced generic constraints)
See original GitHub issueTraits
Traits are a specification a Type / Method must have to be valid. This specification is validation at both compile-time and runtime. The runtime cost maybe worth it for additional safety,
Basic Grammar
trait ::= "Trait" identifier specification
specification ::= '{' spec+ '}'
spec ::=
incomplete
A trait can be define in a separate construct, like a class / struct.
Examples
trait Zero { static readonly Zero ()->T }
trait Unit { static readonly Unit ()->T }
trait [+] ( static [+] (T,T)->T } // operator + (addition)
trait [-] { static [-] (T,T)->T } // operator - (subtraction)
A trait can “inherit” other existing traits. eg.
trait SimpleCalc <: { Zero, Unit, [+], [-] }
This allows “constrained generics” over numeric types.
Summation< T > ( IEnumerable<T> nums )
T has SimpleCalc
{
T total = T.Zero();
foreach( T num in nums)
total = total + num; // += can't be used as the specification didn't specify it.
return total;
}
A trait can also be anonymously define at the point of use
foo <T> ()
T has Trait { ... }
{
// method code
}
Value Traits
Value Trait are checked against the value of a variable, if it possible to valid at compile-time it is, if not it is validated at runtime.
trait NonNull <T : class> { != null }
int CharCount ( string s )
s is NonNull
{
return s.Length;
}
Note: T!
could be an alias for the NonNull Trait
I do require help to spec-out this idea, I think it has potential has *(as see it) that traits would also enable other current proposals / part of them.
Issue Analytics
- State:
- Created 9 years ago
- Comments:46 (28 by maintainers)
Top GitHub Comments
I like this very much. It allows the generics in C# to be much more flexible, allowing structural typing for methods and classes that use the traits.
This is a really good basis to develop other features on top of in the future. For instance it’d be nice if you could have automatic traits, where the compiler infers the traits based on the usage within the class/function. That would eliminate a LOT of the boiler plate of types in C#, and give you essentially global type inference in opt-in scenarios.
I’d like to use a trait in a similar way I’d use an interface:
Inheritance:
Usage:
I personally won’t bother about value traits and leave this kind of checks/validations to the Method contracts.