<br><br><div class="gmail_quote">On Fri, Feb 26, 2010 at 10:07, Norbert Nemec <span dir="ltr">&lt;<a href="mailto:Norbert@nemec-online.de">Norbert@nemec-online.de</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div class="im">Jason House wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
Would sum!( &quot;i&quot;, &quot;a[i]*b[i]&quot; ) be acceptable? That should be achievable with a template mixin that does string mixins under the hood.<br>
</blockquote>
<br></div>
It is indeed a solution for the problem, but I still don&#39;t like it too much. For one, writing expressions as strings always feels awkward. Even though D can handle these strings at compile time, it just doesn&#39;t feel like writing native D code.<br>

<br>
Beyond this &quot;gut feeling&quot; I also see two technical problems:<br>
<br>
* code editors do not recognize the string content as code, so they cannot offer syntax highlighting or more advanced language tools<br>
<br>
* the syntax does not allow nesting:<br>
<br>
        sum(i)( a[i] * sum(j)(b[i,j]*c[j]) )<br></blockquote><div><br>You could use anonymous functions, like this:<br><br>sum!( (i,a,b) { return a[i]+b[i];})(array1, array2);<br><br>Here I consider a function of an index and some arrays, but you could use functions on elements:<br>
 <br>
sum!( (a,b) { return a+b*a;})(array1, array2);<br>
<br>Editors can recognize these functions and they nest (though it&#39;s a bit heavy):<br><br>sum!( (a,b) { return a + sum!((b) { return b*b;})(array2) * a)(array1);<br><br>A possible implementation for one array can be :<br>
<br>T sum(alias op, T)(T[] array) /* also, RandomAccessRange*/<br>{<br>    T result;<br>    foreach(i, elem; array) result += op(i, array);<br>    return result;<br>}<br><br>It&#39;s quite simplified: I consider op returns a T...<br>
<br>Now, what&#39;s interesting is generalizing it somewhat : any number of inputs, and inputs can be input ranges and not only arrays:<br><br>auto sum(alias op, R...)(R ranges) if(allSatisfy!(isInputRange,R))<br>{<br>    alias staticMap!(ElementType,R) FrontType;<br>
    FrontType f;<br>    typeof(op(f)) theSum;<br>    while(!ranges[0].empty)<br>    {<br>        foreach(i, Type; FrontType) { // extracting the fronts<br>            f[i] = ranges[i].front;<br>            ranges[i].popFront;<br>
        }<br>        theSum += op(f);<br>    }<br>    return theSum;<br>}<br><br>usage:<br><br>int[] ar1 = [0,1,2,3];<br>int[] ar2 = [4,5,6,7];<br>auto s = sum!((a,b,c) {return a+b*c;})(ar1,ar2,ar1);<br>writeln(s); // 44<br>
<br>Note that we could sum ranges with any element type, as long as the .init value can be summed. float/double being initialiazed to NaN, it&#39;s a bit tricky.<br><br>We could adopt std.algorithm &#39;string functions&#39; trick, to get this syntax, which I quite like:<br>
<br>auto s = sum!&quot;a+b*c&quot;(ar1, ar2, ar3);<br><br>Maybe you could be interested by looking at some modules with these ideas at:<br><a href="http://www.dsource.org/projects/dranges">http://www.dsource.org/projects/dranges</a><br>
<br>(addendum: another generalization is of course to have two operations: the &#39;mapping&#39; operation and the &#39;reducing&#39; operation<br>like this:<br>auto sum = mapReduce!(&quot;a*b*c+1&quot;, &quot;a+b&quot;)(range1, range2, range3);<br>
The first function is applied on the elements, the second on the successive results of the first fun.<br><br>Philippe<br> <br><br><br><br></div></div>