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]`.