117 lines
2.8 KiB
Markdown
117 lines
2.8 KiB
Markdown
|
# C# Language Design Notes for Jan 22, 2018
|
|||
|
|
|||
|
***Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!***
|
|||
|
|
|||
|
# Range
|
|||
|
|
|||
|
``` c#
|
|||
|
var numbers = ints[from..to];
|
|||
|
```
|
|||
|
|
|||
|
Should this mean inclusive?
|
|||
|
|
|||
|
Not many languages have *only* inclusive ranges. Apart from F#, they tend to either have exclusive ranges or both (at the upper end; the lower is always inclusive).
|
|||
|
|
|||
|
Python has exclusive, though a lot of people seem to be confused about it.
|
|||
|
```
|
|||
|
var s = a[0..a.Length];
|
|||
|
```
|
|||
|
|
|||
|
Do we read it out loud as "zero *to* a dot length"? If so, then the intuition really does suggest inclusive.
|
|||
|
|
|||
|
```
|
|||
|
foreach (var x in 1..100) { ... }
|
|||
|
|
|||
|
foreach (var x in 0..100) { ... }
|
|||
|
```
|
|||
|
|
|||
|
You don't use constants in practice, though, except as a zero lower bound. In F# it is often a bit of a pain for do a for loop for array iteration, for instance.
|
|||
|
|
|||
|
Exclusive is "in the middle" between inclusive and start/length.
|
|||
|
|
|||
|
``` c#
|
|||
|
// The three scenarios with exclusive
|
|||
|
Range incl = start..end+1;
|
|||
|
Range excl = start..end;
|
|||
|
Range rel = start..start+length;
|
|||
|
Range emp = 0..0;
|
|||
|
|
|||
|
// The three scenarios with inclusive
|
|||
|
Range incl = start..end;
|
|||
|
Range excl = start..end-1;
|
|||
|
Range rel = start..start+length-1;
|
|||
|
Range emp = 0..-1;
|
|||
|
|
|||
|
// The three scenarios with start/length
|
|||
|
Range incl = start:end-start+1;
|
|||
|
Range excl = start:end-start;
|
|||
|
Range rel = start:length;
|
|||
|
Range emp = 0:0;
|
|||
|
```
|
|||
|
|
|||
|
[1/22/2018 10:27 AM] Miguel de Icaza:
|
|||
|
From the TensorFlow (504), NUmPy (1,063) - both numeric heavy- and Python’s core libraries (2,094). Only one use of “end-range plus one”, ie, used in exlusive way
|
|||
|
|
|||
|
[1/22/2018 10:31 AM] Miguel de Icaza:
|
|||
|
More data for you: in F#’ compiler source code, out of 1,034 uses of ranges, 51 use the idiom limit-1
|
|||
|
|
|||
|
[1/22/2018 10:32 AM] Miguel de Icaza:
|
|||
|
Fixed: 64 out of 1,034
|
|||
|
|
|||
|
[1/22/2018 10:39 AM] Miguel de Icaza:
|
|||
|
Go source code, out of 5865, 11 need “+1”
|
|||
|
|
|||
|
One idea is that when we start talking about sets of numbers (not enumerations) we should just have a different syntax. That's in pattern matching/containment checking, etc.
|
|||
|
|
|||
|
``` c#
|
|||
|
x is in 3 to 5;
|
|||
|
x is in 3--5;
|
|||
|
x is in 3 !.. 5
|
|||
|
```
|
|||
|
|
|||
|
Tensors are really just multidimensional arrays, so similar arguments apply.
|
|||
|
|
|||
|
|
|||
|
Let us go with `..` means exclusive.
|
|||
|
|
|||
|
|
|||
|
## Open ended
|
|||
|
|
|||
|
Is represented as such in the type. Syntax:
|
|||
|
|
|||
|
``` c#
|
|||
|
Range openL = ..5;
|
|||
|
Range openR = 3..;
|
|||
|
Range openLR = ..;
|
|||
|
```
|
|||
|
|
|||
|
``` c#
|
|||
|
r1 = ..12;
|
|||
|
r2 = 3..;
|
|||
|
|
|||
|
var a = new int[5];
|
|||
|
a[r2]; // fine
|
|||
|
a[r1 * r2]; // fail;
|
|||
|
Range x = new Range(r1.Start, r2.End);
|
|||
|
Range x = r1.EndAt(r2);
|
|||
|
```
|
|||
|
|
|||
|
Would like not to write conditional logic to manipulate and combine ranges.
|
|||
|
|
|||
|
## Natural type
|
|||
|
|
|||
|
``` c#
|
|||
|
var r = 4..6; // infer Range
|
|||
|
```
|
|||
|
|
|||
|
If we do this, `Range` will be forever tied to it as the preferential type.
|
|||
|
|
|||
|
We're good with that.
|
|||
|
|
|||
|
|
|||
|
## Start/length
|
|||
|
|
|||
|
Can technically be added later, but if we want to do it we should try to do it now.
|
|||
|
|
|||
|
|