
# C# LDM for June 10, 2020

## Agenda

1. "Roles"

## Discussion

Exploration of previous proposal: #1711

This is a topic that we've explored before which we're reviving for further consideration and discussion.

We have a "role" proposal, but it's more of a starting point for a final design. There are a number of
different problems we can presumably solve here, but it seems like we have some intersecting features that
might address multiple problems simultaneously.

There are many tradeoffs to consider in these designs. One of the most well-known is sometimes called
"incoherence," where the ability to implement an interface in two ways on the same type effectively causes
the two implementations to "cross" each other in ways that can be hard to predict. For instance, if two
people implemented `IEquatable<T>` on the same third-party type, and both added it to a dictionary, if they
used different `GetHashCode` implementations then the same member could be added twice, and each consumer
wouldn't see the implementation used by other consumers.

Another tradeoff is the ability to use the role as a type, namely refer to it in a type position. This
is often desirable, but has some tradeoffs in type equivalence (see SML modules for alternative notions
of type equivalence through functors).

The Roles proposal as a whole seems very powerful, but there are many big questions here. The biggest,
most pressing question is: what problems do we think are the most important and how big a feature do
we need to address them? Providing a way to abstract over different numeric abstractions is a concrete
scenario, but it may not need the fully generalized mechanism. Allowing existing types to conform
to an abstract after definition is also powerful and has many possible use cases, but how flexible
do we need to make that mechanism? Can it only be used in generics? Can you implement abstractions
defined in other compilations on types defined in other compilations?

The performance concerns are also very real. We have a few mechanisms for abstraction in the language
today, but a lot of those mechanisms come with performance costs like allocation that make them
unusable in performance-sensitive scenarios. We would like more zero-cost abstractions if possible,
but we're not sure what functionality we could provide in those circumstances and whether the features
would fit well into the existing ecosystem.