Skip to end of metadata
Go to start of metadata
Unknown macro: {style}


Unknown macro: {font-family}

Function data type

In Lisp, a function is a data type. They are not treated any differently than other data types. To pass a function foo as an argument, you give it the prefix #`, making it #`foo. The parameter listing to accept a function does not need any special identification. The function can then (funcall param) to execute the function.

For another example, see First-class functions.


Functions may not be overloaded in Lisp. For instance, the following is illegal:

This example shows that the built-in function + can accept any number of arguments. This is not an example of overloading, but instead an instance of allowing for an arbitrary number of parameters.

Lambda Expressions

Sometimes we want to create a function that is used as an argument but never called on its own. Such a function does not need a name and, once bound to a variable, is only used in the context of the variable. Lisp has lambda expressions for these situations. For instance, if a sorting routine requires a comparison function as an argument, you may want to use a common one such as <, or you may want to define your own. If you define your own, you do not need to write a defun for it because you only need it to sort lists in this one location. You can write a lambda expression to define the function right where you need it.

The syntax is to follow the symbol lambda by a list of the parameters and then the body of the function. For example: (lambda (x) (* x x)) or (lambda (x y) (cons x (list y))).

In the following code snippet, we use the built-in sort function which takes a list and comparison function as arguments. In the first line, we call it with the built-in operator < to sort the list in ascending order. The second line will also sort the list in ascending order, but use a lambda expression to express our intentions. This is not useful, but it demonstrates the possibilities. You can create any relation, though it should satisfy transitivity, reflexiveness, and antisymmetry so that the list can in fact be ordered.

Local Functions

We have previously mentioned that let is a special form which allows you to create local variables. Lisp also allows you to make local functions. The corresponding operator is flet (Function LET). A drawback of flet is that you cannot call one local function from another. The operator labels, on the other hand, does permit this.

Local functions are useful because they allow one function to contain all of its logic, while at the same time modularizing it. This is particularly helpful to implement tail-recursion, which is more efficient than other varieties of recursion but often needs an extra parameter. The primary function may have only the parameters one would expect, and it can define a local tail-recursive function, which it calls.

The following example merges two sorted lists (as in merge-sort). Notice that revlist uses tail recursion with local functions. The option on the left uses nested flet, and the right uses labels. We could replace the flet with labels, but not vice versa because revlist uses rev-util.

Unknown macro: {table}
Unknown macro: {tr}
Unknown macro: {td}
Unknown macro: {td}
  • No labels