csharplang/meetings/2021/LDM-2021-01-11.md
2021-01-11 15:10:24 -08:00

3.6 KiB

C# Language Design Meeting for Jan. 11th, 2021

Agenda

  1. Required properties simple form

Quote of the Day

  • "You didn't want to hear me say um anyway... So, um"

Discussion

Required properties simple form

https://github.com/dotnet/csharplang/discussions/4209#discussioncomment-275575

Today, we took a look at an extension to the existing required properties proposal, that proposed a syntax form that simplifies the base case of the proposal to remove complexity for what we believe is the 80% use case. This form adds a require modifier on a property definition. These requirements and then automatically added to the implicit parameterless constructor of a type, if present, and can be added to explicit constructors with require default, in the same place as the init lists of the last proposal.

First, we discussed the syntax in the proposal, and potential alternatives. We like the move to put a modifier on properties and fields as it makes implicit constructor scenarios much simpler, but something still feels off about the full-blown form of this syntax, with require { Property, List }. We could draw on type parameter constraint clauses, and a rough first attempt looks promising:

public Person() require FirstName, LastName
{
}

public Student() require ID
    : base()
{
}

The proposed ability to assign to properties in the require list might be either odd or outright impossible here, depending on potential syntactic ambiguities we haven't thought of yet, but the syntax immediately feels more like C# than the previous curly-brace version.

Where we spent the bulk of meeting, however, was on how implicit we can make the default parameter list. We had immediate pushback on require default even being necessary on constructors: why can't we just infer that for all constructors in a type, and then have a syntax for removing all requirements? There's a feeling that require default is just busywork, and the compiler should just infer the defaults from the properties and fields in the type that are marked require. Some proposals for the ability to remove all requirements are require none and require default = _. We also considered a version of the proposal that goes even further, that doesn't allow constructors to require additional items: you mark a property or field as required, then remove requirements in the constructor itself. In this model, constructors would be unable to add new requirements, which does remove some potential scenarios, but could simplify the feature significantly. Roughly speaking, the three versions of the proposal can be summarized as follows:

  1. Only implicit constructors get implicit require lists.
  2. All constructors get implicit require lists, and can add requirements of their own:
    1. If the constructor calls base in some manner (including implicit calls to the object constructor), that list is all the fields and properties in the type that are marked require.
    2. If the constructor calls another constructor on this, then it simply advertises chaining to that constructor, potentially removing some requirements if it takes care of them in its body.
  3. All constructors get implicit require lists, and cannot add to them. They can only remove them, and there is no require syntax. This version will need a new syntax for removing requirements, but that will likely be much simpler than the full require clause and need less user education.

After a read of the room, we're interested in seeing where proposal 3 goes. We'll work on fleshing that out with examples and bring it back to LDM soon.