Jump to content

First-class function

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by 12.23.96.197 (talk) at 22:28, 7 July 2008 (→‎Javascript). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

In computer science, a programming language is said to support first-class functions (or function literal) if it treats functions as first-class objects. Specifically, this means that the language supports constructing new functions during the execution of a program, storing them in data structures, passing them as arguments to other functions, and returning them as the values of other functions. This concept doesn't cover any means external to the language and program (metaprogramming), such as invoking a compiler or an eval function to create a new function.

These features are a necessity for the functional programming style, in which (for instance) the use of higher-order functions is a standard practice. A simple example of a higher-ordered function is the map or mapcar function, which takes as its arguments a function and a list, and returns the list formed by applying the function to each member of the list. For a language to support map, it must support passing a function as an argument.

There are certain implementation difficulties in passing functions as arguments and returning them as results. Historically, these were termed the funarg problems, the name coming from "function argument". A different set of difficulties arises when programs can create functions at runtime; if the program is compiled, this means that the runtime environment must itself include a compiler.

Availability

Languages which are strongly associated with functional programming, such as Lisp, Scheme, ML, and Haskell, all support first-class functions. Other languages which also support them include Perl, Python, Lua, ECMAScript (JavaScript, ActionScript), Ruby, Io, Scala, and Nemerle.

Most modern, natively compiled programming languages (e.g. C and Pascal) support function pointers, which can be stored in data structures and passed as arguments to other functions. Nevertheless, they are not considered to support first-class functions since, in general, functions cannot be created dynamically during the execution of a program. The closest analog would be a dynamically compiled function created by a just-in-time compiler, which is compiled as an array of machine language instructions in memory and then cast to a function pointer. However, this technique is specific to the underlying hardware architecture and is, therefore, neither general nor portable. The C++ programming language supports user-defined operators, including the '()' operator, which allows first-class objects to be treated as functions. Those objects can be manipulated just like any other first-class object in C++, but such manipulations do not include changing the function itself at runtime. Additionally, real Lambdas (see Lambda Calculus) have no language support in the last C++ standard (although there may be in C++0x).

Examples

(lambda (a b) (* a b)) ; function literal
((lambda (a b) (* a b)) 4 5) ; function is passed 4 and 5

PROC newton = (REAL x, error, PROC (REAL) REAL f, f prime) REAL:
# Newton's method #
  IF f(x) <= error
  THEN x
  ELSE newton (x - f(x) / f prime (x), error, f, f prime)
  FI;

print((
  newton(0.5, 0.001, (REAL x) REAL: x**3 - 2*x**2 + 6, (REAL x) REAL: 3*x**2 - 4**x),
  newline
));

function(message) { print(message); } // function literal
SomeObject.SomeCallBack=function(message) { print(message); } // function literal assigned to callback

Note that the callee keyword in ECMAScript makes it possible to write recursive functions without naming them.

Python does not have a (full) function literal, because lambda can only be followed by an expression and not statements.

lambda x:x*x # function literal 
map(lambda x:x*x,range(1,10)) # array of first ten square numbers

Javascript supports both first class functions and lexical scope.

// f: function that takes a number and returns a number
// deltaX: small positive number
// returns a function that is an approximate derivative of f
function makeDerivative( f, deltaX )
{
    var deriv = function(x)
    { 
       return ( f(x + deltaX) - f(x) )/ deltaX;
    }
    return deriv;
}
var cos = makeDerivative( Math.sin, 0.000001);
// cos(0)     ~> 1
// cos(pi/2)  ~> 0

See also