Higher-order functions: Difference between revisions

From Rosetta Code
Content added Content deleted
(Add the way to do callback in java)
(→‎[[C]]: Added syntax highlighting)
Line 11: Line 11:




===Simple example===
Simple example, the pointer to the function to be passed as an argument is the only involved pointer.


The pointer to the function to be passed as an argument is the only involved pointer.
Definition of a function whose only parameter is a pointer to a function with no parameters and no return value:


Definition of a function whose only parameter is a pointer to a function with no parameters and no return value:
<highlightSyntax language=C>
void myFuncSimple( void (*funcParameter)(void) )
void myFuncSimple( void (*funcParameter)(void) )
{
{
Line 24: Line 26:
/* ... */
/* ... */
}
}
</highlightSyntax>


Note that you ''can't'' call the passed function by " *funcParameter() ", since that would mean "call funcParameter and than apply the * operator on the returned value".
Note that you ''can't'' call the passed function by " *funcParameter() ", since that would mean "call funcParameter and than apply the * operator on the returned value".
Line 29: Line 32:
Call:
Call:


<highlightSyntax language=C>
void funcToBePassed(void);
void funcToBePassed(void);
Line 34: Line 38:
myFuncSimple(&funcToBePassed);
myFuncSimple(&funcToBePassed);
</highlightSyntax>


===Complex example===

Complex example.


Definition of a function whose return value is a pointer to int and whose only parameter is a pointer to a function, whose (in turn) return value is a pointer to double and whose only parameter is a pointer to long.
Definition of a function whose return value is a pointer to int and whose only parameter is a pointer to a function, whose (in turn) return value is a pointer to double and whose only parameter is a pointer to long.


<highlightSyntax language=C>
int* myFuncComplex( double* (*funcParameter)(long* parameter) )
int* myFuncComplex( double* (*funcParameter)(long* parameter) )
{
{
Line 52: Line 57:
/* ... */
/* ... */
}
}
</highlightSyntax>

Call:
Call:


<highlightSyntax>
double* funcToBePassed(long* parameter);
double* funcToBePassed(long* parameter);
Line 62: Line 68:
outInt = myFuncComplex(&funcToBePassed);
outInt = myFuncComplex(&funcToBePassed);
</highlightSyntax>


===Pointer===

Finally, declaration of a pointer variable of the proper type to hold such a function as myFunc:
Finally, declaration of a pointer variable of the proper type to hold such a function as myFunc:


<highlightSyntax language=C>
int* (*funcPointer)( double* (*funcParameter)(long* parameter) );
int* (*funcPointer)( double* (*funcParameter)(long* parameter) );
Line 71: Line 79:
funcPointer = myFuncComplex;
funcPointer = myFuncComplex;
</highlightSyntax>



Of course, in a real project you shouldn't write such a convoluted code, but use some typedef instead, in order to break complexity into steps.
Of course, in a real project you shouldn't write such a convoluted code, but use some typedef instead, in order to break complexity into steps.

Revision as of 01:31, 21 February 2007

Task
Higher-order functions
You are encouraged to solve this task according to the task description, using any language you may know.

Pass a function as an argument to another function.

C

Standard: ANSI C

Compiler: GCC version 3.4.2 (mingw-special)


Simple example

The pointer to the function to be passed as an argument is the only involved pointer.

Definition of a function whose only parameter is a pointer to a function with no parameters and no return value: <highlightSyntax language=C>

 void myFuncSimple( void (*funcParameter)(void) )
 {
     /* ... */
    
     (*funcParameter)();  /* Call the passed function. */
     funcParameter();     /* Same as above with slight different syntax. */
 
     /* ... */
 }

</highlightSyntax>

Note that you can't call the passed function by " *funcParameter() ", since that would mean "call funcParameter and than apply the * operator on the returned value".

Call:

<highlightSyntax language=C>

 void funcToBePassed(void);
 
 /* ... */
 
 myFuncSimple(&funcToBePassed);

</highlightSyntax>

Complex example

Definition of a function whose return value is a pointer to int and whose only parameter is a pointer to a function, whose (in turn) return value is a pointer to double and whose only parameter is a pointer to long.

