www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Passing function as values and returning functions

reply "Xan" <xancorreu gmail.com> writes:
Hi,

Following the thread of Higher-order functions, how can I do to 
pass a function as a parameter and return a function. That is a 
something like:

import std.functional, std.stdio;

int f (int a) {
    return 2*a;
}

int delegate (int) g(int function(int a) p) {
    return p;
}


void main() {
    writeln(g(f)(1));
}


but it gives me:

$ gdmd-4.6 functions.d
functions.d:8: Error: cannot implicitly convert expression (p) of 
type int function(int a) to int delegate(int)
functions.d:13: Error: function functions.f (int a) is not 
callable using argument types ()
functions.d:13: Error: expected 1 function arguments, not 0
functions.d:13: Error: function functions.g (int function(int a) 
p) is not callable using argument types (int)
functions.d:13: Error: cannot implicitly convert expression (f()) 
of type int to int function(int a)


Thanks,
Xan.
Apr 11 2012
parent reply Jacob Carlborg <doob me.com> writes:
On 2012-04-11 13:10, Xan wrote:
 Hi,

 Following the thread of Higher-order functions, how can I do to pass a
 function as a parameter and return a function. That is a something like:

 import std.functional, std.stdio;

 int f (int a) {
 return 2*a;
 }

 int delegate (int) g(int function(int a) p) {
 return p;
 }


 void main() {
 writeln(g(f)(1));
 }


 but it gives me:

 $ gdmd-4.6 functions.d
 functions.d:8: Error: cannot implicitly convert expression (p) of type
 int function(int a) to int delegate(int)
 functions.d:13: Error: function functions.f (int a) is not callable
 using argument types ()
 functions.d:13: Error: expected 1 function arguments, not 0
 functions.d:13: Error: function functions.g (int function(int a) p) is
 not callable using argument types (int)
 functions.d:13: Error: cannot implicitly convert expression (f()) of
 type int to int function(int a)
Use "delegate" or "function" both for the argument type and return type. -- /Jacob Carlborg
Apr 11 2012
parent reply "Xan" <xancorreu gmail.com> writes:
On Wednesday, 11 April 2012 at 11:59:14 UTC, Jacob Carlborg wrote:
 On 2012-04-11 13:10, Xan wrote:
 Hi,

 Following the thread of Higher-order functions, how can I do 
 to pass a
 function as a parameter and return a function. That is a 
 something like:

 import std.functional, std.stdio;

 int f (int a) {
 return 2*a;
 }

 int delegate (int) g(int function(int a) p) {
 return p;
 }


 void main() {
 writeln(g(f)(1));
 }


 but it gives me:

 $ gdmd-4.6 functions.d
 functions.d:8: Error: cannot implicitly convert expression (p) 
 of type
 int function(int a) to int delegate(int)
 functions.d:13: Error: function functions.f (int a) is not 
 callable
 using argument types ()
 functions.d:13: Error: expected 1 function arguments, not 0
 functions.d:13: Error: function functions.g (int function(int 
 a) p) is
 not callable using argument types (int)
 functions.d:13: Error: cannot implicitly convert expression 
 (f()) of
 type int to int function(int a)
Use "delegate" or "function" both for the argument type and return type.
How to do that?
Apr 11 2012
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 11 Apr 2012 08:08:44 -0400, Xan <xancorreu gmail.com> wrote:

 On Wednesday, 11 April 2012 at 11:59:14 UTC, Jacob Carlborg wrote:
 Use "delegate" or "function" both for the argument type and return type.
How to do that?
int function(int) g(int function(int a) p) { return p; } Should do the trick. delegates are not implicitly convertible to/from function pointers. You can, however, explicitly convert a function to a delegate. But this should be done only when there is a requirement to use delegates. However, use std.functional.toDelegate if you are interested. -Steve
Apr 11 2012
parent reply "Xan" <xancorreu gmail.com> writes:
On Wednesday, 11 April 2012 at 12:19:06 UTC, Steven Schveighoffer 
wrote:
 On Wed, 11 Apr 2012 08:08:44 -0400, Xan <xancorreu gmail.com> 
 wrote:

 On Wednesday, 11 April 2012 at 11:59:14 UTC, Jacob Carlborg 
 wrote:
 Use "delegate" or "function" both for the argument type and 
 return type.
