Language Idea #6892: in array ops, enable mixing slices and random access ranges

Meta jared771 at gmail.com
Tue Feb 6 02:14:35 UTC 2018


On Monday, 5 February 2018 at 17:35:45 UTC, Guillaume Piolat 
wrote:
> General idea
> ============
>
> Currently arrays ops express loops over slices.
>
>     a[] = b[] * 2 + c[]
>
> It would be nice if one could mix a random access range into 
> such an expression.
> The compiler would have builtin support for random access range.
>
>
> Example
> =======
>
> ------------------------------>3---------------------------------------
>
> import std.algorithm;
> import std.array;
> import std.range;
>
> void main()
> {
> 	int[] A = [1, 2, 3];
> 	
> 	// arrays ops only work with slices
> 	A[] += iota(3).array[];
> 	
> 	
> 	// Check that iota is a random access range
> 	auto myRange = iota(3);
> 	static assert( isRandomAccessRange!(typeof(myRange)) );
> 	
> 	
> 	// Doesn't work, array ops can't mix random access ranges and 
> slices
>         // NEW
> 	A[] += myRange[]; // whatever syntax could help the compiler
> }
>
> ------------------------------>3---------------------------------------
>
>
> How it could work
> =================
>
>     A[] += myRange[]; // or another syntax for "myRange as an 
> array op operand"
>
> would be rewritten to:
>
>     foreach(i; 0..A.length)
>         A[i] += myRange[i];
>
>
> myRange should not be a range without "length".
>
>
> Why?
> ====
>
> Bridges a gap between lazy generation and array ops, now that 
> array ops are reliable.
> Allow arrays ops to take slice-like objects.
>
>
> What do you think?

It's already possible, with only very slightly worse aesthetics:

struct VecOp(T)
{
     T[] arr;

     pragma(inline, true)
     T[] opOpAssign(string op: "+", Range)(Range r)
     {
         int i;
         foreach (e; r)
         {
             arr[i] += e;
             i++;
         }

         return arr;
     }
}

pragma(inline, true)
VecOp!E vecOp(E)(return E[] arr)
{
     return typeof(return)(arr);
}

void main()
{
     import std.range: iota;

     int[] a = [1, 2, 3];
     a.vecOp += iota(3);

     assert(a == [1, 3, 5]);
}

I'm not very good at reading assembly, so I have no idea whether 
it's comparable to doing `a[] += [0, 1, 2]`.


More information about the Digitalmars-d mailing list