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.
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
<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
<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;
};
- pass named coderef
print another \&reverser, 'data';
- pass anonymous coderef
print another sub {return scalar reverse shift}, 'data';
- if all you have is a string and you want to act on that,
- 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/;
- 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!" }
- output:
- Boing!
- Boing!
sub twice-with-param(&todo) {
todo(0); todo(1);
} twice-with-param -> $time {
say "{$time+1}: Hello!"
}
- output:
- 1: Hello!
- 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
<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
<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 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
}
- 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
}
- This procedure executes its argument in the context of its caller, which is
- useful for scripts so they get the right variable resolution context
proc demoScript {script} {
uplevel 1 $script
}
- 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
- 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