2.7 KiB
C# Language Design Notes for Dec 6, 2017
Agenda
Range
Several arguments against a generic Span<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:
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
:
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.