# C# Language Design Meeting for March 12th, 2025

## Agenda

- [Optional and named parameters in expression trees](#optional-and-named-parameters-in-expression-trees)
- [Collection builder method parameter order](#collection-builder-method-parameter-order)
- [Ignored directives](#ignored-directives)

## Quote of the Day

- "I'm here for 5 minutes of [redacted] before everyone gets back!" _no one speaks for the 5-minute bio break_ "That was an exciting 5 minutes."
- "I think we should accept C#'s age of over 25 years and go with octothorpe"

## Discussion

### Optional and named parameters in expression trees

Champion issue: https://github.com/dotnet/csharplang/issues/9246  
Specification: https://github.com/dotnet/csharplang/blob/b200d0a075dbeaff5a5b2eaab7b529102d5483af/proposals/optional-and-named-parameters-in-expression-trees.md

First up today, we took a look at a change around expression trees to support something that seems like it should just fall out. This isn't
a broad change, nor is it any kind of new node: it's simply removing an error. Doing searches through the history of C#, we're unsure why
this is even restricted in the first place; our notes from the C# 4 timeframe don't indicate that any consideration was put into this
topic, and no one still in the LDM who was present at the time can remember any discussions about blocking this. Likely, it was simply
just forgotten about.

Given that, we have a few approaches we can take:

1. Do nothing and keep the status quo.
2. Allow optional arguments. These will be filled in by the compiler, and emitted as if they had been called by the user.
3. Allow named arguments in-order. These will have no impact on the shape of the tree.
4. Allow named arguments out-of-order. This would potentially have impacts on the shape of the tree. While we likely could avoid adding
   new nodes for this, it would mean the compiler would start emitting existing node types that were never emitted before, which would
   be a breaking change for linq providers.

We think we're fine with 2, and with 3. 4 is more complicated; the compiler doesn't emit any `BlockExpression`s today, if we were to
have the C# compiler support out-of-order named parameters, it would need to do so in order to replicate C# named argument behavior, by
saving the out of order results and then passing them to the method call so side effects happen in the correct order. We don't like this,
and don't think the potential risk is worth it. Therefore, we plan to proceed with options 2 and 3. We don't think 4 is entirely out of
the question, but it would need to be a detailed investigation into where and how query providers would break or support this node.

#### Conclusion

We will allow optional parameters in expression trees, and we will allow named arguments, so long as the arguments are supplied in
parameter order (a la the C# 7.2 feature rules for non-trailing named arguments).

### Collection builder method parameter order

Champion issue: https://github.com/dotnet/csharplang/issues/8887  
Specification: https://github.com/dotnet/csharplang/blob/0d5e1f2c0864e65c6163e4a06405720493ba018a/proposals/collection-expression-arguments.md#collection-builder-method-parameter-order

Next, we looked at a small open question in collection expressions around the `Create` method, and where it will expect parameters to be
located. We have a standard pattern in the BCL for such create methods, which is to have arguments such as the comparator first, and then
the actual contents of the collection to be created. We'd prefer to stick with this pattern for now, absent examples that need some other
pattern. If we do find examples that need a different order, we can consider some way for a type author to explicitly indicate which
parameter is the "collection contents" parameter in the future, such as an attribute or other piece of metdata on the parameter. Until we
have such examples, though, we'll go with the simple solution of the contents must be the last parameter.

#### Conclusion

The `ReadOnlySpan` of collection contents must be the last parameter of the `Create` method.

### Ignored directives

Champion issue: https://github.com/dotnet/csharplang/issues/8617  
Specification: https://github.com/dotnet/csharplang/blob/a71774147c58d45efb5c6515c41665267684c9c5/proposals/ignored-directives.md

Finally today, we took a look at this proposal for ignored directives. This was a proposal opened a number of years ago in anticipation
of `dotnet run file.cs` eventually becoming a thing, and now that that effort is moving forward, it's time to talk about how the C# file
will interact with this system.

We want the system to be able to iterate without needing direct input from the compiler for every change. Given that, we think the bespoke
`#sdk`, `#package`, and other directives shouldn't exist. We also think that just using `#!` for everything is a bad idea; it would
complicate parsing and set up scenarios where the first line of the file isn't actually a valid `#!` directive for running the file.
For now, we like the `#:` proposal; use the `#!` directive specifically for shell communication as the first line in the file, and `#:`
for SDK communication otherwise. We like the brevity of the directive for this purpose, but would potentially be open to other syntaxes
based on feedback from initial usage.

#### Conclusion

We accept `#!` and `#:` as the directive syntaxes for this feature, and look forward to working with the SDK and ecosystem on driving this
feature forward.
