csharplang/meetings/2021/LDM-2021-02-10.md
2021-02-10 17:35:31 -08:00

8.8 KiB

C# Language Design Meeting for Feb 10th, 2021

Agenda

  1. Follow up on record equality
  2. Namespace directives in top-level programs
  3. Global usings
  4. Triage
    1. Nominal And Collection Deconstruction
    2. Sealed record ToString
    3. using aliases for tuple syntax
    4. Raw string literals
    5. Allow var variables to be used in a nameof in their initializers
    6. First-class native integer support
    7. Extended property patterns

Quote of the Day

  • "That's 3 issues in 8 minutes." "That's an LDM record!"
  • "Back to serious stuff. Raw string literals. Because raw is better for digestion"

Discussion

Follow up on record equality

https://github.com/dotnet/csharplang/issues/39#issuecomment-678097433 https://github.com/dotnet/csharplang/discussions/4411

Back when the linked comment on #39 was raised, we had an internal email chain discussing changing the implementation of == to move the reference equality short-circuit down to the strongly-typed Equals implementation. We came to the conclusion that instead of moving the check we should duplicate it, to ensure that == still behaves correctly for null, but we never followed up on that conclusion. Today, we confirmed that we do indeed want to do that, and update the C# compiler to generate this better version of equality.

Conclusion

We'll do this. https://github.com/dotnet/roslyn/issues/51136 tracks following up on that work.

Namespace directives in top-level programs

Our last discussion on the namespace directive had one open question left: should we allow them in combination with top-level statements? We had an internal email chain on this topic since then, and came to the conclusion that we should disallow this combination. There's a couple reasons for this:

  1. We think the namespace directive is confusing here. It looks like a statement, but the rest of the statements on the top-level don't introduce a new scope.
  2. It is easier to remove an error later if we decide that it's too restrictive. If we allow it, we'd have to support it forever.
  3. Users might expect to be able to put a namespace before those top-level statements and change the namespace the implicit Main is generated into.

Conclusion

Decision upheld. Top-level statements are not allowed in combination with file-scoped namespace directives.

Global usings

Our last discussion on global usings had us split right down the middle on whether to make global usings a C# syntax feature, or a command-line switch to the compiler, with a razor-thin majority leaning to C# syntax. In order to make progress here to begin implementation, we again took an internal email chain to discuss this further. This conversation drew a few conclusions:

  • Neither a a command-line switch nor C# syntax would prevent a source-generator from providing their own set of usings, but the switch would prevent the source-generator from dynamically providing this, it would have to be predefined in props/targets file in the generator nuget package.
  • We really need to be considering the experience when using dotnet, not csc. The SDK passes 182 parameters to a build of a simple hello world application today. It's very unrealistic to base scenarios on calling csc directly.
  • For the base templates, such as as a console app or a default ASP.NET application, this choice doesn't really affect the files the templates drop down. In either case, the usings will be hidden. For more complicated templates, this choice changes whether the template drops a GlobalUsings.cs file, or fills in a property in the template csproj. In either case, the template has really moved beyond a single-file program, so the difference isn't huge.
  • We've had a number of requests over the years for global aliases, and a C# syntax will fit in nicely with such a feature.

Conclusion

Given the need to start implementing here and the thin majority that prefer C# syntax, we will start investigation and implementation on the C# syntax version, with a speclet forthcoming later this week.

Triage

Nominal and Collection Deconstruction

https://github.com/dotnet/csharplang/issues/4082

This feature will add symmetry with tuple patterns/deconstruction, which is desirable. There is some potential parsing challenges, as several of the examples look like a block with a labelled statement inside it and will need some tricky work to ensure disambiguation works.

Conclusion

To the backlog. We like the idea and think there's a way to get it into a form we like, but can't commit to it right now.

Sealed record ToString

https://github.com/dotnet/csharplang/issues/4174

This is a simple enough change and we've had a few complaints about the behavior and inability to seal. As an alternative, we could design a parallel ToString implementation for records that the base type in a hierarchy will call into, which would be a minor behavior change from C# 9 as released. However, this would be complicated, and sealed is the keyword to tell consumers "No really, this is the final version of this behavior, you can't change it."

Conclusion

We'll put this in Any Time to promote community contributions for this small feature, but if no one picks it up we will likely put in a bit of effort to get it into C# 10.

using aliases for tuple syntax

https://github.com/dotnet/csharplang/issues/4284

The title of this issue is a bit of a misnomer, as the proposal actually extends to all types, not just tuples. We've also looked at a broader proposal recently in conjunction with the global using statement feature, which would allow things like global using MyDictionary<TValue> = System.Collections.Generic.Dictionary<int, TValue> and other similar work. It seems like we want to make some improvements in the alias and using area, and we should consider doing a subset of that larger proposal now in the same fashion that we've continuously shipped incremental updates for patterns.

Conclusion

Triaged into the working set. We want to make a general using improvement push in 10, and have a goal of at least doing this much for alias improvements in this release.

Raw string literals

https://github.com/dotnet/csharplang/issues/4304

There are a number of potentially contentious design decisions in this area, but we intentionally tried to steer away from them today and limit to just the general concept. There are many scenarios for embedding other languages into C#: XML, JSON/Javascript, C#, and more. In many of these languages, " and ' are not interchangeable, so anything with a " in it is painful in C# today. We also thing that interpolation in these strings is important, as these embedded code scenarios are often used for templating. There is potential work around a way to specify what character sequence defines the interpolation holes, but we did not go into details or specifics here.

Conclusion

Into the Working Set. There's a bunch of design questions that we'll need to spend some time working on.

Allow var variables to be used in a nameof in their initializers

https://github.com/dotnet/csharplang/issues/4384

This is a minor convenience issue that has come up a few times for users, but has potential implementation nastiness with disambiguating whether nameof is a method or a nameof_expression. Given the minor benefit and the potential implementation concerns, we're concerned about doing this unless we decide to make nameof a non-conditional keyword.

Conclusion

Rejected. If we ever make the change to make nameof not a conditional keyword and can simplify the binding here, then we can bring this back, but until that point we will leave this as is.

First-class native integer support

https://github.com/dotnet/csharplang/issues/4385

As the language is specified today, compliant C# compilers have to emit certain overflow conversions and then roundtrip those conversions back to the original representation. This is inefficient and a small spec change will produce no observable semantic difference, while allowing the compiler to emit better code.

Conclusion

Accepted into the working set.

Extended property patterns

https://github.com/dotnet/csharplang/issues/4394

This is something that patterns are very verbose about today, and it's a syntax we've previously discussed as a potential shorthand to reduce the boilerplate. We could also potentially extend this idea to object initializers, but don't want to tie that to this proposal.

Conclusion

Accepted into the working set.