2020-06-10 21:18:32 +02:00
|
|
|
|
|
|
|
# C# LDM for June 10, 2020
|
|
|
|
|
|
|
|
## Agenda
|
|
|
|
|
|
|
|
1. "Roles"
|
|
|
|
|
|
|
|
## Discussion
|
|
|
|
|
2020-06-19 01:08:51 +02:00
|
|
|
Exploration of previous proposal: #1711
|
|
|
|
|
2020-06-10 21:18:32 +02:00
|
|
|
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.
|