<highlightSyntax language=C>

 int* myFuncComplex( double* (*funcParameter)(long* parameter) )
 {
      long* inLong;
      double* outDouble;
 
      /* ... */
 
      outDouble = (*funcParameter)(inLong);  /* Call the passed function and store returned pointer. */
      outDouble = funcParameter(inLong);     /* Same as above with slight different syntax. */
 
      /* ... */
 }

</highlightSyntax> Call:

<highlightSyntax>

 double* funcToBePassed(long* parameter);
 
 /* ... */
 
 int* outInt;  
 
 outInt = myFuncComplex(&funcToBePassed);

</highlightSyntax>

Pointer

Finally, declaration of a pointer variable of the proper type to hold such a function as myFunc:

<highlightSyntax language=C>

 int* (*funcPointer)( double* (*funcParameter)(long* parameter) );
 
 /* ... */
 
 funcPointer = myFuncComplex;

</highlightSyntax>

Of course, in a real project you shouldn't write such a convoluted code, but use some typedef instead, in order to break complexity into steps.

C++

Function Pointer

Standard: ANSI C++

Compiler: GCC version 3.4.2 (mingw-special)

Same as C.

Template

Compiler: Visual C++ 2005

 #include <iostream>
 
 template<class Func>
 void first(Func func)
 {
   func();
 }
 
 void second()
 {
   std::cout << "second" << std::endl;
 }
 
 int main()
 {
   first(second);
   return 0;
 }

Template and Inheritance

Compiler: Visual C++ 2005

 #include <iostream>
 #include <functional>
 
 template<class Func>
 typename Func::result_type first(Func func, typename Func::argument_type arg)
 {
   return func(arg);
 }
 
 class second : public std::unary_function<int, int>
 {
 public:
   result_type operator()(argument_type arg)
   {
     return arg * arg;
   }
 };
 
 int main()
 {
   std::cout << first(second(), 2) << std::endl;
   return 0;
 }

Haskell

Interpreter: GHCi 6.6

A function is just a value that wants arguments:

func1 f = f "a string"
func2 s = "func2 called with " ++ s

main = putStrLn $ func1 func2

Or, with an anonymous function:

func f = f 1 2 

main = print $ func (\x y -> x+y)
-- output: 3

Note that func (\x y -> x+y) is equivalent to func (+). (Operators are functions too.)

Java

There is no real callback in java like in C or C++, but we can do the same as swing do for executing an event. We need to create an interface that has the method we want to call or create an that will call the method we want to call. The following example use the second way.

 public class NewClass {
    
    public NewClass() {
        first(new AnEventOrCallback() {
            public void call() {
                second();
            }
        });
    }
    
    public void first(AnEventOrCallback obj) {
        obj.call();
    }
    
    public void second() {
        System.out.println("Second");
    }
    
    public static void main(String[] args) {
        new NewClass();
    }
 }

 interface AnEventOrCallback {
    public void call();
 }

JavaScript

 function first(func) {
   return func();
 }
 
 function second() {
   return "second";
 }
 
 var result = first(second);
 result = first(function() { return "third"; });

Perl

Interpreter: Perl

Passing a pointer to a function

my $retval = first('data', \&second);

sub first ($ $){
  my $val = shift;
  my $func = shift;
  return $func->($val);
}

sub second ($){
  return(reverse(shift));
}

Passing a string to be used as a function

my $retval = first('data', 'second');

sub first ($ $){
  my $val = shift;
  my $func = shift;
  return &{$func}($val);
}

sub second ($){
  return(reverse(shift));
}


Python

Interpreter: Python 2.5

 def first(function):
     return function()
 
 def second():
     return "second"
 
 result = first(second)

or

 result = first(lambda: "second")

PHP

function first($func) {
  return $func();
}

function second() {
  return 'second';
}

$result = first('second');

Scala

def functionWithAFunctionArgument(x : int, y : int, f : (int, int) => int) = f(x,y)

Call:

functionWithAFunctionArgument(3, 5, {(x, y) => x + y}) // returns 8

Tcl

 # this procedure executes its argument:
 proc demo {function} { 
   $function 
 }
 # for example:
 demo bell