Add raw notes

This commit is contained in:
Mads Torgersen 2018-04-06 10:44:01 -07:00
parent 82738ecc3a
commit f4791be052
2 changed files with 222 additions and 0 deletions

View file

@ -0,0 +1,59 @@
# C# Language Design Review Apr 2, 2018
***Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!***
# C# 8.0
Tag with needs runtime support or ecosystem support
Process: make it more clear where we are. Help people understand when beating on a feature would be wasting their time.
# Nullable
Make sure we work backwards to understand how long it takes to build the whole experience.
## Dotted names
We probably have a good level of invalidation.
## Type strengthening
Based on null state and `!`. Should definitely keep that.
## !
Because `!` only applies "right here", it is ok to also silence warnings recursively. But we should not consider automatically flowing `!` on the given execution path then, because you may not always want to silence all warnings on the variable subsequently.
## Unannotated assemblies
Maybe there should be a warning that you are referencing unannotated assemblies.
## Tracking non-null variables and "W" warnings
Understand the motivation. This is ok.
## Type parameters
Unconstrained may be either nullable or nonnullable, so we have to be defensive. That's quite restrictive, but probably right.
## Structural relationships
In TypeScript there are more type relationships because of structural types. We don't even get to first base here.
# Ranges
## Open
Sure about syntax? Should there be `*` instead?
## From end
Indexing from end is probably more common in Python than any ranges at all! Cutting that off with `-x` syntax is a shame.
If we weren't doing `^`, just do ranges with positive numbers. Solve the "from end" problem in general or not at all.
## Conclusion
If indexing and multiple dimensions are in the core syntax, might as well do the whole enchilada. Optimize in compiler when using `^` on arrays and strings.

View file

@ -0,0 +1,163 @@
# C# Language Design Notes for Apr 4, 2018
***Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!***
## Agenda
# Design review follow-up
## Ranges
Let's flip what we prototype to implement the `Index` and `^` option.
``` c#
(Index) ^ i
```
## Nullable
Let's start having the discussion on external annotation soon, bringing in the right people from BCL's etc.
One proposal for external annotations:
``` c#
[Nullable(typeof(MyClass))]
class C
{
static object f1;
static object? f2;
}
```
Nice because it's source based.
May also use or mirror JetBrains' annotations. https://github.com/JetBrains/ExternalAnnotations
Offer the capability just for BCL vs for general libraries?
# Ordering of ref and partial keywords
There's a strict ordering around `ref` and `partial` preceding `struct`. We need to relax a bit, or a lot:
1. `ref partial` and `partial ref` are both allowed, but need to be right before `struct`
2. allow `ref` and `partial` anywhere in the modifier list
Let's do 2, since that leads to a more consistent language. No reason to have special limitation on some modifiers, even though there might be guidance (and code style enforcement in the IDE) to put things in a certain order.
# Patterns
In Roslyn, we would probably put deconstructors that only return the "important" data, whereas non-optional tokens would be left out. (We're essentially reinventing abstract syntax tree.) If we evolve the node, we can add another overload of the deconstructor with more out parameters.
The code gen is now roughly as efficient as what you would have written, though it doesn't know about testing `Kind` fields, of course (which actually isn't always more efficient).
## Order of evaluation in pattern-matching
Giving the compiler flexibility in reordering the operations executed during pattern-matching can permit flexibility that can be used to improve the efficiency of pattern-matching. The (unenforced) requirement would be that properties accessed in a pattern, and the Deconstruct methods, are required to be "pure" (side-effect free, idempotent, etc). That doesn't mean that we would add purity as a language concept, only that we would allow the compiler flexibility in reordering operations.
It may be a little disconcerting not to specify order of evaluation, but if patterns don't do what user code will do, they will be slower and will not be generally adopted/useful.
People generally don't care what the spec says - they care if something changes release over release. So it's more important that the compiler doesn't change what it generates from version to version.
### Conclusion
We're good with this. We don't want to slow down pattern matching just to guarantee order of evaluation when people do something side effecting where they shouldn't.
We'll make an effort to discover if changes to the compiler change the output of existing code. Then we'll have a discussion about whether that is warranted.
## Range Pattern
If we have a range operator `1..10`, would we similarly have a range pattern? How would it work?
``` c#
if (ch is in 'a' to 'z')
switch (ch) {
case in 'a' to 'z':
```
### Conclusion
We like the idea, but are unsure about value yet, and probably want to pursue it in connection with `foreach` and `from` uses.
## `var` deconstruct pattern
It would be nice if there were a way to pattern-match a tuple (or Deconstructable) into a set of variables declared only by their designator, e.g. the last line in this match expression
``` c#
var newState = (GetState(), action, hasKey) switch {
(DoorState.Closed, Action.Open, _) => DoorState.Opened,
(DoorState.Opened, Action.Close, _) => DoorState.Closed,
(DoorState.Closed, Action.Lock, true) => DoorState.Locked,
(DoorState.Locked, Action.Unlock, true) => DoorState.Closed,
var (state, _, _) => state };
```
(Perhaps not the best example since it only declares one thing on the last line)
This would be based on some grammar like this
``` antlr
var_pattern
: 'var' variable_designation
;
```
where the _variable_designation_ could be a _parenthesized_variable_designation_, i.e. generalizing the current construct.
To make this syntactically unambiguous, we would no longer allow `var` to bind to a user-declared type in a pattern. Forbidding it from binding to a constant would also simplify things, but probably isn't strictly necessary.
At a recent LDM it was suggested that `var` could perhaps be used as a placeholder for an unknown type taken from context. But that would conflict with this usage because this usage changes the syntax of what is permitted between the parens (designators vs patterns).
This is implemented in the current prototype, in which `var` is now a contextual keyword.
### Conclusion
This is a useful shorthand, and we already love it in C# 7.0 deconstructing declarations. We should have it here too, for symmetry and brevity.
## ref/lvalue-producing pattern switch expression
As currently designed, the “switch expression” yields an rvalue.
``` c#
e switch { p1 when c1 => v1, p2 when c2 => v2 }
```
@agocke pointed out that it might be valuable for there to be a variant that produces a ref or an lvalue.
1. Should we pursue this?
2. What would the syntax be?
`e switch { p1 when c1 => ref v1, p2 when c2 => ref v2 }`
You could argue that while the conditional (ternary) operator is often used in perf-sensitive code, and combining with `ref` was important there, it's less likely to see a combination of patterns and high-performance code.
### Conclusion
This feels right, but is not all that important. Let's keep it on the back burner.
## switching on a tuple literal
In order to switch on a tuple literal, you have to write what appear to be redundant parens
``` c#
switch ((a, b))
{
```
It has been proposed that we permit
``` c#
switch (a, b)
{
```
There are a couple of ways of doing it:
1. Make the outer parens optional when there is a tuple literal
2. Make the inner parens optional when there is a tuple literal
3. It's a list that's part of the switch statement (and expression, when we get there)
## Conclusion
Let's do 1. This means that in certain cases switch statements will no longer have parentheses, so analyzers that expect that will have to adjust.