Add meeting notes for Feb. 19, 2020
This commit is contained in:
parent
33a60a1db1
commit
82e330685f
82
meetings/2020/LDM-2020-02-19.md
Normal file
82
meetings/2020/LDM-2020-02-19.md
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
|
||||||
|
# C# Language Design for Feb. 19, 2020
|
||||||
|
|
||||||
|
## Agenda
|
||||||
|
|
||||||
|
Exploring Value Equality
|
||||||
|
|
||||||
|
## Discussion
|
||||||
|
|
||||||
|
Proposal: https://github.com/dotnet/csharplang/issues/3213
|
||||||
|
|
||||||
|
* We haven't decided (yet) to add support for value equality on all
|
||||||
|
classes (separate from records)
|
||||||
|
|
||||||
|
* The behavior is actually that all fields _declared_ in the class are
|
||||||
|
members in the value equality, not all fields in the class (since inherited fields are not
|
||||||
|
included)
|
||||||
|
|
||||||
|
* Inheritance would be implemented using the previously described
|
||||||
|
proposals using the `EqualityContract` property
|
||||||
|
|
||||||
|
* Records wouldn't behave differently, except that they have `value` by
|
||||||
|
default
|
||||||
|
|
||||||
|
* The main difference with how records work in other places is that the semantics
|
||||||
|
of a record is otherwise decided by the members of the primary constructor, while in this
|
||||||
|
proposal the members of the record primary constructor have no special contribution to the value
|
||||||
|
equality semantics
|
||||||
|
|
||||||
|
* There's an evolution risk where we want to provide more complex things, like deep
|
||||||
|
equality, but these features don't support enough complexity to add it. Instead, we end up just
|
||||||
|
adding more keywords or more attributes. Consider array fields. The default equality is reference
|
||||||
|
equality, but sequence equality isn't particularly rare. How would users customize that?
|
||||||
|
A new keyword? Attribute? Writing Equals manually?
|
||||||
|
|
||||||
|
* Turns out we're finding a lot of customization pivots. String comparison is another one.
|
||||||
|
If we want to support all these scenarios attributes could be better. If we could use
|
||||||
|
attributes to supply an EqualityComparer that would be almost completely customizable.
|
||||||
|
|
||||||
|
* If equality is this complicated, should we only support simple generated equality for
|
||||||
|
records? Can we leave more complicated scenarios to tooling, like source generators?
|
||||||
|
|
||||||
|
Record equality: use the "primary" members or use all fields?
|
||||||
|
|
||||||
|
* Using all the fields is consistent with how structs work
|
||||||
|
|
||||||
|
* Using the "primary" members mirrors how the generation of `With` or other things
|
||||||
|
generated by a record with a primary constructor
|
||||||
|
|
||||||
|
* There does seem to be a possibility that after you get to a certain size, positional
|
||||||
|
records are less useful. In that case we want a path to the nominal record. If we do want the
|
||||||
|
nominal path, it's generally desirable that we want as little "record" syntax as possible.
|
||||||
|
If we choose the struct "use all the fields" approach, then we could use exactly the
|
||||||
|
same mechanism for both the "nominal" and the "positional" records.
|
||||||
|
|
||||||
|
* The nominal record syntax that has been floated is
|
||||||
|
|
||||||
|
```C#
|
||||||
|
record Point { int X; int Y; }
|
||||||
|
```
|
||||||
|
|
||||||
|
which generates
|
||||||
|
|
||||||
|
```C#
|
||||||
|
record Point
|
||||||
|
{
|
||||||
|
public int X { get; init; }
|
||||||
|
public int Y { get; init; }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Aside from the shorthand for properties, this generates Equals, GetHashCode and some form
|
||||||
|
of "With", which doesn't seem much different from proposals for a separable value equality. Is
|
||||||
|
there really much point in separating these proposals?
|
||||||
|
|
||||||
|
* One completely opposite possibility: bypass the question by prohibiting private members in the
|
||||||
|
positional record entirely
|
||||||
|
|
||||||
|
**Conclusion**
|
||||||
|
|
||||||
|
No hard decisions yet. Leaning slightly towards using "all declared fields" as the metric for
|
||||||
|
value equality. There's some support for the "no private fields approach."
|
Loading…
Reference in a new issue