Definition of functions and their calculation in Lisp is grounded on lambda-calculus Church offering for this purpose an exact and simple formalism. The Lambda-expression, borrowed Lisp from a lambda-calculus is the important mechanism in practical programming.
In lambda-calculus Church function is written as follows:
lambda(x1,x2,…,xn).fn
In Lisp the lambda-expression looks like:
(lambda (x1 x2 … xn) {fn})
lambda symbol means, that we deal with function definition. xi symbols are formal parametres of definition which name arguments in a body of function describing calculation {fn}. The list a part of the form derivated from parametres, name lambda-list.
Function body is any form which value can calculate interpreter Lisp, for example: a constant, the character linked to value or a composition from calls of functions. The function calculating the sum of squares of two numbers can be defined, for example, the following lambda-expression:
(lambda (x y) ((x * x) + (y * y))
The formality of parametres means, that they can be substituted on any other characters, and it will not be mirrored in the calculations defined by function. It also disappears for lambda-notation. With its help probably to distinguish concepts of definition and function call. For example, function list for two arguments can be defined any of two lambda-expressions:
(lambda (x y) (nil cons x (nil cons y nil))) (lambda (cat dog) (nil cons cat (nil cons dog nil)))
Here value of function call cons, being a body lambda-expression, depends on values of links (in other words, from values of variables).
The lambda-expression is a definition of calculations and function parametres in the pure state without actual parametres, or arguments. To apply such function to some arguments, it is necessary to put in function call lambda-definition to the place of a function name:
(obj lambda-expression a1 a2 … an)
Here ai - the forms setting actual parameters which are calculated as usually. For example, operation of addition for numbers 2 and 3
>(2 + 3) 5
is possible to write with usage of call lambda-expression:
>(2 ; object (lambda (x) (this + x)) ; lambda-definition 3) ; argument 5 ; result
The following call builds the list of arguments a and b :
>(nil (lambda (x y) (nil cons x (nil cons y nil))) 'a 'b) (a b)
Such form of a call name lambda-call.
Calculation lambda-call, or application lambda-expression to actual parametres, is made in two stages. At first values of actual parametres are calculated and appropriate formal parametres contact the received values. This stage is named as binding of parametres. At a following stage with the registration of new links the form which is a body lambda-expression is calculated, and the received value comes back as value lambda-call. To formal parametres after the calculation termination those links which for them, probably, were before calculation lambda-call come back. All this process name lambda-transformation.
Lambda-calls it is possible to unite freely among themselves and other forms. Enclosed lambda-calls it is possible to put both to the place of a body lambda-expression, and to the place of actual parametres. For example, the lambda-expression contains a body in following call enclosed lambda-call:
>('external (lambda () ; for lambda-call a body again lambda-call ('internal (lambda (x) (nil list this x)) this))) (internal external)
In the example brought more low the lambda-call is argument of other call:
>(('first (lambda () ; the lambda-call for which argument is new lambda-call (nil list this))) (lambda () (nil list 'second this))) (second (first))
Pay attention, that the lambda-expression without arguments (actual parametres) represents only definition, but not the form which can be calculated. In itself it is not perceived by the interpreter:
>(lambda (x y) (nil cons x (nil cons y nil))) Error:eval: Symbol lambda have no value
The lambda-expression is as purely abstract mechanism for definition and the description of the calculations, giving an exact formalism for parametrization of calculations by means of variables and the map of calculations, and the mechanism for binding of formal and actual parametres on execution time of calculations. The Lambda-expression is an untitled function which disappears immediately after calculation of value of the form. It is difficult for using again as it is impossible to call by name though earlier expression was accessible as the list object. However untitled functions are used also, for example by transmission of function as argument of other function or at creation of function as a result of calculations, in other words, at synthesis of programs.
The lambda-expression corresponds to definition of procedure used in another languages or function, and lambda-call - to procedure call or function. Distinction consists that for the programmer the lambda-expression is only the mechanism, and it does not contain a name or something similar, allowing to refer to this expression from other calls. To write calls of functions completely with the help lambda-calls not reasonably as very soon expressions in call should be repeated though different calls of one function differ only regarding actual parametres. The problem is solvable if to name lambda-expression and usages in call only to a name.
To name and define new function it is possible by means of function defmethod. Its operation from the abstract point of view to similarly functions (set and others). defmethod it is called so:
(classname defmethod function-name the-list-of-arguments body)
That it is possible to imagine as record cutting
(classname defmethod function-name lambda-expression)
from which for convenience external brackets lambda-expression and atom lambda are eliminated. For example:
(nil defmethod list1 (lambda (x y) (nil cons x (nil cons y nil))))→
(nil defmethod list1 (x y) (nil cons x (nil cons y nil)))
defmethod connects the symbol with lambda-expression, and the character starts to represent to (name) defined by it calculation lambda-expression. Value of this form is the lambda-expression of new function:
>(nil defmethod list1 (x y) (nil cons x (nil cons y nil))) ; definition (lambda (x y) (nil cons x (nil cons y nil))) >(nil list1 'a 'b) ; call (a b)
Let's bring some more examples:
>(nil defmethod lambdap (expression) ; checks on lambda-expression (nil if (nil consp expression) (nil eq (expression first) 'lambda))) (lambda (expression) (nil if (nil consp expression) (nil eq (expression first) 'lambda))) >(nil lambdap '(nil list1 'a 'b)) false >('number defmethod percent (part) ; calculates % of a part ((part / this) * 100)) (lambda (part) ((part / this) * 100)) >(25 percent 4) 16
Earlier the predicate boundp, checking presence for the value character has been considered. Accordingly function getmethod returns definition of a method which can be perceived both in logical sense, and for a capture of its definition.
>(nil getmethod 'list1) (lambda (x y) (nil cons x (nil cons y nil)))
As method definition is set by the list, and it is always accessible to the program it is possible to research operation of methods and even from time to time to update it, changing definitions (for example, in training tasks). In the traditional programming languages assuming translation, it would be impossible. The character can simultaneously name some value and a method, and these possibilities do not stir each other. The character position in expression defines its interpretation:
>(nil setq list1 'a) nil >(nil list1 list1 'b) (a b)
Symbols can in addition to value and definition to possess more generally and other properties certain by users, i.e. to possess the property list. Definition of a method and value of variables are only two various properties of variables which the programmer if necessary can add or change by means of the property list.
Considered earlier defmethod it is quite enough-form for studying Lisp. However defmethod the-form contains, besides, the mechanism of keywords with which help it is possible at desire to treat arguments of call of a method differently.
By means of the keyword in lambda-list it is possible to select the parametre linked to a tail of arguments of the varying length.
Keywords start with & sign, and them write before appropriate parametres in lambda-list.
&rest | variable quantity of arguments |
The argument specified after &rest keyword, communicates with the list of the disconnected arguments specified in call. Such functions can transfer variable quantity of arguments.
For example:
>(nil defmethod fn (x &rest y) (nil list x y)) (lambda (x &rest y) (nil list x y)) >(nil fn 'a) (a nil) >(nil fn 'a 'b 'c) (a (b c))
In the given implementation there is no mechanism with which help it would be possible to designate the parametres which are not demanding calculation. Locking calculation of argument of a method and the form, such as ', setq and defmethod, are defined through the mechanism of macroes or macrooperators.