csharplang/meetings/2019/LDM-2019-03-04.md
Nick Schonning 870cc06bea fix: MD038/no-space-in-code
Spaces inside code span elements
2019-04-13 14:23:40 -04:00

5.1 KiB

C# Language Design Notes for March 4th, 2019

Agenda

  1. Nullable user studies
  2. Interpolated string and string.Format optimizations

Discussion

The 'default loophole'

var y = default(SomeStructWithNonNullableFields);

For the above, no warning is produced. The same is true for other default expressions. Is that OK?

Conclusion

Let's continue to track the nullability of the fields and not produce a warning. If we were to produce a warning it seems likely that we would produce warnings that are fundamentally unactionable because the user doesn't control the struct definition.

User study for nullable design

Today we went over the results from some user studies which simulated upgrading a code base with the non-nullable reference types design enabled.

There were 5 sessions, with two simple, but non-trivial, code bases:

  1. Telegram bot API
  2. Jil, a JSON serializer

Problems:

  • People had a fair amount of problems with member definitions, rather than bodies

    • We haven't published much information on how nullable interacts with definitions

    • Interface implementation and overriding are hard to fix since there are multiple places that need to change for every nullability change

  • Object initializer pattern is a persistent problem and the warnings don't seem to be providing much value

  • Constructor chaining is also a problem, where fields are piecewise initialized

    • Worse, when looking at the diagnostic, it was hard to get to the member, but when you're at the member, it's hard to verify this one was the problem because the diagnostic also does not occur

    • Almost everyone expected the warnings to be on the field/property

  • Nullable value types are a problem because they assumed that the problems were in nullable reference types, but the problems/solutions were subtly different

  • Diagnostic quality: generics were confusing, especially with tuples

  • Code fixes

    • People definitely want code fix to/from a nullable reference

    • They want a "fix-all" but it's not clear what that is

      • Some people wanted to see all the warnings, but then narrow down, especially via a code fix
  • Some people looked at the process as "satisfying the compiler" and others looking at "code hygiene" or "possible bugs"

    • There were at least a few null-safety bugs and no one found them in the time allotted, but probably would have

    • People who used the feature for overall code hygiene were more excited about using the feature

params and string interpolation

We discussed a new proposal for improving the performance of certain string.Format calls and interpolated string expressions.

Proposal: https://github.com/dotnet/csharplang/blob/master/proposals/format.md

Summary:

Using certain APIs, especially params and string.Format, can be a source of large performance problems. For certain projects (MSBuild) that are "string manipulation" programs, this can even be the main performance bottleneck for those programs.

Unfortunately, these APIs are also very convenient and, in many cases, the preferred way of accessing certain string manipulation functionality in the .NET framework. We'd like it if these features could be less heavyweight.

Proposals:

  1. Allow params to have any of the types Span<T>/ReadOnlySpan<T>/IEnumerable<T>

Advantages:

  • The callee cannot stash the parameter, so we can re-use an allocation

    • Sometimes users do this themselves because it's demonstrably more efficient

Consequences:

Overload resolution needs to change. New tie breaking rules:

  • ReadOnlySpan<T>

  • Span<T>

  • T[]

  • IEnumerable<T>

  1. Allow any standard Format overload resolution for interpolated strings

This feature builds on (1). If interpolated strings could use new Format overloads that have ReadOnlySpan<T> arguments, interpolated strings could share in the performance improvements.

  1. ValueFormattableString

Support new ValueFormattableString type as a target of a string interpolation.

This would be a breaking change when people upgrade to the new framework with the new type, but the older compiler always chooses the string overload (because it doesn't understand ValueFormattableString) and whenever they upgrade the compiler the call suddenly changes to ValueFormattableString. If those two methods do anything different, that would be a breaking change.

This feature also does not support using a custom type instead of ValueFormattableString. That could be desirable for a number of different scenarios, but would probably make the backwards compatibility constraints even more difficult.

We should carefully evaluate the tradeoffs in this feature and see what we can do to enable the most scenarios without taking unacceptable breaks.

  1. stackalloc the Span for params

It's not possible for C# to generally predict whether or not it's OK to stackalloc arguments. We're interested in enabling this functionality if provided with a "maybe stackalloc" helper from the runtime, and we'd like to keep that possibility open, but we will not do anything here until such a feature is available.