Jump to content

Higher-order functions

From Rosetta Code
Revision as of 07:13, 1 February 2007 by rosettacode>Sgeier (fixing capitalization TCL -> Tcl)
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:

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

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:

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


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.

 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. */
 
      /* ... */
 }

Call:

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


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

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


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: Microsoft 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: Microsoft 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.)

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');

Tcl

 # this procedure executes its argument:
 proc demo {function} { 
   $function 
 }
 # for example:
 demo bell
Cookies help us deliver our services. By using our services, you agree to our use of cookies.