csharplang/meetings/2017/LDM-2017-12-06.md
2018-03-20 09:03:16 -07:00

70 lines
2.8 KiB
Markdown

# C# Language Design Notes for Dec 6, 2017
***Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!***
## Agenda
# Range
Several arguments against a generic `Range<T>`, such as conversions between them.
Step() should maybe be step with range
# Operator `..`
`op_Range` in IL, marked as special method.
Should it be target typed?
Example: `FloatRange`. If we don't supply it, no-one ever can, unless we make it target typed.
Conversion between ranges does not seem like a good idea: Even though it's technically possible, it might not make conceptual sense.
Target typing seems better. There's an issue with compat and ambiguity, where operator declarations on the operands and the result may clash. The proposal is to let the target type win. But that may not be necessary. The operator declared in the operands corresponds to the "natural type", and if there's an exact match to the target type, it would win.
For `IntRange` we get:
``` c#
IntRange r = 1 .. 10;
```
Here `..` is defined on the operand types, and when that one is applied, the natural type is `IntRange`, and that wins in overload resolution.
For `LongRange`:
``` c#
LongRange lr = 1 .. 10;
```
That works just dandy with target typing, but if there's also a conversion from `IntRange` to `LongRange` then there seem to be two competing conversions. We probably don't want that, and need to think through if that's the case, and if so how to amend it.
## Alternative 1
Look for an instance method (which can be an extension method), and have declared conversions and no target typing. That would lead to N x N extension methods and N x N conversion methods having to be declared to get the same "convenience".
But for the situation of having `x .. y` and *not* a target type, it would be simpler, in that it wouldn't need the `..` operator to be retrofitted to existing types.
## Alternative 2
Have a generic `Range<T>`. A range expression produces a range of the best common type of the operands. It can be target typed to another `Range<S>`, as long as there's a conversion from the end points to `S`. Comparison is done by expanding to use of `<=`, which better be defined.
# Wrap around
Let's make sure the library side doesn't allow foreach to throw on the boundary (`int.MaxValue`) or wrap around infinitely.
# Inclusive/exclusive
For floating point/non-enumerable, there's real expressiveness at stake. That's probably not the main scenario, though.
Problem with exclusive: I create a range from Sunday to Saturday, I need a name for the thing outside the range. Also, what if I need `int.MaxValue` as the top element?
Problem with inclusive: Going to array.Length. Slicing and windowing.
Evidence in the Mono code base for instance, shows both prevalent, with a slight overweight of inclusive.
# Range pattern