Stupid little iota of an idea

bearophile bearophileHUGS at lycos.com
Wed Feb 9 10:54:34 PST 2011


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


More information about the Digitalmars-d mailing list