# C# Language Design Notes for Feb 26

***Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!***

"We introduced off-by-two errors!"

# Ranges

Python has indexing from the end, as well as range endpoints from the end. The last element is -1.

In ranges, the only way to express "to the end" is then to omit the end point (since they're also exclusive).

There is no way to talk about the position at "length" in Python. We are concerned with that approach, because you can easily make an error where you compute "distance from end" into a variable as 0, then accidentally it means "from beginning" instead of "from end".

The benefit of `^x` and `~x` is that they can fully express the "at index length" index as `~0` or `^0`.

Pro `~`:
* Just works
* No new syntax or types

Against:
* No protection against bugs (accidentally using `-`)
* Cannot add overloads that go from end
* No documentation for whether the int indexer understands negative
 
If we do this just for `Range` (including maybe `^` syntax), then it's hard to add `Index` later.

Existing types with indexers (e.g. arrays and strings) would be lots of work to evolve to make use of `Index` (or `Range` for that matter).

Could the `int` conversion to `Index` also take negative numbers, but with the Python meaning? Then it would essentially "subtract 1 from negative numbers".

The problem with `~` is that it is off-by-one from Python. The `~` can only hide it so much, but if you look in the debugger, `~1` is `-2`!

Current options:

1. Do like Python: just live with "0 from end" not being expressible as a number; it's a special case (5)
2. Use ~ (1)
3. Add `Index` and `^` (6)
4. Don't support "from end" (1)

Could we disallow "mixed" ranges (one from beginning one from end)? That's not a reasonable restriction. `1..-1` strips off the double quotes, etc.

We're down to two options, 1 and 3. Let's take these through VB design as well, to see if we get new insights.

Most likely to care are app developers, like web developers. Library authors will just be trading in Ranges that are already created.

# Bestest betterness

1. When gathering candidates, if one of them has inferred type arguments that do not satisfy constraints, we'll discard the candidate. This means you can overload on constraints!
2. If you're in a static context, instance members are discarded, and vice versa. Only simple names in instance members will include both, as well as Color/Color situations
3. Converting a method group to a delegate type, we consider a conversion where the return type is wrong, even though that conversion is an error. Methods with such parameters will also be weeded out.

In the first round this led to worse error messages (because we no longer pointed to the "wrong" method), but this has been fixed.

This has been done in a way to not affect type inference.


# Fixed arrays