# C# Language Design Meeting for April 23rd, 2025

## Agenda

- [Extensions](#extensions)
    - [Extension operators](#extension-operators)
    - [Overload resolution priority](#overload-resolution-priority)
- [Dictionary Expressions](#dictionary-expressions)

## Quote of the Day

- "This is worse, that's lambda calculus" "Is [redacted] in the meeting yet? Maybe they can explain it to us" "Not in one minute they can't"

## Discussion

### Extensions

Champion issue: https://github.com/dotnet/csharplang/issues/8697  
Specification: https://github.com/dotnet/csharplang/blob/feb7a075739e81393def6c28ab12eb7b8fdc3bb6/proposals/extensions.md

#### Extension operators

Proposal: https://github.com/dotnet/csharplang/blob/feb7a075739e81393def6c28ab12eb7b8fdc3bb6/meetings/working-groups/extensions/extension-operators.md

We started today by looking through the latest proposal on how we want to work with extension operators. We like the proposal in general, and spent time talking
about the open question: whether to put restrictions on scenarios where the operator could potentially "lose" to a built-in conversion. For example, if an
extension operator `+` is on a type parameter `T`, then when `int` is substituted for `T`, that operator could potentially silently lose to a language-default
operator. While this is true, we don't think we need to try and come up with a set of rules to protect users from this possibility; if it happens, it happens.
Unlike other types of restricted operators, there's no potential for the "wrong" thing to happen, where a built-in operator would be overridden by an extension
operator. Given this, we're happy with the proposal, and will not put restrictions on type parameter extensions.

##### Conclusion

Approved. We will not restrict extensions on type parameters with more rules about what operators are valid.

#### Overload resolution priority

Question: https://github.com/dotnet/csharplang/blob/feb7a075739e81393def6c28ab12eb7b8fdc3bb6/proposals/extensions.md#lookup

Next, we looked at a brief question on whether `OverloadResolutionPriorityAttribute` should apply to properties in extensions. This scenario can occur when
a single static class contains more than one extension block, which define an overloaded set of properties. In such a scenario, authors might want to use something
like ORPA to avoid ambiguity errors for their users. We think this is a good idea; there might be some discoverability issues with this solution, given that ORPA
can usually only be used on indexers, but ORPA itself is generally pretty niche and not well-known anyways. It's intended as an uncommon, last-ditch tool, not a
generalized solution for any lookup problem. The main question is timing: we don't think this is critical for v1 of extensions, so if it has to slip to the next
version of C# to get more important bits of extensions out the door, so be it.

##### Conclusion

We will allow ORPA to be used on extension properties, and the containing type of the extension property is the static class that contains the extension block.

### Dictionary Expressions

Champion issue: https://github.com/dotnet/csharplang/issues/8659  
Specification: https://github.com/dotnet/csharplang/blob/feb7a075739e81393def6c28ab12eb7b8fdc3bb6/proposals/dictionary-expressions.md#question-special-case-comparer-support-for-dictionaries-and-regular-collections

We [previously](./LDM-2025-04-14.md#arguments-for-interface-types) talked about what collection expression arguments should do on interface types, and as part of
that discussion, wanted to explore a more specialized syntax for just providing comparers. This syntax would potentially entirely replace the generalized
collection expression argument feature, so the working group went off and explored the idea. After looking at the results, we don't think a specialized syntax
for just comparers is the right approach. Even within the BCL, there's potential for more than just `capacity` and `comparer` arguments. `ImmutableDictionary`,
for example, has both `keyComparer` and `valueComparer` parameters. We also don't want to invent 2 ways to specify parameters for dictionaries, one that needs to
be used when the target type is an interface, and one for when the target type is any other concrete type. Given that, we want to proceed with the full collection
expression arguments feature, even for interfaces. Our main question at this point is whether to use a curated list of constructors for the dictionary interfaces,
or let the full set of constructors of the underlying type show through. For `IDictionary`, it seems like it might be ok; after all, we guarantee what the concrete
type used to create one is. However, for `IReadOnlyDictionary`, we do not guarantee this, we only say that a compatible implementation must be used. Therefore, for
now, we will curate the constructors to just the ones that take a comparer, capacity, or both, and no others. We can expand in the future if there are motivating
scenarios, rather than being very lax now and potentially regretting our inability to change later.

#### Conclusion

Specialized comparer-only syntax is abandoned. We will move forward with collection expression arguments for interface types, using a curated set of constructors
that take either a comparer, capacity, or both.
