Evaluator for adding and subtracting algebraic expressions

I wrote a little program that adds and subtracts some algebraic expressions.

In my code (2 x 3) represents $$\2x^3\$$.

The purpose of this post is to get some feedback; moreover, I would like to know how to make it perform better and improve it.

I ran this program on a Mac with SBCL + Emacs.

(defun compute (exp)
(cond ((term? exp) exp)
((expression? exp)
(make (compute (first-expression exp))
(compute (second-expression exp))
(operator exp)))
(t (error "Unknown Expression Type --COMPUTE" exp))))

(defun term? (exp)
(or (numberp exp)
(monomial? exp)))

(defun monomial? (exp)
(and (consp exp)
(numberp (car exp))
(symbolp (car (cdr exp)))
(numberp (car (cdr (cdr exp))))))

(defun expression? (exp)
(or (eql (car exp) '+)
(eql (car exp) '*)
(eql (car exp) '-)))

(defun first-expression (exp) (car (cdr exp)))

(defun second-expression (exp) (car (cdr (cdr exp))))

(defun operator (exp) (car exp))

(defun make (e1 e2 op)
(cond ((eql op '+)
((eql op '-)
(make-subtraction e1 e2))
(t (make-product e1 e2))))

I wrote the following higher order procedures because version 1 had a lot patterns.

(defun make-addition (e1 e2)
(make-exp e1
e2
'+

(defun make-subtraction (e1 e2)
(make-exp e1
e2
'-
#'subtract-monomials))

(defun make-exp (e1 e2 op term)
(cond ((eql e1 0) e2)
((eql e2 0) e1)
((&number? e1 e2) (+ e1 e2))
((&monomial? e1 e2)
(funcall term e1 e2))
(t (list op e1 e2))))

;; make-product
(defun make-product (e1 e2) (list '* e1 e2))

(defun &number? (e1 e2)
(and (numberp e1)
(numberp e1)))

(defun &monomial? (e1 e2)
(and (monomial? e1)
(monomial? e2)))

(defun add-monomials (e1 e2)
(compute-monomials e1
e2
#'+
'+))

(defun subtract-monomials (e1 e2)
(compute-monomials e1
e2
#'-
'-))

(defun compute-monomials (e1 e2 term op)
(if (same-variable? e1 e2)
(make-monomial (funcall term (coeff e1) (coeff e2))
(variablex e1)
(exponent e1))
(list op e1 e2p)))

(defun variablex (exp) (car (cdr exp)))

(defun same-variable? (e1 e2)
(eql (variablex e1) (variablex e2)))

(defun make-monomial (coeff var exp)
(list coeff var exp))

(defun coeff (exp) (car exp))

(defun exponent (exp) (car (cdr (cdr exp))))
• you might want to improve indentation. It's off in many places and makes the code difficult to read. Maybe your editor uses tab characters and you are copying the code with tabs? Don't use tabs then. – Rainer Joswig Jun 27 at 7:50
• are there any performance problems? Which ones? – Rainer Joswig Jun 27 at 8:03

Make sure your code is indented correctly here. It isn't.

Then document your code at least with some minimum amount of explanations and structure.

Common Lisp has ways to comment code:

;;;; program comment

;;; section comment

(defun bar ()

"This is a retrievable function documentation
string, which
can be spread over many lines."

(let ((foo (random 100)))
;;  indented code comment
(+ foo 3)   ; inline code comment
))

#|
|#

Then one can retrieve the function documentation with some IDE keystrokes/mechanisms and:

(documentation 'bar 'function)

Some hints:

(defun expression? (exp)
(or (eql (car exp) '+)
(eql (car exp) '*)
(eql (car exp) '-)))

(case exp
((+ * -) t)
(otherwise nil))

(member (car exp) '(+ * -))

(defun first-expression (exp) (car (cdr exp)))

(second exp)

(defun second-expression (exp) (car (cdr (cdr exp))))

(third exp)

(defun make (e1 e2 op)
(cond ((eql op '+)