(define T (lambda (a b) a)) (define F (lambda (a b) b)) (define NOT (lambda (x) (x F T))) (define AND (lambda (b1 b2) (b1 b2 F))) (define OR (lambda (b1 b2) (b1 T b2)))
``` Quer um desafio maior? Os mais sucintos dialetos LISP trabalham sempre em cima de apenas uma estrutura de dados: a lista. E essa lista, por sua vez, é manipulada por três primitivas básicas: a construção de um par (A,B) (`pair` ou `cons`), a seleção do primeiro elemento de um par (`head` ou `car`), e a seleção do segundo elemento de um par (`tail` ou `cdr`). De tal maneira que `head(pair(a,b))` resulte em `a` e `tail(pair(a,b))` resulte em `b`.
Como implementar essas três primitivas? Você vai ver que, sem usar estrutura de dados, porém com auxílio de ifs, já dá algum trabalho. É um bom exercício. Mas há como implementar sem nem ifs, nem estruturas! E não é tão complicado, basta que a primeiriva `pair`, dado os dois elementos a e b, guarde-os. Como guardar se não temos estrutura de dados? Devolvemos um lambda que por sua vez recebe um novo lambda que será aplicado nos dois argumentos. As primitivas de `head` e `tail` vão então aplicar esse lambda, que representa um par, passando uma função que, dado dois argumentos, devolve o primeiro ou último elemento.
```code
pair ≡ λab.λf.fab head ≡ λp.p(λab.a) tail ≡ λp.p(λab.b)