Higher-order functions

From Rosetta Code
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.

Ada

with Ada.Text_Io; use Ada.Text_Io;

procedure Subprogram_As_Argument is
   type Proc_Access is access procedure;
   
   procedure Second is
   begin
      Put_Line("Second Procedure");
   end Second;
  
   procedure First(Proc : Proc_Access) is
   begin
      Proc.all;
   end First;
begin
   First(Second'Access);
end Subprogram_As_Argument;

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

Pointer

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: 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"; });

Pascal

Standard Pascal (will not work with Turbo Pascal):

program example(output);

function first(function f(x: real): real): real;
 begin
  first := f(1.0) + 2.0;
 end;

function second(x: real): real;
 begin
  second = x/2.0;
 end;

begin
 writeln(first(second));
end.

Turbo Pascal (will not work with Standard Pascal):

program example;

type
 FnType = function(x: real): real;

function first(f: FnType): real;
 begin
  first := f(1.0) + 2.0;
 end;

function second(x: real): real;
 begin
  second := x/2.0;
 end;

begin
 writeln(first(second));
end.

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