Andrei:

> But the most important question is: if the rewrite were done, to what extent 
> would that improve your use of the language? Integral intervals do occur 
> outside foreach and slices, but quite infrequently. In those cases you'd gain 
> by replacing iota(a, b) with a..b. Is this significant?<

I can list you why I think an interval syntax is better, but at the end you 
need to judge values:

- The basic range syntax is already present in two different situations in the 
language, for slices and foreach (switch-case statement use the dot-dot syntax 
for a related but different purpose). So D programmers don't need to learn a 
new syntax, the cognitive cost is probably negative.

- The 1 .. 5 syntax is present in math too (even if it often means a set closed 
on the right too).

- There is no need to learn to use a function with a weird syntax like iota, 
coming from APL. This makes Phobos and learning D a bit simpler.

- Both 1..5 and iota(1,5) are able to support the "in" operator. This is good 
because D doesn't support the a<X<b Python syntax.  X in a..b will mean a<=X<b.

- If the compiler front-end becomes aware of the interval syntax, it is able to 
perform "3 in 1..10" at compile-time too, simplifying sub-expressions even when 
they are inside other run-time expressions.

- With the interval syntax there is no need to import std.range, that's 
necessary for iota().

- the a..b syntax is shorter and a bit less noisy:  array(1..5) compared to 
array(iota(1,5)).

- The a..b syntax is extendible to cover the third stride argument of iota(). I 
suggest a..b:c  (The stride syntax is later usable for arrays too if the stride 
is a compile-time constant). Python shows several nice usages of the stride 
argument.

- Currently foreach(i; retro(iota(...))) or even foreach(i; iota(...)) are not 
as fast as foreach(i; ...). I hope this interval syntax will help DMD digest a 
lazy interval more efficiently.

- Interesting point, to translate this to interval syntax: iota(1.,-5.) it 
becomes 1...5. that's a mess. You need zeros:  1.0 .. 5.0

- Another interesting point, currently the semantics of iota() and the interval 
in foreach are not the same, only the second loop here raises an exception:

import std.stdio, std.range;
void main() {
    foreach (x; 1 .. -5)
        writeln(x);
    foreach (x; iota(1, -5))
        writeln(x);
}

In my opinion iota() semantics here must be the same as the foreach interval, 
and yield an empty iterable with no errors:
http://d.puremagic.com/issues/show_bug.cgi?id=4603


I like the interval literal syntax for static things too, example:
http://d.puremagic.com/issues/show_bug.cgi?id=4085
static foreach (x; 1 .. -5)

A first class literal syntax in D (typeid(typeof(1..5)) gives a new type) may 
become useful for slices too in objects/structs, this is Python 2.6 code:


class Foo(object):
    def __getitem__(self, key):
        print key
f = Foo()
f[1:2]


Output:
slice(1, 2, None)

Bye,
bearophile

Reply via email to