Thread overview
deducing Template Tuple Parameters
Jan 29, 2008
Im, Jihyuk
Jan 29, 2008
Im, Jihyuk
A functor-based curry
Jan 29, 2008
downs
Re: A functor-based curry: YET I HAVE PROBLEM
Jan 30, 2008
Im, Jihyuk
Jan 30, 2008
Im, Jihyuk
Jan 30, 2008
downs
thanx you!
Jan 30, 2008
Im, Jihyuk
January 29, 2008
I saw the Curry example in http://www.digitalmars.com/d/2.0/template.html

"source.1"
[code]
import std.stdio;

/* R is return type
 * A is first argument type
 * U is TypeTuple of rest of argument types
 */
R delegate(U) Curry(R, A, U...)(R delegate(A, U) dg, A arg)
{
    struct Foo
    {
	typeof(dg) dg_m;
	typeof(arg) arg_m;

	R bar(U u)
	{
	    return dg_m(arg_m, u);
	}
    }

    Foo* f = new Foo;
    f.dg_m = dg;
    f.arg_m = arg;
    return &f.bar;
}

void main()
{
    int plus(int x, int y, int z)
    {
	return x + y + z;
    }

    auto plus_two = Curry(&plus, 2);
    writefln("%d", plus_two(6, 8));	// prints 16
}
[/code]




