csharplang/meetings/2021/LDM-2021-03-24.md
2021-03-25 10:49:29 -07:00

4.5 KiB

C# Language Design Meeting for March 24th, 2021

Agenda

  1. Improved interpolated strings
  2. field keyword

Quote of the Day

  • "We all want to be happy"

Discussion

Improved interpolated strings

https://github.com/dotnet/csharplang/issues/4487

Today, we looked at one of the open questions in improved interpolated strings, conditional evaluation of the interpolated string holes. The proposal today allows the interpolated string builder to return false from creation or from any TryFormat methods, which short-circuits evaluation of any of the following interpolation holes. This has some pros and cons:

  • Pro: Interpolation holes can be expensive, and if they don't need to be executed it gives an easy way to achieve semantics that people often do with lambdas currently.
  • Con: This is "invisible" to the user. There isn't a way, looking at an interpolated string expression as an argument to a method, to tell whether the holes in this string will be conditionally-evaluated or not.

This conditional evaluation can have visible impacts when the interpolated string expression has side-effects. For example, a conditionally-evaluated string won't have its holes impact definite assignment, because we can't be sure that the expressions were evaluated. Further, due to the way the proposal is written, upgrading to a new version of a library could change the semantics of existing code, as the library author could introduce a new overload that the interpolated string prefers, introducing conditional evaluation of what used to be unconditionally-evaluated code. While library upgrades can always introduce behavior changes in a user's code (introducing a new instance method that is preferred over an extension method, for example), this would be expanding such concerns.

We considered whether to have some syntax marker to indicate that "the interpolated string expression holes will be conditionally evaluated", such as putting a ? in the hole (like $"{?name}"). While this syntax calls out that conditional evaluation is occurring, we're concerned that it leans too far into making new language features obvious. We'd need to start shipping analyzers that ensure that users are using this syntax where possible, and it could become another pitfall of "make sure you add this syntax for maximum performance."

Finally, we looked at whether we could investigate a broader feature around lazily-evaluated arguments. Today, users often use lambdas to defer this type computation. We're concerned by building a feature like this on lambdas, however, because of the implicit allocation cost here. If we make advances in this space later, we can look at incorporating those advances at that point, but we feel that we can move forward with conditional evaluation at this point.

Conclusion

We will have conditional evaluation of interpolated string holes without a special syntax for calling this out.

field keyword

https://github.com/dotnet/csharplang/issues/140

We looked at how the field identifier will be resolved inside a property, and what exactly will indicate to the compiler that the property should have a backing field generated for it. The proposal calls for resolving field to the backing field when there is no other identifier named that in scope. We thought about a few alternatives:

  • Could we make field always a contextual keyword in property bodies, gated by target language version? We made a bigger break with record type names, but it was a very different break. record was used as a type name, which are by-convention PascalCase in C# programs. Here, we'd be breaking field as an identifier, which is much more common and fits in with standard C# naming practices.
  • Could we use a __ name? Identifiers with a __ are reserved by C#, so we can use one without breaking anyone. However, __ names are not common, only used for things that aren't common practice in C# (such as __makeref or __arglist).
  • Could we take a page from VB's book, and introduce a _PropName identifier? While it still has a potential conflict with class fields, the conflict should be much smaller, and theoretically resolving the ambiguity could be as easy as deleting the class field (provided we get the naming right), whereas a class field identifier could be entirely unrelated to the current property.

Conclusion

We'd like to explore the last 2 proposals a bit, and come back to the LDM with a fleshed out proposal after some thinking about it.