Higher-order functions

From Rosetta Code
Revision as of 12:14, 13 January 2011 by rosettacode>Presidentbeef (Add Brat example)
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.f. First-class functions

ActionScript

<lang actionscript>package {

   public class MyClass {
       public function first(func:Function):String {
           return func.call();
       }
    
       public function second():String {
           return "second";
       }
       
       public static function main():void {
           var result:String = first(second);
           trace(result);
           result = first(function() { return "third"; });
           trace(result);
       }
   }

}</lang>

Ada

Simple Example

<lang 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;</lang>

Complex Example

<lang ada>with Ada.Text_Io; use Ada.Text_Io;

procedure Subprogram_As_Argument_2 is

  -- Definition of an access to long_float
  type Lf_Access is access Long_Float;
  
  -- Definition of a function returning Lf_Access taking an
  -- integer as a parameter
  function Func_To_Be_Passed(Item : Integer) return Lf_Access is
     Result : Lf_Access := new Long_Float;
  begin
     Result.All := 3.14159 * Long_Float(Item);
     return Result;
  end Func_To_Be_Passed;
  
  -- Definition of an access to function type matching the function
  -- signature above
  type Func_Access is access function(Item : Integer) return Lf_Access;
  
  -- Definition of an integer access type
  type Int_Access is access Integer;
  
  -- Define a function taking an instance of Func_Access as its
  -- parameter and returning an integer access type
  function Complex_Func(Item : Func_Access; Parm2 : Integer) return Int_Access is
     Result : Int_Access := new Integer;
  begin
     Result.All := Integer(Item(Parm2).all / 3.14149);
     return Result;
  end Complex_Func;
  
  -- Declare an access variable to hold the access to the function
  F_Ptr : Func_Access := Func_To_Be_Passed'access;
  
  -- Declare an access to integer variable to hold the result
  Int_Ptr : Int_Access;

