Apply

Last updated

In mathematics and computer science, apply is a function that applies a function to arguments. It is central to programming languages derived from lambda calculus, such as LISP and Scheme, and also in functional languages. It has a role in the study of the denotational semantics of computer programs, because it is a continuous function on complete partial orders. Apply is also a continuous function in homotopy theory, and, indeed underpins the entire theory: it allows a homotopy deformation to be viewed as a continuous path in the space of functions. Likewise, valid mutations (refactorings) of computer programs can be seen as those that are "continuous" in the Scott topology.

Contents

The most general setting for apply is in category theory, where it is right adjoint to currying in closed monoidal categories. A special case of this are the Cartesian closed categories, whose internal language is simply typed lambda calculus.

Programming

In computer programming, apply applies a function to a list of arguments. Eval and apply are the two interdependent components of the eval-apply cycle , which is the essence of evaluating Lisp, described in SICP. [1] Function application corresponds to beta reduction in lambda calculus.

Apply function

Apply is also the name of a special function in many languages, which takes a function and a list, and uses the list as the function's own argument list, as if the function were called with the elements of the list as the arguments. This is important in languages with variadic functions, because this is the only way to call a function with an indeterminate (at compile time) number of arguments.

Common Lisp and Scheme

In Common Lisp apply is a function that applies a function to a list of arguments (note here that "+" is a variadic function that takes any number of arguments):

