First class lazy Interval

Michel Fortin michel.fortin at michelf.com
Fri Feb 27 04:12:42 PST 2009


On 2009-02-27 04:43:46 -0500, bearophile <bearophileHUGS at lycos.com> said:

> D2 supports the interval syntax in the foreach:
> foreach (i; 1..1000) {...}
> 
> Such intervals are useful in a very large number of situations. So, 
> with the new Range support, it may be useful to allow the interval 
> syntax to be used in other contexts as well.
> So x..y may become a first-class lazy interval from x to y-1, that can 
> be passed to functions too, etc, and not just used into foreach (the 
> compiler can recognize it, and often optimize it away in many 
> situations, replacing it with a normal for() loop).

I agree that having first-class intervals in the language would make it 
better, especially when you want to pass intervals as function 
arguments.

In the D/Objective-C bridge, I've defined the NSRange struct (a Cocoa 
type representing an integer interval) so it can be created by typing 
NSRange[start..end] in adition to the traditional NSMakeRange(start, 
length). It's better than nothing, but even better would be the ability 
to omit NSRange[] entirely.


> 1) x..y..s
> where s is a step/stride, so you can define odd numbers, etc.
> 1..10..3 ==> 1 4 7
> 10..1..-2 ==> 10 8 6 4 2
> 1..5..1 ==> 1 2 3 4
> I don't like this syntax much, but I think it's acceptable.

May I propose that strides not be part of the interval syntax. Keep the 
interval simple (x..y) then define operators to transform them. Perhaps 
the modulus operator could create a steped interval (x..y % s), 
although this operator doesn't seem to fit exactly right. Perhaps just 
step(x..y, s) would be enough. It'd return a special struct for 
iterating the interval in bigger steps.

As for strides, why not just (a..b ~ c..d) for joining two ranges and 
~(x..y) for everything outside x..y ?


> 2) Such intervals may enjoy a fast opIn_r() method, for quick membership test:
> if (a in 0..10) {...}
> if (c in 'c'..'z'+1) {...}

That'd be great if you could use them in the switch statement too:

	switch (a)
	{
		case 0..10: break;
	}

The only downside is that it may confuse people who are accustomed to 
the GCC extension with define an inclusive interval this way:

	switch (a)
	{
		case 0...10: break;
	}

Perhaps we could make 3 dots mean an inclusive interval (including the 
second value in the interval), and 2 dots an exclusive one (excluding 
the second value).

-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/




More information about the Digitalmars-d mailing list