Tal como em matemática, pode-se definir numa linguagem de programação a operação de elevar um número ao quadrado. Assim, se pretendermos determinar o produto de um número por ele próprio, escrevemos a combinação (* x x) sendo x o número, i.e.
> (* 5 5) 25 > (* 6 6) 36
Os números 5 e 6 e a operação * são elementos primitivos. As expressões (* 5 5) e (* 6 6) são combinações. À combinação genérica (* x x) queremos associar um nome, por exemplo, quadrado. Isso equivale a acrescentar uma nova função à linguagem.
A título de exemplo, vamos definir a função quadrado:
> (defun quadrado (x) (* x x)) quadrado
Para se definirem novas funções em Lisp, é necessário criar uma combinação de quatro elementos. O primeiro elemento desta combinação é a palavra defun, que informa o avaliador que estamos a definir uma função. O nome defun é uma abreviatura de ``define function''. O segundo elemento é o nome da função que queremos definir, o terceiro elemento é uma combinação com os parâmetros da função e o quarto elemento é a combinação que determina o valor da função para aqueles parâmetros.
Quando se dá uma expressão desta forma ao avaliador, ele acrescenta a função ao conjunto de funções da linguagem, associando-a ao nome que lhe demos e devolve como valor da definição o nome da função definida.
A definição da função quadrado diz que para se determinar o quadrado de um número x, devemos multiplicar esse número por ele próprio (* x x). Esta definição associa a palavra quadrado a um procedimento. Este procedimento possui parâmetros e um corpo de expressões. De forma genérica temos:
(defun nome (parâmetro-1 ...parâmetro-n) corpo)
Os parâmetros de um procedimento são designados parâmetros formais e são os nomes usados no corpo de expressões para nos referirmos aos argumentos correspondentes. Quando escrevemos no avaliador de Lisp (quadrado 5), 5 é o argumento. Durante o cálculo da função este argumento está associado ao parâmetro formal x. Os argumentos de uma função são também designados parâmetros actuais.
> (quadrado 5) 25 > (quadrado 6) 36
Note-se que a regra de avaliação de combinações é também válida para as funções por nós definidas. Assim, a avaliação da expressão (quadrado (+ 1 2)) passa pela avaliação do operando (+ 1 2). Este operando tem como valor 3, valor esse que é usado pela função no lugar do parâmetro x. O corpo da função é então avaliado, i.e., o valor final será o da combinação (* 3 3).
O seguinte exemplo mostra um caso um pouco mais complexo. Nele estão apresentadas as etapas de avaliação dos operandos e de avaliação do corpo da função.
(quadrado (quadrado (+ 1 2))) (quadrado (quadrado 3)) (quadrado (* 3 3)) (quadrado 9) (* 9 9) 81
A definição de funções permite-nos associar um procedimento a um nome. Isto implica que o Lisp tem de possuir uma memória onde possa guardar o procedimento e a sua associação ao nome dado. Esta memória do Lisp designa-se ambiente.
Note-se que este ambiente apenas existe enquanto estamos a trabalhar com a linguagem. Quando terminamos, perde-se todo o ambiente. Isto implica que, se não queremos perder o trabalho que estivemos a escrever, devemos escrever as funções num ficheiro e ir passando-as para o Lisp. A grande maioria das implementações do Lisp permite fazer isto de forma automática.