array operations and ranges

Manu via Digitalmars-d digitalmars-d at puremagic.com
Sat May 2 08:38:10 PDT 2015


On 1 May 2015 at 15:10, Walter Bright via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On 4/26/2015 3:17 AM, Manu via Digitalmars-d wrote:
>>
>> There must be years of thoughts and work on this sort of thing?
>> It seems arrays and ranges are unnecessarily distanced from
>> eachother... what are the reasons for this?
>
>
> I think you've got the start of some dazz ideas. I want to think about this
> more.

Cool. I'm finding myself using ranges more and more in my code these
days. My current projects are almost exclusively range based code.
The most problem cases are:
  float[100] stackArray = range.map!(e => e*2)[]; // <- I often have a
lazy operation that needs to be resolved to the stack. It's sad to
break this on to another line and use .copy()

Other cases come when I have a standard array operation, for instance:
  a[] = b[]*2;
I often want to apply an operation that is expressed via a lazy range,
ie, map!() or something. As soon as you do that, you need to rearrange
the code:
  a[] = b.amplitude[]*2; // <- where amplitude is a function that
returns map!(e=>20*log10(abs(e)))
Or should it be:
  a[] = b[].amplitude*2;// ?
Either way, it must be refactored to keep the compiler happy:
  b[].amplitude.map!(e=>e*2).copy(a);

I think that's a lot less easy to follow. I would try to avoid that
compared to the line above, but that creates a mutual exclusion with
the use of ranges and simple, readable code.


My experience is revealing to me that about 60% of my lines (in
range-related code) are map!(e=>...), and that's a lot of boilerplate
surrounding '...', obscuring the actual operation.
I also find the paren nesting gets pretty deep (for instance, the map
above) and the code is harder to follow than a traditional foreach
loop.
If we can do normal array operations on ranges, and have them lower to
sensible things (like map), I think that sugar will make range
programming a lot more succinct.

Perhaps my 'amplitude' function above could just be a scalar function?
I have one of them too, there are duplicates of most things because I
need to supply a range based version in parallel to the scalar
versions :/
Using UFCS; range.scalarFunction could be recognised as a
range-vs-scalar operation, the same as range*2. Ie, if there are no
proper overload/template matches, the compiler could try and lower to
map(e=>e.scalarFunction), assuming ElementType!Range is compatible
with the scalar function. That would eliminate most instances of
map!(), which are the highest contributor to pointless visual noise in
my current code.

Anyway, I think there's a lot of low-hanging fruit in this area, and I
think range based programming is proving to be one of the most
compelling (and surprisingly awesome) parts of D. With a little polish
it could become a major selling point.


More information about the Digitalmars-d mailing list