Higher-order functions: Difference between revisions
→Pointer: Removed syntax highlighting |
→[[JavaScript]]: Added Pascal |
||
Line 199: | Line 199: | ||
var result = first(second); |
var result = first(second); |
||
result = first(function() { return "third"; }); |
result = first(function() { return "third"; }); |
||
==[[Pascal]]== |
|||
[[Category: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]]== |
==[[Perl]]== |
Revision as of 01:13, 15 March 2007
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);
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