Anonymous function

This is an old revision of this page, as edited by Cburnett (talk | contribs) at 20:29, 29 February 2008 (Examples: Added C#). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

An anonymous function is a function (or a subroutine) defined, and possibly called, without being bound to a name. In lambda calculus, all functions are anonymous. The Y combinator can be utilised in these circumstances to provide anonymous recursion. Certain programming languages also provide support for both named and anonymous functions. The lambda calculus without anonymous function definition forms a combinatory logic.

Some object-oriented programming languages have anonymous classes, which are a similar concept. Java is such a language.

Uses

Anonymous functions can be used to contain functionality that need not be named and possibly for short-term use. Some notable examples include closures and currying.

All of the code in the following sections is in python.

Sorting

When attempting to sort in a non-standard way it may be easier to contain the comparison logic as an anonymous function instead of creating a named function. Most languages provide a generic sort function that implements a sort algorithm that will sort arbitrary objects. This function usually accepts an arbitrary comparison function that is supplied two items and the function indicates if they are equal or if one is "greater" or "less" than the other (typically indicated by returned a negative number, zero, or a positive number).

Consider sorting items in a list by the name of their class (everything in python has a class):

a = [10, '10', 10.0]
a.sort(lambda x,y: cmp(x.__class__.__name__, y.__class__.__name__))
print a
[10.0, 10, '10']

Note that 10.0 has class name "float", 10 has class name "int", and '10' has class name "str". The sorted order is "float", "int", then "str".

The anonymous function in this example is the lambda expression:

lambda x,y: cmp(...)

The anonymous function accepts two arguments — x & y — and returns the comparison between them using the built-in function cmp(). Another example would be sorting a list of strings by length of the string:

a = ['three', 'two', 'four']
a.sort(lambda x,y: cmp(len(x), len(y)))
print a
['two', 'four', 'three']

which clearly has been sorted by length of the strings.

Closures

Closures are functions evaluated in an environment containing bound variables. The following example binds the variable "threshold" in an anonymous function that compares the input to the threshold.

def comp(threshold):
  return lambda x: x < threshold

This can be used as a sort of generator of comparison functions:

a = comp(10)
b = comp(20)

print a(9), a(10), a(20), a(21)
True False False False

print b(9), b(10), a(20), b(21)
True True False False

It would clearly be very impractical to create a function for every possible comparison function and may be too inconvenient to keep the threshold around for further use. Regardless of the reason why a closure is used the anonymous function is what the contains the functionality that does the comparing.

Currying

Currying is transforming a function from multiple inputs to fewer inputs.

def divide(x,y):
  return x/y

def divisor(d):
  return lambda x: divide(x,d)

half = divisor(2)
third = divisor(3)

print half(32), third(32)
16 10

print half(40), third(40)
20 13

While the use of anonymous functions is perhaps not common with currying it still can be used. In the above example, the function divisor generates functions with a specified divisor. The functions half and third curry the divide function with a fixed divisor.

(It just so happens that the divisor function forms a closure as well as curries by binding the "d" variable.)

Map

The map function performs a function call on each element of an array. The following example squares every element in an array with an anonymous function.

a = [1, 2, 3, 4, 5, 6]
print map(lambda x: x*x, a)
[1, 4, 9, 16, 25, 36]

The anonymous function accepts an argument and multiplies itself by itself (squares it).

Fold

The fold/reduce function reduces a list of elements repeatedly from left-to-right until only one element remains.

a = [1, 2, 3, 4, 5]
print reduce(lambda x,y: x*y, a)
120

This performs:

 

The anonymous function here is simply the multiplication of the two arguments.

List of languages

The following is a list of programming languages that fully support unnamed anonymous functions; support some variant of anonymous functions; and have no support for anonymous functions.

Language Full support Some support No support
C  Y
C++  Y
C# v1  Y
C# v2  Y
Java  Y
JavaScript  Y
Lisp  Y
Perl  Y
Python  Y
PHP  Y
Scheme  Y

Examples

Numerous languages support anonymous functions, or something similar.

C#

C# has partial anonymous function support through the use of delegates. Somewhat similar to PHP delegates are given a unique name but unlike PHP the name is not required for the delegate to be used. (The example has been trimmed down to demonstrate the anonymous functionality.)

delegate int DeletateClass(int x);
DelegateClass d = delegate(int x) {
    return x*x;
};

System.Console.WriteLine("{0}^2 = {1}", 10, d(10));

The C# compiler takes the code block of the anonymous function and creates a static private function whose name is based on the function in which it is declared. As mentioned above the example is trimmed down to demonstrate the anonymous function instead of using valid C# syntax. Since anonymous methods are not nameless and can only be declared inside methods of classes then C# does not support full anonymous functionality.

JavaScript

JavaScript supports anonymous functions.

var foo = function(x) {return x*x;}
alert(foo(10));

Unlike python, anonymous functions in JavaScript are just like named functions and are declared just like named functions.

Lisp

Lisp supports anonymous functions.

(lambda (arg) (* arg arg))

Python

Python supports anonymous functions through the lambda form. It is, however, expected to be only a single line of code and always returns whatever that line returns. For example:

foo = lambda x: x*x
print foo(10)

The lambda function always returns x*x and there is no way for a lambda function to not return something. This makes anonymous functions limited and are not simply nameless functions.

PHP

PHP doesn't have true anonymous functions because the only way to reference functions is by name. The closest PHP is shown in the following.

$foo = create_function("$x", "return $x*$x;");
echo $foo(10);

Perl

Perl supports anonymous functions, as follows:

(sub { print "I got called\n" })->();         # 1. fully anonymous, called as created

my $squarer = sub { my $x = shift; $x * $x }; # 2. assigned to a variable

sub curry (&@) {
    my ($sub, @args) = @_;
    return sub { $sub->(@args, @_) };         # 3. as a return value of another function
}

# example of currying in Perl
sub sum { my $tot = 0; $tot += $_ for @_; $tot } # returns the sum of its arguments
my $curried = curry \&sum, 5, 7, 9;
print $curried->(1,2,3), "\n";    # prints 27 ( = 5 + 7 + 9 + 1 + 2 + 3 )

Other constructs take "bare blocks" as arguments, which serve a function similar to lambda functions of a single parameter, but don't have the same parameter-passing convention as functions -- @_ is not set.

my @squares = map { $_ * $_ } 1..10;   # map and grep don't use the 'sub' keyword
my @square2 = map $_ * $_, 1..10;      # parentheses not required for a single expression

my @bad_example = map { print for @_ } 1..10; # values not passed like normal Perl function