Timon is, of course, right. I got a bit confused when trying to simplify in a hurry. What I meant was actually something like this:<div><br><div>ops.d:</div><div><div>import std.stdio;</div><div><br></div><div>int sum( T )( T mat ){</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>writeln("ops.sum");</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// return reduce!"a+b"( 0, mat );</div><div>

<span class="Apple-tab-span" style="white-space:pre"> </span>return 1;</div><div>}</div><div><br></div><div>int numelems( T )( T mat ) {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// return mat.rows * mat.columns;</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>return 1;</div><div>}</div><div><br></div><div>int mean( T )( T mat ) {</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>return sum( mat ) / numelems( mat );</div>

<div>}</div><div><br></div></div><div>diagonal.d:</div><div><div>import ops;</div><div>import std.stdio;</div><div><br></div><div>struct DiagonalMatrix {</div><div><span class="Apple-tab-span" style="white-space:pre">   </span></div>

<div>}</div><div><br></div><div>int sum( T : DiagonalMatrix )( T mat ) {</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>writeln( "diagonal.sum" );</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>// return reduce!"a+b"( 0, mat.diagonal() );</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>return 1;</div><div>} </div></div><div><br></div><div>main.d:</div><div>import ops;</div><div>import diagonal;</div><div><br></div><div><div>void main() {</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>DiagonalMatrix mat;</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>sum( mat );   // this will not compile, but if removed mean</div>

<div><span class="Apple-tab-span" style="white-space:pre">      </span>mean( mat ); // will use ops.sum, not diagonal.sum anyway</div></div><div>}</div><div><br></div><div>The first problem could, in theory, be fixed using a member flag, something like enum specializedSum = true; and ops.sum could be redefined as: int sum( T )( T mat ) if( !T.specializedSum ) {}. But in this case mean() would still try to use  ops.sum which will fail. All of this can be easily fixed by providing member functions, and having the free functions call the member ones when they exist.</div>

<div><div><br></div><div>---</div>Cristi Cobzarenco<div>BSc in Artificial Intelligence and Computer Science</div><div>University of Edinburgh<br>Profile: <a href="http://www.google.com/profiles/cristi.cobzarenco" target="_blank">http://www.google.com/profiles/cristi.cobzarenco</a></div>

<br>
<br><br><div class="gmail_quote">On 10 April 2012 10:35, Timon Gehr <span dir="ltr"><<a href="mailto:timon.gehr@gmx.ch">timon.gehr@gmx.ch</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im">On 04/10/2012 03:24 AM, Cristi Cobzarenco wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thanks for the suggestions!<br>
<br>
I don't think UFCS would help us. Our problem is that we can't do this:<br>
triangular.d:<br>
   struct TriangularMatrix {<br>
<br>
   }<br>
<br>
   void sum( T )( T x ) if( is( T : TriangularMatrix ) ) {<br>
<br>
   }<br>
<br>
diagonal.d:<br>
   struct DiagonalMatrix {<br>
<br>
   }<br>
<br>
   void sum( T )( T x ) if( is( T : DiagonalMatrix ) ) {<br>
   }<br>
<br>
main.d:<br>
import diagonal;<br>
import triangular;<br>
<br>
void bar() {<br>
    TriangularMatrix a;<br>
    Diagonal b;<br>
    sum( a );  // this does not compile because sum() is ambiguous<br>
    sum( b );  // nor does this<br>
}<br>
</blockquote>
<br></div>
There are no ambiguities in that example, and if ambiguities occur, they can always be fixed manually.<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
<br>
This, AFAIK, is deliberate to avoid name hijacking - ADL in C++ had its<br>
share of criticism. I doubt we will ever get this behaviour in D and<br>
that is perhaps a good thing. I may have misunderstood UFCS though - or<br>
what you meant by making non-member function calls look nicer - please<br>
correct me if that's the case.<br>
<br>
Don't worry about long names, t() is already the way transposition is<br>
defined SciD. Moreover, it's a property so you can actually do "a.t * a"<br>
- convenience galore. I'm also considering of creating a submodule like<br>
std.linalg.short which defines aliases with short names for types and<br>
free functions - this will allow particularly numerics-heavy functions<br>
to be written more compactly. I'm not entirely sure it would be a good<br>
idea though as it may sacrifice readability where it's most needed.<br>
<br></div><div class="im">
---<br>
Cristi Cobzarenco<br>
BSc in Artificial Intelligence and Computer Science<br>
University of Edinburgh<br>
Profile: <a href="http://www.google.com/profiles/cristi.cobzarenco" target="_blank">http://www.google.com/<u></u>profiles/cristi.cobzarenco</a><br>
<br>
</div></blockquote>
<br>
If you change 'Diagonal' to 'DiagonalMatrix', this compiles fine.<br>
<br>
</blockquote></div><br></div></div>