# C# Language Design Meeting for Feb 10th, 2021

## Agenda

1. [Follow up on record equality](#follow-up-on-record-equality)
2. [Namespace directives in top-level programs](#namespace-directives-in-top-level-programs)
3. [Global usings](#global-usings)
4. [Triage](#triage)
    1. [Nominal And Collection Deconstruction](#nominal-and-collection-deconstruction)
    2. [Sealed record ToString](#sealed-record-ToString)
    3. [`using` aliases for tuple syntax](#using-aliases-for-tuple-syntax)
    4. [Raw string literals](#raw-string-literals)
    5. [Allow `var` variables to be used in a `nameof` in their initializers](#allow-var-variables-to-be-used-in-a-nameof-in-their-initializers)
    6. [First-class native integer support](#first-class-native-integer-support)
    7. [Extended property patterns](#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.