But this example use gc instead of manual delete (or RAII), I try to make it return functor."source.2"[code]template Curry( R, A, U... ){ class Curried { public:  alias R delegate ( A, U ) Source;  Source   src_;  A     arg_; this( Source src, A arg )  {    src_ = src; arg_ = arg;   writefln( "Curried ctor" );   }  ~this()  { writefln( "Curried dtor" ); }    R opCall( U u ) { return src_( arg_, u ); } }  Curried Curry( R delegate(A, U) dg, A arg ) {  return new Curried( dg, arg ); }}void CurryTest(){ int sum( int a, int b, int c ) { return a+b+c; }  writefln( "start of curry block" );    {  scope auto p = Curry( &sum, 1 );  writefln( "%d", p( 2, 3 ) ); // == 6    } // automatically p is deleted from here writefln( "end of curry block" );}[/code]but this code emits D:\_work\java_flash\test\test.d(206): template test.Curry(R,A,U...) is not a function templateD:\_work\java_flash\test\test.d(239): template test.Curry(R,A,U...) cannot deduce template function from argument types (int delegate(int a, int b, int c),int)it cant be deduce?actually, i modifed that code to this for making compiler happy"source.3"[code]class Bind1stFunctor(R, A, U...){public: alias R delegate ( A, U ) Source; Source   src_; A     arg_; this( Source src, A arg ) {  src_ = src;  arg_ = arg;  writefln( "Bind1stFunctor ctor" );  } ~this() {        writefln( "Bind1stFunctor dtor" ); }  R opCall( U u ) {  return src_( arg_, u ); }}Bind1stFunctor!(R, A, U ) Curry1st(R, A, U...)(R delegate(A, U) dg, A arg){ return new Bind1stFunctor!(R,A,U)( dg, arg );}[/code]can you tell me what's wrong with the second source? I just wanna make it as one template scope like soruce.2---http://www.xecode.com/blog2


January 29, 2008
oops for failed text format :0


I saw the Curry example in http://www.digitalmars.com/d/2.0/template.html

"source.1"
[code]
import std.stdio;

/* R is return type
 * A is first argument type
 * U is TypeTuple of rest of argument types
 */
R delegate(U) Curry(R, A, U...)(R delegate(A, U) dg, A arg)
{
    struct Foo
    {
 typeof(dg) dg_m;
 typeof(arg) arg_m;

 R bar(U u)
 {
     return dg_m(arg_m, u);
 }
    }

    Foo* f = new Foo;
    f.dg_m = dg;
    f.arg_m = arg;
    return &f.bar;
}

void main()
{
    int plus(int x, int y, int z)
    {
 return x + y + z;
    }

    auto plus_two = Curry(&plus, 2);
    writefln("%d", plus_two(6, 8)); // prints 16
}
[/code]



But this example use gc instead of manual delete (or RAII), I try to make it
return functor.

"source.2"
[code]
template Curry( R, A, U... )
{
 class Curried
 {
 public:
  alias R delegate ( A, U ) Source;
  Source   src_;
  A     arg_;

  this( Source src, A arg )
  {
   src_ = src; arg_ = arg;
   writefln( "Curried ctor" );
  }
  ~this()
  { writefln( "Curried dtor" ); }

  R opCall( U u )
  { return src_( arg_, u ); }
 }

 Curried Curry( R delegate(A, U) dg, A arg )
 {
  return new Curried( dg, arg );
 }
}

void CurryTest()
{
 int sum( int a, int b, int c ) { return a+b+c; }

 writefln( "start of curry block" );
    {
  scope auto p = Curry( &sum, 1 );
  writefln( "%d", p( 2, 3 ) ); // == 6
    } // automatically p is deleted from here
 writefln( "end of curry block" );
}
[/code]

but this code emits

D:\_work\java_flash\test\test.d(206): template test.Curry(R,A,U...) is not a
function template
D:\_work\java_flash\test\test.d(239): template test.Curry(R,A,U...) cannot
deduce template function from argument types (int delegate(int a, int b, int
c),int)
it cant be deduce? actually, i modifed that code to this for making compiler
happy



"source.3"
[code]
class Bind1stFunctor(R, A, U...)
{
public:
 alias R delegate ( A, U ) Source;
 Source   src_;
 A     arg_;

 this( Source src, A arg )
 {
  src_ = src;
  arg_ = arg;
  writefln( "Bind1stFunctor ctor" );
 }
 ~this()
 {
  writefln( "Bind1stFunctor dtor" );
 }

 R opCall( U u )
 {
  return src_( arg_, u );
 }
}

Bind1stFunctor!(R, A, U ) Curry1st(R, A, U...)(R delegate(A, U) dg, A arg)
{
 return new Bind1stFunctor!(R,A,U)( dg, arg );
}
[/code]

can you tell me what's wrong with the second source? I just wanna make it as
one template scope like
soruce.2

---
http://www.xecode.com/blog2


January 29, 2008
[snip]

Your example doesn't work because a function template must only contain exactly a single defined symbol that has the same name as the template.

Here's a simple functor version:

> import std.stdio, std.traits;
> 

A sample function

> int add(int a, int b, int c) { return a+b+c; }
> 

The initialization of T

> template Init(T) { T Init; }
> 
> class CurryFunctor(C, P...) {
>   C callable;
>   P params;
>   this(C c, P p) {
>     callable = c;
>     foreach (id, v; p) params[id] = v;
>   }

The purpose of this is to allow a kind of automatic return type deduction. Think of this as the function body of opCall.

>   const string CODE = "
>     static if (is(typeof(callable(params, Init!(R))))) {
>       return callable(params, rest);
>     } else
>       return curry(callable, params, rest);
>   ";

Now we use our function body to determine the return type of opCall, by asking the question: "If our function were a function literal that took no parameters (declaring rest as a variable; this is okay because this function literal is never called), then what would its type be?"

>   typeof(mixin("function(){ R rest; "~CODE~" }()")) opCall(R...)(R rest) {
>     mixin(CODE);
>   }
> }
> 

A simple wrapper.

> CurryFunctor!(C, P) curry(C, P...)(C callable, P params) {
>   return new CurryFunctor!(C, P)(callable, params);
> }
> 

And examples.

> void main() {
>   writefln(curry(&add, 2, 3)(5));
>   writefln(curry(&add, 2)(3)(4));
> }

Have fun with it!

 --downs
January 30, 2008
thanx for your kind reply :)

now I get to know the problem was a function template block should has one
definition inside.
but I think if the second code works fine, I think it's useful for
listing template parameter once and use various tempalte declaration but the
parameter deduced with parameters to
template function inside.

Indeed my third code works fine for me :) your code contains string code evaluation and mixin that's yet tough to me as c++ programmer

But i found this simple code also emits duduction failure error

[code]
template Foo( R, A, U  )
{
 R delegate (U)  Foo( R delegate ( A, U ) dg, A a )
 {
  R Foo_( U u )
  { R i; return i; }
  return &Foo2_;
 }
}

void my_test()
{
 int plus_3( int a, int b, int c )
 {
  return a+b+c;
 }

 Foo( &plus_3, 10 );  // deduction failure
}
[/code]

in simpler function template works fine like:

[code]
R delegate (U) Foo2( R, A, U...)( R delegate ( A, U ) dg, A a )
{
 R Foo_( U u )
 { R i; return i; }
 return &Foo2_;
}
 Foo2( &plus_3, 10 );  // ok
[/code]

What's the problem? bug? or is there anything that i couldn't get yet?

