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