# 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.