"downs" <default_357-line@yahoo.de> wrote in message news:fnncoj$2g95$1@digitalmars.com...
> [snip]
>
> Your example doesn't work because a function template must only contain exactly a single defined symbol that has the same name as the template.
>
> Here's a simple functor version:
>
>> import std.stdio, std.traits;
>>
>
> A sample function
>
>> int add(int a, int b, int c) { return a+b+c; }
>>
>
> The initialization of T
>
>> template Init(T) { T Init; }
>>
>> class CurryFunctor(C, P...) {
>>   C callable;
>>   P params;
>>   this(C c, P p) {
>>     callable = c;
>>     foreach (id, v; p) params[id] = v;
>>   }
>
> The purpose of this is to allow a kind of automatic return type deduction. Think of this as the function body of opCall.
>
>>   const string CODE = "
>>     static if (is(typeof(callable(params, Init!(R))))) {
>>       return callable(params, rest);
>>     } else
>>       return curry(callable, params, rest);
>>   ";
>
> Now we use our function body to determine the return type of opCall, by
> asking the question:
> "If our function were a function literal that took no parameters
> (declaring rest as a variable;
> this is okay because this function literal is never called), then what
> would its type be?"
>
>>   typeof(mixin("function(){ R rest; "~CODE~" }()")) opCall(R...)(R rest)
>> {
>>     mixin(CODE);
>>   }
>> }
>>
>
> A simple wrapper.
>
>> CurryFunctor!(C, P) curry(C, P...)(C callable, P params) {
>>   return new CurryFunctor!(C, P)(callable, params);
>> }
>>
>
> And examples.
>
>> void main() {
>>   writefln(curry(&add, 2, 3)(5));
>>   writefln(curry(&add, 2)(3)(4));
>> }
>
> Have fun with it!
>
> --downs


January 30, 2008
there're some errata in code but maybe anybody know what's the point

below code is the right one

[code]
template Foo( R, A, U  )
{
 R delegate (U)  Foo( R delegate ( A, U ) dg, A a )
 {
  R Foo_( U u )
  { R i; return i; }
  return &Foo_;
 }
}
R delegate (U) Foo2( R, A, U...)( R delegate ( A, U ) dg, A a )
{
 R Foo2_( U u )
 { R i; return i; }
 return &Foo2_;
}
[/code]

-- 
Im, Jihyuk aka gshock
http://www.xecode.com/blog2


"Im, Jihyuk" <icedac@g-nospam-mail.com> wrote in message news:fnov9q$sq1$1@digitalmars.com...
> thanx for your kind reply :)
>
> now I get to know the problem was a function template block should has one
> definition inside.
> but I think if the second code works fine, I think it's useful for
> listing template parameter once and use various tempalte declaration but
> the parameter deduced with parameters to
> template function inside.
>
> Indeed my third code works fine for me :) your code contains string code evaluation and mixin that's yet tough to me as c++ programmer
>
> But i found this simple code also emits duduction failure error
>
> [code]
> template Foo( R, A, U  )
> {
> R delegate (U)  Foo( R delegate ( A, U ) dg, A a )
> {
>  R Foo_( U u )
>  { R i; return i; }
>  return &Foo2_;
> }
> }
>
> void my_test()
> {
> int plus_3( int a, int b, int c )
> {
>  return a+b+c;
> }
>
> Foo( &plus_3, 10 );  // deduction failure
> }
> [/code]
>
> in simpler function template works fine like:
>
> [code]
> R delegate (U) Foo2( R, A, U...)( R delegate ( A, U ) dg, A a )
> {
> R Foo_( U u )
> { R i; return i; }
> return &Foo2_;
> }
> Foo2( &plus_3, 10 );  // ok
> [/code]
>
> What's the problem? bug? or is there anything that i couldn't get yet?
>
> "downs" <default_357-line@yahoo.de> wrote in message news:fnncoj$2g95$1@digitalmars.com...
>> [snip]
>>
>> Your example doesn't work because a function template must only contain exactly a single defined symbol that has the same name as the template.
>>
>> Here's a simple functor version:
>>
>>> import std.stdio, std.traits;
>>>
>>
>> A sample function
>>
>>> int add(int a, int b, int c) { return a+b+c; }
>>>
>>
>> The initialization of T
>>
>>> template Init(T) { T Init; }
>>>
>>> class CurryFunctor(C, P...) {
>>>   C callable;
>>>   P params;
>>>   this(C c, P p) {
>>>     callable = c;
>>>     foreach (id, v; p) params[id] = v;
>>>   }
>>
>> The purpose of this is to allow a kind of automatic return type
>> deduction.
>> Think of this as the function body of opCall.
>>
>>>   const string CODE = "
>>>     static if (is(typeof(callable(params, Init!(R))))) {
>>>       return callable(params, rest);
>>>     } else
>>>       return curry(callable, params, rest);
>>>   ";
>>
>> Now we use our function body to determine the return type of opCall, by
>> asking the question:
>> "If our function were a function literal that took no parameters
>> (declaring rest as a variable;
>> this is okay because this function literal is never called), then what
>> would its type be?"
>>
>>>   typeof(mixin("function(){ R rest; "~CODE~" }()")) opCall(R...)(R rest)
>>> {
>>>     mixin(CODE);
>>>   }
>>> }
>>>
>>
>> A simple wrapper.
>>
>>> CurryFunctor!(C, P) curry(C, P...)(C callable, P params) {
>>>   return new CurryFunctor!(C, P)(callable, params);
>>> }
>>>
>>
>> And examples.
>>
>>> void main() {
>>>   writefln(curry(&add, 2, 3)(5));
>>>   writefln(curry(&add, 2)(3)(4));
>>> }
>>
>> Have fun with it!
>>
>> --downs
>
> 