How to do that?
int function(int) g(int function(int a) p) { return p; } Should do the trick. delegates are not implicitly convertible to/from function pointers. You can, however, explicitly convert a function to a delegate. But this should be done only when there is a requirement to use delegates. However, use std.functional.toDelegate if you are interested. -Steve
Thanks, Steve, but another problem: $ gdmd-4.6 functions.d functions.d:13: Error: function functions.f (int a) is not callable using argument types () functions.d:13: Error: expected 1 function arguments, not 0 functions.d:13: Error: function functions.g (int function(int) p) is not callable using argument types (int) functions.d:13: Error: cannot implicitly convert expression (f()) of type int to int function(int) import std.functional, std.stdio; int f (int a) { |___return 2*a; } int function(int) g(int function(int a) p) { |___return p; } void main() { |___writeln(g(f)(1)); } I want to g return f and then f evaluate 1.
Apr 11 2012
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 11 Apr 2012 08:53:00 -0400, Xan <xancorreu gmail.com> wrote:

 Thanks, Steve, but another problem:
[snip]
 void main() {
 |___writeln(g(f)(1));
 }
writeln(g(&f)(1)); Unlike C, you *must* take the address of a function symbol to get a function pointer. -Steve
Apr 11 2012
parent reply "Xan" <xancorreu gmail.com> writes:
On Wednesday, 11 April 2012 at 13:04:01 UTC, Steven Schveighoffer 
wrote:
 On Wed, 11 Apr 2012 08:53:00 -0400, Xan <xancorreu gmail.com> 
 wrote:

 Thanks, Steve, but another problem:
[snip]
 void main() {
 |___writeln(g(f)(1));
 }
writeln(g(&f)(1)); Unlike C, you *must* take the address of a function symbol to get a function pointer. -Steve
Yes, it works, finally. Thanks, Steve. Xan.
Apr 11 2012
next sibling parent reply James Miller <james aatch.net> writes:
* Xan <xancorreu gmail.com> [2012-04-11 20:28:38 +0200]:

 On Wednesday, 11 April 2012 at 13:04:01 UTC, Steven Schveighoffer
 wrote:
On Wed, 11 Apr 2012 08:53:00 -0400, Xan <xancorreu gmail.com>
wrote:
[snip]
writeln(g(&f)(1));

Unlike C, you *must* take the address of a function symbol to get
a function pointer.

-Steve
Yes, it works, finally. Thanks, Steve. Xan.
Glad you got help Xan, but for future reference can you please keep questions to D.learn? It is somewhat frustrating to see the question "How do I do that?" on this list, since it is for discussion, and high-level questions, not for people that are learning D. (High level questions being along the lines of "What changes need to be made in dmd to support the new AA implementation?") -- James Miller
Apr 12 2012
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 12 Apr 2012 10:49:03 -0400, James Miller <james aatch.net> wrote:

 Glad you got help Xan, but for future reference can you please keep
 questions to D.learn? It is somewhat frustrating to see the question
 "How do I do that?" on this list, since it is for discussion, and
 high-level questions, not for people that are learning D.
Um... this is d.learn... -Steve
Apr 12 2012
prev sibling parent James Miller <james aatch.net> writes:
* James Miller <james aatch.net> [2012-04-13 02:49:03 +1200]:

 Glad you got help Xan, but for future reference can you please keep
 questions to D.learn? It is somewhat frustrating to see the question
 "How do I do that?" on this list, since it is for discussion, and
 high-level questions, not for people that are learning D.
 
 (High level questions being along the lines of "What changes need to be
 made in dmd to support the new AA implementation?")
 
And now I look like an asshole because I wasn't paying attention to the mailbox I was in. Ignore me, I'm an idiot... -- James Miller
Apr 12 2012