151 lines
5.1 KiB
Markdown
151 lines
5.1 KiB
Markdown
|
|
# 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>`
|
|
|
|
2. 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.
|
|
|
|
3. `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.
|
|
|
|
3. `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. |