Add LDM notes for Nov. 14, 2018

This commit is contained in:
Andy Gocke 2018-11-28 10:08:05 -08:00
parent 050eba840f
commit 4811c98606
2 changed files with 137 additions and 4 deletions

View file

@ -0,0 +1,131 @@
# C# Language Design Notes for Nov 14, 2018
## Agenda
1. Base call syntax for default interface implementations
2. Switch exhaustiveness and null
## Discussion
### Default interface implementations
Example of base calls:
```C#
interface I1 { void M(); }
interface I2 { void M(); }
interface I3 : I1, I2 { void I1.M() { } void I2.M() { } }
interface I4 : I1, I2 { void I1.M() { } void I2.M() { } }
interface I5 : I3, I4
{
void I1.M()
{
base<I3>(I1).M();
base<I4>(I1).M();
}
void I2.M()
{
base<I3>(I2).M();
base<I4>(I2).M();
}
}
```
Q: Should we even allow the programmer to call explicit implementations?
In existing C# code this is not allowed since all explicit implementations
are private. You can always call by casting to the interface if the interface
is not re-implemented, but there's no way to do this via a base call.
However, there's no way to use overriding default interface implementation in
C# 8.0 *except* for explicit implementation, so not allowing it would basically
not allow the scenario.
Java does allow this scenario, so full compat would require us to add the feature.
Q: What type of dispatch would we use in the runtime?
One way is to constrain to the interface, then do a virtual dispatch for a
particular method. This probably would require additional (fairly expensive)
runtime work.
Q: What does the syntax need to express?
One problem is for `I3`, where by signature `M` is ambiguous because it's not
clear whether you mean `I1.M` and `I2.M`. The syntax would need to specify both
that the `I3` implementation is requested *and* whether or not to choose `I1.M` or
`I2.M`.
One other option is to just not provide a way of disambiguating `M`. If there's an
ambiguity you can't call any particular `M`.
**Conclusion**
Let's do the simplified form. If the `M` being called is ambiguous, it's illegal to
call such a method. The only configuration we're considering is which base to look
for the method.
#### Syntax
```C#
namespace N {
interface I1<T> { int M(string s) => s.Length; }
}
class C : I1<T>
{
int I1.M(string s)
{
// Options:
base<N.I1<T>>.M(s);
base(N.I1<T>).M(s);
N.I1<T>.base.M(2);
base{N.I1<T>}
base:N.I1<T>.M(s);
base!N.I1<T>.M(s);
base@N.I1<T>.M(s);
base::global::N.I1<T>.M(s);
base.(N.I1<T>).M(s);
(base as N.I1).M(s); // base isn't an expression, so this isn't legal today
((N.I1)base).M(s); // same here
base.N.I1.M(s); // clash with a member on base, doesn't allow for qualified name
N.I1.M(s); // this is currently a static call on I1, can't work
}
}
```
We think the forms that take advantage of `base` not being an expression are
too clever and would just be confusing. `N.I1.base.M(2)` is possibly tricky
for human readability since `base` is in the middle and is harder to notice
without coloration.
One problem with `base(N.I1).M(s)` is if we want to add "invocation" operators
to the language, that would disallow invoking your base.
`base::N.I1<T>.M(s)` has some history in the language.
**Conclusion**
Decided on `base(N.I1<T>).M(s)`, conceding that if we have an invocation
binding there may be problem here later on.
### Switch exhaustiveness and null
Current design: warning about not handling all inputs *except* null.
Q: What happens when the switch actually doesn't match what was given at
compile time?
**Proposal**:
A new `MatchFailureException` that extends `ArgumentException`. This allows
the compiler to use an existing exception for down-level support. There's
no data, just a message.
**Conclusion**
The base should be `InvalidOperationException`, not `ArgumentException`. If
the argument being switched on can be trivially boxed into object, we'll add
it as an argument to the `MatchFailureException`. Otherwise, just fill in
`null`.

View file

@ -212,12 +212,14 @@ Discussion of records proposals:
1. Where can #nullable go?
2. Open issues with pattern matching
# Upcoming meetings
## Nov 14, 2018
- Base call syntax for default interface implementations (Aleksey, David, Michal)
- Runtime exception for switch expressions (Neal)
[C# Language Design Notes for Nov 14, 2018](LDM-2018-11-14.md)
1. Base call syntax for default interface implementations
2. Switch exhaustiveness and null
# Upcoming meetings
## Nov 28, 2018