# C# Language Design Meeting for September 22nd, 2021 ## Agenda 1. [Open questions in list patterns](#open-questions-in-list-patterns) 1. [Breaking change confirmation](#breaking-change-confirmation) 2. [Positional patterns on ITuple](#positional-patterns-on-ITuple) 3. [Slicing rules](#slicing-rules) 4. [Slice syntax recommendations](#slice-syntax-recommendations) 5. [Other list pattern features](#other-list-pattern-features) 2. [Nested members in `with` and object creation](#nested-members-in-with-and-object-creation) 3. [CallerIdentityAttribute](#calleridentityattribute) 4. [Attributes on `Main` for top level programs](#attributes-on-main-for-top-level-programs) ## Quote of the Day - "That's not just our normal passive aggressive shtick, it's just actively aggressive." ## Discussion ### Open questions in list patterns https://github.com/dotnet/csharplang/issues/3435 https://github.com/dotnet/csharplang/issues/5201 #### Breaking change confirmation First, we looked at the breaking change for `Length`/`Count` on indexable and countable types. We're a bit concerned about making this case a generalized error, even when a list pattern isn't being used: there are potential use cases for a `Length` that returns negative, such as some object modeling a physics concept. We think we'd like to try and downgrade this to a warning instead of an error, for the specific case where a negative length is tested and the location wasn't already subsumed. Some examples: ```cs x is { Length: -1 } // Warning, not subsumbed by any previous case x is { Length: >=0 } // Considered Exhaustive x is { Length: <5 or -1 } // Error on the -1, subsumed by <5. No warning on the <5. ``` ##### Conclusion Try to make it a warning for non-subsumed cases. #### Positional patterns on ITuple Currently, we've implemented subsumption rules that allows list patterns and `ITuple` positional patterns to understand they refer to the same alias. However, we think that this results in weird interactions with regular `ValueTuple` instances. `ValueTuple`s explicit implement `ITuple`'s properties, so when pattern matching on one they would not be considered indexable or countable unless boxed into `ITuple`. This would mean that, unless we were to make `ValueTuple` special in list patterns, there wouldn't be the same correspondence as `ITuple` has. We also don't think that, in general, `Deconstruct` implies an order for an indexer: other than for `ITuple`, these seem to be unrelated concepts. ##### Conclusion There will be no correspondence between positional patterns and list patterns, even for ITuple. If someone comes along with a killer scenario for ITuple later, we can readd this. #### Slicing rules These rules, as stated, matches our previous discussions on the topic. ##### Conclusion No changes. #### Slice syntax recommendations We have two general choices for the slice pattern: ```cs e is [ first, .. var rest ] // Space e is [ first, ..var rest ] // No space ``` We feel that the code reads oddly without the leading space because the pattern being applied itself has a space. It introduces an odd feeling of `(..var) rest`, even though the code is really `.. (var rest)`. ##### Conclusion We're in favor of having a space. #### Other list pattern features For `IEnumerable` patterns, we'd like to introduce them at the same time as the rest of the list pattern feature, even if in a more limited form, to ensure we avoid any potential breaking changes. They may go to preview at different times, and we may need to section off some of the pattern features to ensure we can ship, but we'd like to at least have an initial version. We also do want to make sure that we're generating as good code for this as possible, which may overlap some with params Span work to see whether we can stackalloc. For indexer patterns, we are interested, but they don't need to be this version of C#. We do think that we'll want them in the near future though: we have lists, we should also be able to have dictionaries. For length patterns, we're not seeing the need. We explored them previously and the exploration seems to have concluded that they might be needed for IEnumerable, but if so we can revisit as we look at IEnumerable again. ### Nested members in `with` and object creation https://github.com/dotnet/csharplang/issues/4587 We like the concept of reducing the boilerplate for nested with patterns. However, we're not a fan of the strawman syntax. Multiple members of the LDM misinterpreted it as modifying the nested instance, rather than doing a `with` on the nested property. It would also fall over if multiple properties on a nested instance need to be set. We have a couple of initial ideas: ```cs methodCallExpression with { Method with { Name = "MethodName", BaseType = "C" } } methodCallExpression with { Method = { Name = "MethodName", BaseType = "C" } } // more similar to nested object initializer? ``` #### Conclusion Into the working set, with some syntax modifications. ### CallerIdentityAttribute https://github.com/dotnet/csharplang/issues/4984 Mostly a convenience feature for ASP.NET which will help them structure code in a way more conducive to AOT. It seems in line with our existing caller info attributes, so we'll work with the BCL and ASP.NET teams to prioritize the issue. #### Conclusion Into the working set. ### Attributes on `Main` for top level programs https://github.com/dotnet/csharplang/issues/5045 We do think there needs to be some design work: the feature proposes allowing the `main` modifier in any file. We need to decide whether that's a use case we want to support, and if we do, whether we should allow the target with regular entry points or only with top level statements. If we allowed it with any entry point, we think there are some decent engineering challenges with the way the language is currently structured that would make it more complex than first blush might indicate. Some form of this feature seems reasonable though, so we'll work with the BCL to determine the right scope of the feature. #### Conclusion Into the working set.