82 lines
5.8 KiB
Markdown
82 lines
5.8 KiB
Markdown
|
# C# Language Design Meeting for November 16th, 2020
|
||
|
|
||
|
## Agenda
|
||
|
|
||
|
1. [Ternary comparison operator](#ternary-comparison-operator)
|
||
|
2. [Nominal and collection deconstruction](#nominal-and-collection-deconstruction)
|
||
|
3. [IgnoreAccessChecksToAttribute](#ignoreaccesscheckstoattribute)
|
||
|
|
||
|
## Quote of the Day
|
||
|
|
||
|
- "If it turns out to be really hard, give it to a smarter compiler dev"
|
||
|
- "The name is not good: It should be the BreakTermsOfServiceAttribute"
|
||
|
|
||
|
## Discussion
|
||
|
|
||
|
### Ternary comparison operator
|
||
|
|
||
|
https://github.com/dotnet/csharplang/issues/4108
|
||
|
|
||
|
This proposal centers around add a bit of syntax sugar to simply binary comparisons, where a user might want to compare 3 objects
|
||
|
for ascending or descending order. Today, the user would have to write `a < b && b < c`, but with this proposal they would just
|
||
|
write `a < b < c`. In order to deal with the potential ambiguities, we'd have to first attempt to bind these scenarios as we would
|
||
|
today, and if that fails then attempt to bind them as this new "relational chaining" form. This feature would need to have a very
|
||
|
specific pattern: if we were to allow `a < b > c`, for example, that could be syntactically ambiguous with a generic, and would need
|
||
|
to keep binding to that as it would today. We therefore are only interested in strictly-ordered comparisons: all comparisons in a
|
||
|
chain should be less-than/less-than-or-equal, or greater-than/greater-than-or-equal, without mixing between the 2 orders. We are
|
||
|
also worried about the compile-time cost of double-binding here, particularly since the most-likely binding will have to be done second,
|
||
|
in order to preserve backwards compatability. We also considered allowing more than 3 objects in such a chain: we like the idea, but
|
||
|
it will require some spec work as it does not just fall out of the current specification.
|
||
|
|
||
|
#### Conclusion
|
||
|
|
||
|
Triaged into Any Time. This needs some specification work to allow the 4 or more operators, which would likely be similar in form to
|
||
|
the null-conditional operator. Additionally, any implementation will have to take steps to address potential perf issues and demonstrate
|
||
|
that it does not adversely affect compilation perf on real codebases.
|
||
|
|
||
|
### Nominal and collection deconstruction
|
||
|
|
||
|
https://github.com/dotnet/csharplang/issues/4082
|
||
|
|
||
|
This feature provides unity between patterns and deconstruction assignment. Today, we have tuple deconstruction assignment, and tuple
|
||
|
patterns. They evolved in the opposite direction: we started with tuple deconstruction assignment, then added general patterns to the
|
||
|
language. We now consider adding nominal deconstruction assignment, to complete the symmetry between the feature sets.
|
||
|
|
||
|
One thing we want to be careful of here is to not go to far down the path of replicating patterns in assignment. A pattern in an `is`
|
||
|
or `switch` forces the user to deal with the case that the pattern did not match, which is not present here. For nominal deconstruction,
|
||
|
we can leverage nullable reference types: the user will get a warning if they attempt to deconstruct an element that could be null. For
|
||
|
list patterns, though, there is no similar level of warning, and we want to be careful of creating a pit of failure that will result in
|
||
|
exceptions at runtime. We are also concerned about some of the aspects of allowing names to be given to outer structures, such as allowing
|
||
|
`var { Range: { Column: column } range } = GetRange();`. This could mix badly with allowing existing variable reuse: in patterns today,
|
||
|
the `{ ... } identifier` syntax always introduces a new variable, which we think would end up being confusing. We very wary of allowing
|
||
|
patterns to match into existing variables because it would introduce side-effects to patterns, which is very concerning. Finally, given
|
||
|
that we haven't yet designed regular list patterns, we think we should hold off on list deconstruction assignment until those are complete,
|
||
|
at which point we should have a discussion around whether we should have them at all.
|
||
|
|
||
|
#### Conclusion
|
||
|
|
||
|
Nominal deconstruction assignment is accepted into the working set. Let's split list deconstruction assignment into a separate issue, which
|
||
|
will be followed up on after list patterns are designed. Open questions exist on whether we should allow names on patterns themselves.
|
||
|
|
||
|
### IgnoreAccessChecksToAttribute
|
||
|
|
||
|
We had a very spirited discussion around this attribute, which is essentially the inverse of `InternalsVisibleToAttribute`. Where IVT
|
||
|
allows an author to grant access to a specific other dll, this allows a specific other dll to grant themselves access to an author. There
|
||
|
are many challenges around this scheme that fundamentally affect the entire ecosystem, and those discussions need to happen at a .NET
|
||
|
ecosystem level, rather than at a language level, even though most of the implementation work will fall on the compiler. Ref assemblies,
|
||
|
for example, do not have internal members today. There also needs to be discussions on how we would enforce the "use at your own risk"
|
||
|
aspect of this feature. We can say that all we want, but at the end of the day if VS were to take a dependency on an internal Roslyn
|
||
|
API that we need to change, it could block shipping until either Roslyn readded the API or the dependency was removed. Given our
|
||
|
experiences with `InternalsVisibleToAttribute` already, we're not certain that this burden of risk will be correctly shouldered by the
|
||
|
ones actually taking on the risk.
|
||
|
|
||
|
#### Conclusion
|
||
|
|
||
|
Tabled for now. Discussion needs to happen at a higher level.
|
||
|
|
||
|
## Working Set Themes
|
||
|
|
||
|
With our discussions today, we have finished working through our current triage backlog! We've collected the various issues and themes
|
||
|
in our working set and created a meta-issue to track them all: https://github.com/dotnet/csharplang/issues/4144. We've locked the issue
|
||
|
to ensure that it stays a clean space. For discussion on a particular topic, please see the topic issue, or create a new discussion.
|