csharplang/meetings/2020/LDM-2020-11-16.md
2020-11-16 15:14:04 -08:00

5.8 KiB

C# Language Design Meeting for November 16th, 2020

Agenda

  1. Ternary comparison operator
  2. Nominal and collection deconstruction
  3. 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.