Unfortunately, my proposal was not picked up this year. I might try to work on these ideas this summer anyway so I would still be very much interested in ideas and feedback, but I will probably have much less time if I'll be working somewhere else.
--- Cristi Cobzarenco BSc in Artificial Intelligence and Computer Science University of Edinburgh Profile: http://www.google.com/profiles/cristi.cobzarenco On 10 April 2012 12:31, Cristi Cobzarenco <[email protected]>wrote: > 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: > > ops.d: > import std.stdio; > > int sum( T )( T mat ){ > writeln("ops.sum"); > // return reduce!"a+b"( 0, mat ); > return 1; > } > > int numelems( T )( T mat ) { > // return mat.rows * mat.columns; > return 1; > } > > int mean( T )( T mat ) { > return sum( mat ) / numelems( mat ); > } > > diagonal.d: > import ops; > import std.stdio; > > struct DiagonalMatrix { > } > > int sum( T : DiagonalMatrix )( T mat ) { > writeln( "diagonal.sum" ); > // return reduce!"a+b"( 0, mat.diagonal() ); > return 1; > } > > main.d: > import ops; > import diagonal; > > void main() { > DiagonalMatrix mat; > sum( mat ); // this will not compile, but if removed mean > mean( mat ); // will use ops.sum, not diagonal.sum anyway > } > > 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. > > --- > Cristi Cobzarenco > BSc in Artificial Intelligence and Computer Science > University of Edinburgh > Profile: http://www.google.com/profiles/cristi.cobzarenco > > > > On 10 April 2012 10:35, Timon Gehr <[email protected]> wrote: > >> On 04/10/2012 03:24 AM, Cristi Cobzarenco wrote: >> >>> Thanks for the suggestions! >>> >>> I don't think UFCS would help us. Our problem is that we can't do this: >>> triangular.d: >>> struct TriangularMatrix { >>> >>> } >>> >>> void sum( T )( T x ) if( is( T : TriangularMatrix ) ) { >>> >>> } >>> >>> diagonal.d: >>> struct DiagonalMatrix { >>> >>> } >>> >>> void sum( T )( T x ) if( is( T : DiagonalMatrix ) ) { >>> } >>> >>> main.d: >>> import diagonal; >>> import triangular; >>> >>> void bar() { >>> TriangularMatrix a; >>> Diagonal b; >>> sum( a ); // this does not compile because sum() is ambiguous >>> sum( b ); // nor does this >>> } >>> >> >> There are no ambiguities in that example, and if ambiguities occur, they >> can always be fixed manually. >> >> >>> This, AFAIK, is deliberate to avoid name hijacking - ADL in C++ had its >>> share of criticism. I doubt we will ever get this behaviour in D and >>> that is perhaps a good thing. I may have misunderstood UFCS though - or >>> what you meant by making non-member function calls look nicer - please >>> correct me if that's the case. >>> >>> Don't worry about long names, t() is already the way transposition is >>> defined SciD. Moreover, it's a property so you can actually do "a.t * a" >>> - convenience galore. I'm also considering of creating a submodule like >>> std.linalg.short which defines aliases with short names for types and >>> free functions - this will allow particularly numerics-heavy functions >>> to be written more compactly. I'm not entirely sure it would be a good >>> idea though as it may sacrifice readability where it's most needed. >>> >>> --- >>> Cristi Cobzarenco >>> BSc in Artificial Intelligence and Computer Science >>> University of Edinburgh >>> Profile: >>> http://www.google.com/**profiles/cristi.cobzarenco<http://www.google.com/profiles/cristi.cobzarenco> >>> >>> >> If you change 'Diagonal' to 'DiagonalMatrix', this compiles fine. >> >> >