(apply#'+(list12))

Similarly in Scheme:

(apply+(list12))

C++

In C++, Bind [2] is used either via the std namespace or via the boost namespace.

C# and Java

In C# and Java, variadic arguments are simply collected in an array. Caller can explicitly pass in an array in place of the variadic arguments. This can only be done for a variadic parameter. It is not possible to apply an array of arguments to non-variadic parameter without using reflection. An ambiguous case arises should the caller want to pass an array itself as one of the arguments rather than using the array as a list of arguments. In this case, the caller should cast the array to Object to prevent the compiler from using the apply interpretation.

variadicFunc(arrayOfArgs);

With version 8 lambda expressions were introduced. Functions are implemented as objects with a functional interface, an interface with only one non-static method. The standard interface

Function<T,R>

consist of the method (plus some static utility functions):

Rapply(Tpara)

Go

In Go, typed variadic arguments are simply collected in a slice. The caller can explicitly pass in a slice in place of the variadic arguments, by appending a ... to the slice argument. This can only be done for a variadic parameter. The caller can not apply an array of arguments to non-variadic parameters, without using reflection..

s:=[]string{"foo","bar"}variadicFunc(s...)

Haskell

In Haskell, functions may be applied by simple juxtaposition:

funcparam1param2...

In Haskell, the syntax may also be interpreted that each parameter curries its function in turn. In the above example, "func param1" returns another function accepting one fewer parameters, that is then applied to param2, and so on, until the function has no more parameters.

JavaScript

In JavaScript, function objects have an apply method, the first argument is the value of the this keyword inside the function; the second is the list of arguments:

func.apply(null,args);

ES6 adds the spread operator func(...args) [3] which may be used instead of apply.

Lua

In Lua, apply can be written this way:

functionapply(f,...)returnf(...)end

Perl

In Perl, arrays, hashes and expressions are automatically "flattened" into a single list when evaluated in a list context, such as in the argument list of a function

# Equivalent subroutine calls:@args=(@some_args,@more_args);func(@args);func(@some_args,@more_args);

PHP

In PHP, apply is called call_user_func_array:

call_user_func_array('func_name',$args);

Python and Ruby

In Python and Ruby, the same asterisk notation used in defining variadic functions is used for calling a function on a sequence and array respectively:

func(*args)

Python originally had an apply function, but this was deprecated in favour of the asterisk in 2.3 and removed in 3.0. [4]

R

In R, do.call constructs and executes a function call from a name or a function and a list of arguments to be passed to it:

f(x1,x2)# can also be performed viado.call(what=f,args=list(x1,x2))

Smalltalk

In Smalltalk, block (function) objects have a valueWithArguments: method which takes an array of arguments:

aBlockvalueWithArguments:args

Tcl

Since Tcl 8.5, [5] a function can be applied to arguments with the apply command

applyfunc?arg1arg2...?

where the function is a two element list {args body} or a three element list {args body namespace}.

Universal property

Consider a function , that is, where the bracket notation denotes the space of functions from A to B. By means of currying, there is a unique function . Then Apply provides the universal morphism

,

so that

or, equivalently one has the commuting diagram

More precisely, curry and apply are adjoint functors.


The notation for the space of functions from A to B occurs more commonly in computer science. In category theory, however, is known as the exponential object, and is written as . There are other common notational differences as well; for example Apply is often called Eval, [6] even though in computer science, these are not the same thing, with eval distinguished from Apply, as being the evaluation of the quoted string form of a function with its arguments, rather than the application of a function to some arguments.

Also, in category theory, curry is commonly denoted by , so that is written for curry(g). This notation is in conflict with the use of in lambda calculus, where lambda is used to denote bound variables. With all of these notational changes accounted for, the adjointness of Apply and curry is then expressed in the commuting diagram

Universal property of the exponential object ExponentialObject-01.svg
Universal property of the exponential object

The articles on exponential object and Cartesian closed category provide a more precise discussion of the category-theoretic formulation of this idea. Thus the use of lambda here is not accidental; the internal language of Cartesian closed categories is simply-typed lambda calculus. The most general possible setting for Apply are the closed monoidal categories, of which the cartesian closed categories are an example. In homological algebra, the adjointness of curry and apply is known as tensor-hom adjunction.

Topological properties

In order theory, in the category of complete partial orders endowed with the Scott topology, both curry and apply are continuous functions (that is, they are Scott continuous). [7] This property helps establish the foundational validity of the study of the denotational semantics of computer programs.

In algebraic geometry and homotopy theory, curry and apply are both continuous functions when the space of continuous functions from to is given the compact open topology, and is locally compact Hausdorff. This result is very important, in that it underpins homotopy theory, allowing homotopic deformations to be understood as continuous paths in the space of functions.

Related Research Articles

In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions, each with a single argument. For example, currying a function that takes three arguments creates a nested unary function , so that the code

In mathematics, specifically category theory, a functor is a mapping between categories. Functors were first considered in algebraic topology, where algebraic objects are associated to topological spaces, and maps between these algebraic objects are associated to continuous maps between spaces. Nowadays, functors are used throughout modern mathematics to relate various categories. Thus, functors are important in all areas within mathematics to which category theory is applied.

Lambda calculus is a formal system in mathematical logic for expressing computation based on function abstraction and application using variable binding and substitution. It is a universal model of computation that can be used to simulate any Turing machine. It was introduced by the mathematician Alonzo Church in the 1930s as part of his research into the foundations of mathematics.

In mathematics, logic, and computer science, a type theory is the formal presentation of a specific type system, and in general type theory is the academic study of type systems. Some type theories serve as alternatives to set theory as a foundation of mathematics. Two influential type theories that were proposed as foundations are Alonzo Church's typed λ-calculus and Per Martin-Löf's intuitionistic type theory. Most computerized proof-writing systems use a type theory for their foundation. A common one is Thierry Coquand's Calculus of Inductive Constructions.

Combinatory logic is a notation to eliminate the need for quantified variables in mathematical logic. It was introduced by Moses Schönfinkel and Haskell Curry, and has more recently been used in computer science as a theoretical model of computation and also as a basis for the design of functional programming languages. It is based on combinators, which were introduced by Schönfinkel in 1920 with the idea of providing an analogous way to build up functions—and to remove any mention of variables—particularly in predicate logic. A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.

In mathematics and computer science in general, a fixed point of a function is a value that is mapped to itself by the function.

Curry's paradox is a paradox in which an arbitrary claim F is proved from the mere existence of a sentence C that says of itself "If C, then F", requiring only a few apparently innocuous logical deduction rules. Since F is arbitrary, any logic having these rules allows one to prove everything. The paradox may be expressed in natural language and in various logics, including certain forms of set theory, lambda calculus, and combinatory logic.

In mathematics, a self-adjoint operator on an infinite-dimensional complex vector space V with inner product is a linear map A that is its own adjoint. If V is finite-dimensional with a given orthonormal basis, this is equivalent to the condition that the matrix of A is a Hermitian matrix, i.e., equal to its conjugate transpose A. By the finite-dimensional spectral theorem, V has an orthonormal basis such that the matrix of A relative to this basis is a diagonal matrix with entries in the real numbers. This article deals with applying generalizations of this concept to operators on Hilbert spaces of arbitrary dimension.

In category theory, a category is Cartesian closed if, roughly speaking, any morphism defined on a product of two objects can be naturally identified with a morphism defined on one of the factors. These categories are particularly important in mathematical logic and the theory of programming, in that their internal language is the simply typed lambda calculus. They are generalized by closed monoidal categories, whose internal language, linear type systems, are suitable for both quantum and classical computation.

In mathematics and computer science, a higher-order function (HOF) is a function that does at least one of the following:

In mathematics, a function space is a set of functions between two fixed sets. Often, the domain and/or codomain will have additional structure which is inherited by the function space. For example, the set of functions from any set X into a vector space has a natural vector space structure given by pointwise addition and scalar multiplication. In other scenarios, the function space might inherit a topological or metric structure, hence the name function space.

In computer science and mathematical logic, a function type is the type of a variable or parameter to which a function has or can be assigned, or an argument or result type of a higher-order function taking or returning a function.

In mathematics and in computer programming, a variadic function is a function of indefinite arity, i.e., one which accepts a variable number of arguments. Support for variadic functions differs widely among programming languages.

In computer science, function composition is an act or mechanism to combine simple functions to build more complicated ones. Like the usual composition of functions in mathematics, the result of each function is passed as the argument of the next, and the result of the last one is the result of the whole.

In mathematics, specifically in category theory, an exponential object or map object is the categorical generalization of a function space in set theory. Categories with all finite products and exponential objects are called cartesian closed categories. Categories without adjoined products may still have an exponential law.

In mathematics, Church encoding is a means of representing data and operators in the lambda calculus. The Church numerals are a representation of the natural numbers using lambda notation. The method is named for Alonzo Church, who first encoded data in the lambda calculus this way.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

In mathematics, function application is the act of applying a function to an argument from its domain so as to obtain the corresponding value from its range. In this sense, function application can be thought of as the opposite of function abstraction.

In computer programming, variadic templates are templates that take a variable number of arguments.

In computer science, partial application refers to the process of fixing a number of arguments to a function, producing another function of smaller arity. Given a function , we might fix the first argument, producing a function of type . Evaluation of this function might be represented as . Note that the result of partial function application in this case is a function that takes two arguments. Partial application is sometimes incorrectly called currying, which is a related, but distinct concept.

References

  1. Harold Abelson, Gerald Jay Sussman, Julie Sussman, Structure and Interpretation of Computer Programs, (1996) MIT Press, ISBN   0-262-01153-0. See Section 4.1, The Metacircular Evaluator
  2. "Boost: Bind.HPP documentation - 1.49.0".
  3. "Spread syntax - JavaScript | MDN" . Retrieved 2017-04-20.
  4. "Non-essential built-in functions". Python Library Reference. 8 February 2005. Retrieved 19 May 2013.
  5. "apply". Tcl documentation. 2006. Retrieved 23 June 2014.
  6. Saunders Mac Lane, Category Theory
  7. H.P. Barendregt, The Lambda Calculus, (1984) North-Holland ISBN   0-444-87508-5