www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Range literals

reply Peter Alexander <peter.alexander.au gmail.com> writes:
I know that D2 is supposed to be closed for new features, but I thought 
I'd mention this anyway just in case it's deemed easy/simple enough for 
inclusion, or even if it will just get considered for later on.

Anyway, we all know that we can do the following:

   foreach (int x; 0..10)
     writeln(x);

That will print 0, 1, 2 .. 9.

We could also write it like this:

   foreach (int x; iota(0, 10))
     writeln(x);

for the same effect.

If we want only odd numbers then we can use:

   foreach (int x; filter!("a & 1")(iota(0, 10)))
     writeln(x);

but what we cannot write is:

   foreach (int x; filter!("a & 1")(0..10))
     writeln(x);

because 0..10 isn't a range literal -- it's a special notation that only 
applies to foreach loops and array slicing.

Proposal: Make a..b a literal that evaluates to iota(a, b) or some 
built-in equivalent. Of course, the $ symbol would not be valid for 
these literals.

More advanced proposal: Make .. into a binary operator, which is 
language-defined for integer data types (takes two integers, returns 
iota), and overloadable for user data-types. Why would you want to 
overload it? For linked data-structures, it would be an ideal candidate 
for creating a range between two links (linkA..linkB).

Pros
----
- Creates more uniformity and purity across the language i.e. if I can 
use X and Y to the same effect (as above) then I expect f(X) and f(Y) to 
have the same effect -- assuming that f is referentially transparent.

- Adds a nice, intuitive shorthand for a common practice, increasing the 
productivity and readability of D code.

- It removes a special case of foreach.

- Doesn't (shouldn't?) break backwards-compatibility. If reliance on 
std.algorithm.iota is a problem then perhaps it would be best encoded as 
a D runtime type.

Cons
----
- Slicing still remains a special case, which might confuse people into 
thinking that slicing is an operation that takes a range (arguably, this 
is already the case)

- Requires core language and compiler changes.


I also have a proposal for slicing along the same lines, but I'll leave 
that for later.
Aug 24 2010
parent Norbert Nemec <Norbert Nemec-online.de> writes:
On 24/08/10 08:56, Peter Alexander wrote:
 Proposal: Make a..b a literal that evaluates to iota(a, b) or some
 built-in equivalent.

Indeed, this has been discussed before and I believe people were generally in favor of this idea. I agree that it should still be considered for DMD2. As I see it, this would not be a new feature on its own, but rather a modification to round up the existing set of features.
 Of course, the $ symbol would not be valid for
 these literals.

Indeed -- the $ has nothing to do with the "range" but rather with the indexing expression within which it appears.
 I also have a proposal for slicing along the same lines, but I'll leave
 that for later.

This was discussed along with it and is actually essential for the concept: With a..b turning into an expression of its own, 'opSlice' is not needed any more. The same effect could be achieved by overloading opIndex for the range expression's type. The whole idea is crucial for implementing multidimensional arrays. It is the simplest way to allow implementing mixed indexing expressions like myarray[a,b..c,d]
Aug 24 2010