January 30, 2008
Im, Jihyuk wrote:
> thanx for your kind reply :)
> 
> now I get to know the problem was a function template block should has one
> definition inside.
> but I think if the second code works fine, I think it's useful for
> listing template parameter once and use various tempalte declaration but the
> parameter deduced with parameters to
> template function inside.
> 
> Indeed my third code works fine for me :) your code contains string code evaluation and mixin that's yet tough to me as c++ programmer
> 
> But i found this simple code also emits duduction failure error
> 
> [code]
> template Foo( R, A, U  )

Here's your problem. Since A and U are each single template parameters, they can each assume precisely _one_ type.
However, if you'll look, &plus_3 is a void delegate(int, int, int).
This means that A'd have to be int, U also, and ... then we still got an int left over that doesn't fit the template description.
U... fixes this because it's a tuple and tuples can assume an arbitrary number of types.

> {
>  R delegate (U)  Foo( R delegate ( A, U ) dg, A a )
>  {
>   R Foo_( U u )
>   { R i; return i; }
>   return &Foo2_;
>  }
> }
> 
> void my_test()
> {
>  int plus_3( int a, int b, int c )
>  {
>   return a+b+c;
>  }
> 
>  Foo( &plus_3, 10 );  // deduction failure
> }
> [/code]
> 

 --downs
January 30, 2008
>> template Foo( R, A, U  )
>
> Here's your problem. Since A and U are each single template parameters,
> they can each assume precisely _one_ type.
> However, if you'll look, &plus_3 is a void delegate(int, int, int).
> This means that A'd have to be int, U also, and ... then we still got an
> int left over that doesn't fit the template description.
> U... fixes this because it's a tuple and tuples can assume an arbitrary
> number of types.
>
ooops! that was my errata too! my little programming experience in D led
that err :)
maybe my brain sometimes let me remove '...' in template arguments.
anyway thank you!

"downs" <default_357-line@yahoo.de> wrote in message news:fnphi5$2eap$1@digitalmars.com...
> Im, Jihyuk wrote:
>> thanx for your kind reply :)
>>
>> now I get to know the problem was a function template block should has
>> one
>> definition inside.
>> but I think if the second code works fine, I think it's useful for
>> listing template parameter once and use various tempalte declaration but
>> the
>> parameter deduced with parameters to
>> template function inside.
>>
>> Indeed my third code works fine for me :) your code contains string code evaluation and mixin that's yet tough to me as c++ programmer
>>
>> But i found this simple code also emits duduction failure error
>>
>> [code]
>> template Foo( R, A, U  )
>
> Here's your problem. Since A and U are each single template parameters,
> they can each assume precisely _one_ type.
> However, if you'll look, &plus_3 is a void delegate(int, int, int).
> This means that A'd have to be int, U also, and ... then we still got an
> int left over that doesn't fit the template description.
> U... fixes this because it's a tuple and tuples can assume an arbitrary
> number of types.
>
>> {
>>  R delegate (U)  Foo( R delegate ( A, U ) dg, A a )
>>  {
>>   R Foo_( U u )
>>   { R i; return i; }
>>   return &Foo2_;
>>  }
>> }
>>
>> void my_test()
>> {
>>  int plus_3( int a, int b, int c )
>>  {
>>   return a+b+c;
>>  }
>>
>>  Foo( &plus_3, 10 );  // deduction failure
>> }
>> [/code]
>>
>
> --downs