csharplang/meetings/2020/LDM-2020-06-10.md
2020-06-18 16:31:16 -07:00

2.4 KiB

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.