begin

  -- Call the function using the access variable
  Int_Ptr := Complex_Func(F_Ptr, 3);
  Put_Line(Integer'Image(Int_Ptr.All));

end Subprogram_As_Argument_2;</lang>

ALGOL 68

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny

<lang algol68>PROC first = (PROC(LONG REAL)LONG REAL f) LONG REAL: (

 f(1) + 2

);

PROC second = (LONG REAL x)LONG REAL: (

 x/2

);

main: (

 printf(($xg(5,2)l$,first(second)))

)</lang> Output:

+2.50

AmigaE

The {} takes the pointer to an object (code/functions, variables and so on); Amiga E does not distinguish nor check anything, so it is up to the programmer to use the pointer properly. For this reason, a warning is always raised when a variable (func, holding a pointer to a real function in our case) is used like a function. <lang amigae>PROC compute(func, val)

 DEF s[10] : STRING
 WriteF('\s\n', RealF(s,func(val),4))

ENDPROC

PROC sin_wrap(val) IS Fsin(val) PROC cos_wrap(val) IS Fcos(val)

PROC main()

 compute({sin_wrap}, 0.0)
 compute({cos_wrap}, 3.1415)

ENDPROC</lang>

AutoHotkey

<lang AutoHotkey> f(x) { return x } g(x, y) { msgbox %x% msgbox %y% } g(f("RC Function as an Argument AHK implementation"), "Non-function argument") return </lang>

==[[:Category:{{{1}}}|{{{1}}}]] [[Category:{{{1}}}]] Property "Implemented in language" (as page type) with input value "{{{1}}}" contains invalid characters or is incomplete and therefore can cause unexpected results during a query or annotation process.

 end

in

 {Show {Twice Sqrt 81.0}}  %% prints 3.0</lang>

PARI/GP

Works with: PARI/GP version 2.4.2 and above

<lang>secant_root(ff,a,b)={ e = eps() * 2; aval=ff(a); bval=ff(b); while (abs(bval) > e, oldb = b; b = b - (b - a)/(bval - aval) * bval; aval = bval; bval = ff(b); a = oldb ); b }; addhelp(secant_root, "secant_root(ff,a,b): Finds a root of ff between a and b using the secant method.");

eps()={ precision(2. >> (32 * ceil(default(realprecision) * 38539962 / 371253907)), 9) }; addhelp(eps,"Returns machine epsilon for the current precision.");</lang>

Pascal

Standard Pascal (will not work with Turbo Pascal): <lang 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.</lang>

Turbo Pascal (will not work with Standard Pascal):

<lang 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.</lang>

Perl

<lang perl>sub another {

   # take a function and a value
   my $func = shift;
   my $val  = shift;
   # call the function with the value as argument
   return $func->($val);

};

sub reverser {

   return scalar reverse shift;

};

  1. pass named coderef

print another \&reverser, 'data';

  1. pass anonymous coderef

print another sub {return scalar reverse shift}, 'data';

  1. if all you have is a string and you want to act on that,
  2. set up a dispatch table

my %dispatch = (

   square => sub {return shift() ** 2},
   cube   => sub {return shift() ** 3},
   rev    => \&reverser,

);

print another $dispatch{$_}, 123 for qw(square cube rev);</lang>

<lang perl>sub apply (&@) { # use & as the first item in a prototype to take bare blocks like map and grep

   my ($sub, @ret) = @_;   # this function applies a function that is expected to modify $_ to a list
   $sub->() for @ret;      # it allows for simple inline application of the s/// and tr/// constructs
   @ret

}

print join ", " => apply {tr/aeiou/AEIOU/} qw/one two three four/;

  1. OnE, twO, thrEE, fOUr</lang>

<lang perl>sub first {shift->()}

sub second {'second'}

print first \&second;

print first sub{'sub'};</lang>

Perl 6

The best type to use for the parameter of a higher-order function is Callable (implied by the & sigil), a role common to all function-like objects. For an example of defining and calling a second-order function, see Functional Composition.

Convenient syntax is provided for anonymous functions, either a bare block, or a parameterized block introduced with ->, which serves as a "lambda":

<lang Perl 6>sub twice(&todo) {

  todo(); todo(); # declaring &todo also defines bare function

} twice { say "Boing!" }

  1. output:
  2. Boing!
  3. Boing!

sub twice-with-param(&todo) {

   todo(0); todo(1);

} twice-with-param -> $time {

  say "{$time+1}: Hello!"

}

  1. output:
  2. 1: Hello!
  3. 2: Hello!</lang>

PHP

<lang php>function first($func) {

 return $func();

}

function second() {

 return 'second';

}

$result = first('second');</lang>

PicoLisp

<lang PicoLisp>: (de first (Fun)

  (Fun) )

-> first

(de second ()
  "second" )

-> second

(first second)

-> "second"

(de add (A B)
  (+ A B) )

-> add

(add 1 2)

-> 3

(de call-it (Fun X Y)
  (Fun X Y) )

-> call-it

(call-it add 1 2)

-> 3

(mapcar inc (1 2 3 4 5))

-> (2 3 4 5 6)

(mapcar + (1 2 3) (4 5 6))

-> (5 7 9)

(mapcar add (1 2 3) (4 5 6))

-> (5 7 9)</lang>


PL/I

<lang PL/I> f: procedure (g) returns (float);

  declare g entry (float);
  get (x);
  put (g(x));

end f;

  x = f(p); /* where "p" is the name of a function. */

</lang>

Pop11

<lang pop11>;;; Define a function define x_times_three_minus_1(x);

 return(3*x-1);

enddefine;

Pass it as argument to built-in function map and print the result

mapdata({0 1 2 3 4}, x_times_three_minus_1) =></lang>

Prolog

Works with: SWI Prolog

<lang prolog> first(Predicate):-Predicate. second(Argument):-print(Argument).

-first(second('Hello World!')).

</lang>

PureBasic

<lang PureBasic>Prototype.d func(*text$)

Procedure NumberTwo(arg$)

 Debug arg$

EndProcedure

Procedure NumberOne(*p, text$)

 Define MyFunc.func=*p
 MyFunc(@text$)

EndProcedure

NumberOne(@NumberTwo(),"Hello Worldy!")</lang>

Python

Works with: Python version 2.5

<lang python>def first(function):

   return function()

def second():

   return "second"

result = first(second)</lang>

or

<lang python> result = first(lambda: "second")</lang>

Functions are first class objects in Python. They can be bound to names ("assigned" to "variables"), associated with keys in dictionaries, and passed around like any other object.

R

<lang R>f <- function(f0) f0(pi) # calc. the function in pi tf <- function(x) x^pi # a func. just to test

print(f(sin)) print(f(cos)) print(f(tf))</lang>

REBOL

<lang REBOL>REBOL [ Title: "Function Argument" Author: oofoe Date: 2009-12-19 URL: http://rosettacode.org/wiki/Function_as_an_Argument ]

map: func [ "Apply function to contents of list, return new list." f [function!] "Function to apply to list." data [block! list!] "List to transform." /local result i ][ result: copy [] repeat i data [append result f i] result]

square: func [ "Calculate x^2." x [number!] ][x * x]

cube: func [ "Calculate x^3." x [number!] ][x * x * x]

Testing

x: [1 2 3 4 5] print ["Data: " mold x] print ["Squared:" mold map :square x] print ["Cubed: " mold map :cube x] print ["Unnamed:" mold map func [i][i * 2 + 1] x]</lang>

Output:

Data:    [1 2 3 4 5]
Squared: [1 4 9 16 25]
Cubed:   [1 8 27 64 125]
Unnamed: [3 5 7 9 11]

Ruby

With a proc (procedure): <lang ruby>succ = proc{|x| x+1} def to2(&f)

 f[2]

end

to2(&succ) #=> 3 to2{|x| x+1} #=> 3</lang>

With a method: <lang ruby>def succ(n)

 n+1

end def to2(m)

 m[2]

end

meth = method(:succ) to2(meth) #=> 3</lang>

Scala

<lang scala>def functionWithAFunctionArgument(x : int, y : int, f : (int, int) => int) = f(x,y)</lang> Call: <lang scala>functionWithAFunctionArgument(3, 5, {(x, y) => x + y}) // returns 8</lang>

Scheme

A function is just a value that wants arguments: <lang scheme>> (define (func1 f) (f "a string")) > (define (func2 s) (string-append "func2 called with " s)) > (begin (display (func1 func2)) (newline)) func2 called with a string</lang>

Or, with an anonymous function: <lang scheme>> (define (func f) (f 1 2)) > (begin (display (func (lambda (x y) (+ x y)))) (newline)) 3</lang> Note that (func (lambda (x y) (+ x y))) is equivalent to (func +). (Operators are functions too.)

Slate

Methods and blocks can both be passed as arguments to functions (other methods and blocks): <lang slate>define: #function -> [| :x | x * 3 - 1].

  1. (1 1 2 3 5 8) collect: function.</lang>

Standard ML

<lang sml>- fun func1 f = f "a string"; val func1 = fn : (string -> 'a) -> 'a - fun func2 s = "func2 called with " ^ s; val func2 = fn : string -> string

- print (func1 func2 ^ "\n"); func2 called with a string val it = () : unit</lang>

Or, with an anonymous function: <lang sml>- fun func f = f (1, 2); val func = fn : (int * int -> 'a) -> 'a

- print (Int.toString (func (fn (x, y) => x + y)) ^ "\n"); 3 val it = () : unit</lang> Note that func (fn (x, y) => x + y) is equivalent to func op+. (Operators are functions too.)

Tcl

<lang tcl># this procedure executes its argument: proc demo {function} {

   $function 

}

  1. for example:

demo bell</lang> It is more common to pass not just a function, but a command fragment or entire script. When used with the built-in list command (which introduces a very useful degree of quoting) this makes for a very common set of techniques when doing advanced Tcl programming. <lang tcl># This procedure executes its argument with an extra argument of "2" proc demoFrag {fragment} {

   {*}$fragment 2

}

  1. This procedure executes its argument in the context of its caller, which is
  2. useful for scripts so they get the right variable resolution context

proc demoScript {script} {

   uplevel 1 $script

}

  1. Examples...

set chan stderr demoFrag [list puts $chan] demoFrag {

   apply {x {puts [string repeat ? $x]}}

} demoScript {

   parray tcl_platform

}</lang>

TI-89 BASIC

TI-89 BASIC does not have first-class functions; while function definitions as stored in variables are fully dynamic, it is not possible to extract a function value from a variable rather than calling it. In this case, we use the indirection operator #, which takes a string and returns the value of the named variable, to use the name of the function as something to be passed.

The function name passed cannot be that of a local function, because the local function map does not see the local variables of the enclosing function.

<lang ti89b>Local map Define map(f,l)=Func

 Return seq(#f(l[i]),i,1,dim(l))

EndFunc Disp map("sin", {0, π/6, π/4, π/3, π/2})</lang>

Toka

Toka allows obtaining a function pointer via the ` (backtick) word. The pointers are passed on the stack, just like all other data.

<lang toka>[ ." First\n" ] is first [ invoke ] is second ` first second</lang>

Trith

Due to the homoiconic program representation and the concatenative nature of the language, higher-order functions are as simple as: <lang trith>: twice 2 times ;

hello "Hello, world!" print ;

[hello] twice</lang>

Ursala

Autocomposition is a user defined function that takes a function as an argument, and returns a function equivalent to the given functon composed with itself.

<lang Ursala>(autocomposition "f") "x" = "f" "f" "x"</lang> test program: <lang Ursala>#import flo

  1. cast %e

example = autocomposition(sqrt) 16.0</lang> output:

2.000000e+00


V

Define first as multiplying two numbers on stack <lang v>[first *].</lang> Define second as applying the passed quote on stack <lang v>[second i].</lang> Pass the first enclosed in quote to second which applies it on stack. <lang v>2 3 [first] second</lang>

=6