www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opDispatch and template parameters

reply "Guillaume B." <guillaume.b.spam spam.ca> writes:
Hi,

 Is this usage of opDispatch supposed to work:

====
module test.d;

import std.stdio;

struct DispatchTest {
    void opDispatch(string name, string otherName)() {
        writeln(name, ":", otherName);
    }
}

void main() {
    DispatchTest t;
    //t.testName!("testOtherName")();
    t.opDispatch!("testName", "testOtherName")();
}
====

 This compiles fine but if I remove the commented line, dmd (v2.048) tells 
me:

test.d(13): Error: template instance opDispatch!("testName") does not match 
template declaration opDispatch(string name,string otherName)

The error seems OK for a "normal" function, but for opDispatch, it seems 
limiting to me. Is this a bug?

Here's an other, similar, test:

====
module test.d;

import std.stdio;

struct DispatchTest {
    void opDispatch(string name, T)(T t) {
        writeln(name, ":", T.stringof);
    }
}

void main() {
    DispatchTest t;
    //t.testName!(DispatchTest)(t);
    t.testName(t);
}
====

Which gives, when uncommenting:

test.d(13): Error: template instance opDispatch!("testName") does not match 
template declaration opDispatch(string name,T)

So bug or not?

 Guillaume
Sep 08 2010
next sibling parent "Guillaume B." <guillaume.b.spam spam.ca> writes:
 Oh, well: http://d.puremagic.com/issues/show_bug.cgi?id=4856

 Guillaume

Guillaume B. wrote:

 Hi,
 
  Is this usage of opDispatch supposed to work:
 
 ====
 module test.d;
 
 import std.stdio;
 
 struct DispatchTest {
     void opDispatch(string name, string otherName)() {
         writeln(name, ":", otherName);
     }
 }
 
 void main() {
     DispatchTest t;
     //t.testName!("testOtherName")();
     t.opDispatch!("testName", "testOtherName")();
 }
 ====
 
  This compiles fine but if I remove the commented line, dmd (v2.048) tells
 me:
 
 test.d(13): Error: template instance opDispatch!("testName") does not
 match template declaration opDispatch(string name,string otherName)
 
 The error seems OK for a "normal" function, but for opDispatch, it seems
 limiting to me. Is this a bug?
 
 Here's an other, similar, test:
 
 ====
 module test.d;
 
 import std.stdio;
 
 struct DispatchTest {
     void opDispatch(string name, T)(T t) {
         writeln(name, ":", T.stringof);
     }
 }
 
 void main() {
     DispatchTest t;
     //t.testName!(DispatchTest)(t);
     t.testName(t);
 }
 ====
 
 Which gives, when uncommenting:
 
 test.d(13): Error: template instance opDispatch!("testName") does not
 match template declaration opDispatch(string name,T)
 
 So bug or not?
 
  Guillaume
Sep 13 2010
prev sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Guillaume B. <guillaume.b.spam spam.ca> wrote:

 Hi,

  Is this usage of opDispatch supposed to work:

 ====
 module test.d;

 import std.stdio;

 struct DispatchTest {
     void opDispatch(string name, string otherName)() {
         writeln(name, ":", otherName);
     }
 }

 void main() {
     DispatchTest t;
     //t.testName!("testOtherName")();
     t.opDispatch!("testName", "testOtherName")();
 }
 ====

  This compiles fine but if I remove the commented line, dmd (v2.048)  
 tells
 me:

 test.d(13): Error: template instance opDispatch!("testName") does not  
 match
 template declaration opDispatch(string name,string otherName)

 The error seems OK for a "normal" function, but for opDispatch, it seems
 limiting to me. Is this a bug?
Sorry for not noticing this post before. This is not a bug. The correct way to do what you want is this: module foo; import std.stdio; struct test { template opDispatch( string name ) { void opDispatch( string other )( ) { writeln( name, ", ", other ); } } } void main( ) { test t; t.foo!( "Hey!" )( ); } -- Simen
Sep 13 2010
parent reply "Guillaume B." <guillaume.b.spam spam.ca> writes:
Simen kjaeraas wrote:

 Guillaume B. <guillaume.b.spam spam.ca> wrote:
 
 Hi,

  Is this usage of opDispatch supposed to work:

 ====
 module test.d;

 import std.stdio;

 struct DispatchTest {
     void opDispatch(string name, string otherName)() {
         writeln(name, ":", otherName);
     }
 }

 void main() {
     DispatchTest t;
     //t.testName!("testOtherName")();
     t.opDispatch!("testName", "testOtherName")();
 }
 ====
 [...]
Sorry for not noticing this post before. This is not a bug. The correct way to do what you want is this: module foo; import std.stdio; struct test { template opDispatch( string name ) { void opDispatch( string other )( ) { writeln( name, ", ", other ); } } } void main( ) { test t; t.foo!( "Hey!" )( ); }
Wow! That's a nice trick! Seems like I'll have to be carefull when defining opDispatch! Guillaume
Sep 14 2010
parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Guillaume B. <guillaume.b.spam spam.ca> wrote:

 struct test {
      template opDispatch( string name ) {
          void opDispatch( string other )( ) {
              writeln( name, ", ", other );
          }
      }
 }
  Wow! That's a nice trick! Seems like I'll have to be carefull when  
 defining
 opDispatch!
It's the way the language works. Just like D does not support automatic currying of functions, like this: void foo( int n, string s ) {} auto bar = foo( 4 ); assert( is( typeof( bar ) == void function ( string ) ) ); Neither does it support automatic currying for templates. Hence, all arguments must be passed in one go. The above is in a way doable in D, but only by jumping through hoops: auto foo( int n ) { return ( string s ) {}; } foo( 4 )( "my string!" ); The same is to an extent doable with templates, limited by magical. This way of programming (unary functions that return unary functions [that...]) reminds one of the Lambda calculus[2]. [1]: http://d.puremagic.com/issues/show_bug.cgi?id=242 [2]: http://en.wikipedia.org/wiki/Lambda_calculus -- Simen
Sep 14 2010
parent bearophile <bearophileHUGS lycos.com> writes:
Simen kjaeraas:

 It's the way the language works. Just like D does not support
 automatic currying of functions, like this:
 
 void foo( int n, string s ) {}
 auto bar = foo( 4 );
 assert( is( typeof( bar ) == void function ( string ) ) );
 
 Neither does it support automatic currying for templates. Hence,
 all arguments must be passed in one go. The above is in a way
 doable in D, but only by jumping through hoops:
 
 auto foo( int n ) {
      return ( string s ) {};
 }
 foo( 4 )( "my string!" );
See also std.functional.curry (never used it). Bye, bearophile
Sep 14 2010