Bug 5395 – Interval literals

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-01-01T06:32:00Z
Last change time
2016-10-14T15:11:44Z
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2011-01-01T06:32:05Z
Sometimes it's positive to replace some language feature with good Phobos implementations (like complex numbers), but language design is an iterative process, so sometimes it's positive to go the other way too. Tuples and number intervals are two examples where I think it will be good to add some syntax sugar back into the front-end. This enhancement request is about the number intervals. I suggest for the two following syntaxes to be seen by the compiler as equivalent, as syntax sugar of each other: foreach (i; 0 .. 10) foreach (i; iota(0, 10)) So I suggest the x..y syntax to become first class and to mean std.range.iota(x,y). An extension of the interval literal may allow a step value too: 0 .. 10:2 Once present the interval literal becomes useful to remove a () from lazy expressions, making them more readable: reduce!max(map!foo(1 .. 1000)) Instead of: reduce!max(map!foo(iota(1, 1000))) If the interval literal becomes first class, it's possible to use it for ranged types, or interval tests too: if (x in 5 .. 20) {...} If iota becomes syntax sugar for the ranged sequence, then the compiler is able to compile better simple code like this: foreach (i; iota(0, 10, 2)) {...} See also bug 4603
Comment #1 by denis.spir — 2011-02-09T04:52:39Z
(In reply to comment #0) > I suggest for the two following syntaxes to be seen by the compiler as > equivalent, as syntax sugar of each other: > foreach (i; 0 .. 10) > foreach (i; iota(0, 10)) > > So I suggest the x..y syntax to become first class and to mean > std.range.iota(x,y). +++ > An extension of the interval literal may allow a step value too: > > 0 .. 10:2 Rather doubtful on this; actually topic of your other enhancement request http://d.puremagic.com/issues/show_bug.cgi?id=4112; see comment there. > Once present the interval literal becomes useful to remove a () from lazy > expressions, making them more readable: > reduce!max(map!foo(1 .. 1000)) > Instead of: > reduce!max(map!foo(iota(1, 1000))) > > If the interval literal becomes first class, it's possible to use it for ranged > types, or interval tests too: > if (x in 5 .. 20) {...} Yo, just suggested this and the above (both syntaxes are equivalent) on the mailing list. > If iota becomes syntax sugar for the ranged sequence, then the compiler is able > to compile better simple code like this: > foreach (i; iota(0, 10, 2)) {...} The important point is that, whatever representation and/or rewriting happens on the implementation side, on the language side i..j provide range-compatible semantics (like arrays). It needs not /be/ an instance of Iota (which may also be rewritten, indeed). Denis
Comment #2 by bearophile_hugs — 2011-02-09T10:56:28Z
Comment #3 by bearophile_hugs — 2011-02-12T04:56:42Z
Michel Fortin: > how do you rewrite this using the new proposed syntax: > > auto aa = [iota(a, b, c): 1, iota(d, e): 2];
Comment #4 by denis.spir — 2011-02-12T05:36:01Z
(In reply to comment #3) > Michel Fortin: > > > how do you rewrite this using the new proposed syntax: > > > > auto aa = [iota(a, b, c): 1, iota(d, e): 2]; Annoying. What about reusing '..' instead? Not obvious, sure, but should not introduce syntactic issues. The initial proposal of ':' is far to be obvious anyway, I guess. auto interval = 1..9..2; auto aa = [a..b..c:1, d..e:2]; Or a single dot (since intervals apply only on ints AFAIK): auto interval = 1..9.2; auto aa = [a..b.c:1, d..e:2]; But then we get a lexer ambiguity problem. Could be reinterpreted at compile-time; still, a bit stupid? Other solution: group it using (). Either () is part of the interval syntax, or optional in case of possible ambiguity: auto interval = 1..9:2; auto interval = (1..9:2); auto aa = [(a..b:c):1, d..e:2]; auto aa = [(a..b:c):1, (d..e):2]; I like it (but am not such a fan of saving keystrokes as Bearophile is ;-) Finally, let it down. Frequence of interval notations in code? Relative frequence of interval notations requiring a step? Denis
Comment #5 by bearophile_hugs — 2011-02-12T14:53:19Z
Peter Alexander: > auto foo = [ 1..10 : 2, 2..20 : 3 ]; > > Is foo an AA of ranges to ints, or an array of stepped ranges? Lazy strided intervals as associative array keys is not a common need. But there are few other situations: auto r = pred ? 1..10 : 2 : 2..20 : 3; Where the range syntax is not usable you may use the function from Phobos as fall-back: auto r = pred ? iota(1,10,2) : iota(2,20,3); A possible alternative is to require parentheses where the syntax is ambiguous: auto foo = [(1..10 : 2), (2..20 : 3)]; auto r = pred ? (1..10 : 2) : (2..20 : 3); Another alternative is to use .. to separate the stride too: auto foo = [1..10..2, 2..20..3]; auto r = pred ? 1..10..2 : 2..20..3; Here I assume that the interval syntax is usable on integral values only, like ints, uints, chars, wchars, BigInts, etc. For floating point values you use iota again: iota(1.0, 10.0, 0.5)
Comment #6 by denis.spir — 2011-02-12T23:35:51Z
(In reply to comment #3) > Michel Fortin: > > > how do you rewrite this using the new proposed syntax: > > > > auto aa = [iota(a, b, c): 1, iota(d, e): 2]; I like the proposal by Andrej Mitrovic on the mailing list: But maybe we could extend the array slice syntax to construct [iota] ranges: filter!`a % 2 == 0`([1..5]) auto r = [0 .. 5]; So if the slice sits on its own it becomes a range. Or is this too scary/ambiguous? I don't really like them alone: filter!`a % 2 == 0`(1..5) auto r = 0 .. 5; My comment: This means basically, for slicing: (array expression)~(interval notation) ==> slice operation This also allows noting a step without any syntax problem: [start..end:step] Finally, as noted by someone, this allows reinterpreting slicing as a special case of indexing, possibly unifying metamethods opIndex & opSlice, and opening the door to easier custom rules like multi-dimensional semantics. The issue is indeed this syntax conflicts with current: foreach (n ; i..j) Too bad we have not had this form from the start... Denis
Comment #7 by bearophile_hugs — 2011-03-06T09:43:09Z
Comment #8 by andrei — 2016-10-14T15:11:44Z
I suggest converting this into a DIP if there's interest.