Search code examples
lispcommon-lisplispworks

Getting a "bad binding form" error in LISP


I have to write a simple program in Lisp that multiplies a polynomial by some factor. In this example, I want to multiply (x + 5) * 5x. The answer should be 5x^2 + 25x.

When I put in ((1 1) (5 0)) (5 1)) I should get (5 2) (25 1). However, I'm getting various errors ranging from undefined operator TERM in (TERM) and bad binding form. I'm a novice at Lisp and trying to return a list as shown above. Below is my short block of code:

(defun get-coef (term)
  (car term))

(defun get-power (term)
  (cadr term))

(defun make-term (coef power)
  (cons coef power))

(defun poly-eval (poly factor)
  (if (null poly) 0
    (let ((term (car poly))
          (let (coef ((* (get-coef(term)) (get-coef(factor)))))
               (power ((+ (cadr(term)) (cadr(factor)))))
               (make-term (coef power))
               (poly-eval (cdr poly) factor))))))

Any help is appreciated!!


Solution

  • Several problems with your code:

    1. You are using (fun (arg1 arg2)) syntax. It should be (fun arg1 arg2). For example, you write (make-term (coef power)) but it should be (make-term coef power).

    2. Your bindings in let are all over the place. The correct syntax is

      (let ((v1 e1)
            (v2 e2)
            (v3 e3))
        e0)
      

      i.e. all the bindings are in one list, and each binding is a list of two elements. Note that the expressions that the variables are bound to (e1 etc.) are not wrapped in any extra layers of parentheses.

    3. make-term doesn't use the same representation as get-power. In get-power you use cadr so you need to make sure make-term puts the power in the right position.

    4. Your poly-eval doesn't actually combine (make-term coef power) with the recursive call to (poly-eval (cdr poly) factor), so it gets lost. You should cons the "here"-result to the "there"-result.

    5. Your poly-eval returns 0 instead of the empty list for empty polynomials.

    All in all, your code can be fixed as

    (defun get-coef (term)
      (car term))
    
    (defun get-power (term)
      (cadr term))
    
    (defun make-term (coef power)
      (list coef power))
    
    (defun poly-eval (poly factor)
      (if (null poly) nil
        (let ((term (car poly)))
          (let
              ((coef (* (get-coef term) (get-coef factor)))
               (power (+ (get-power term) (get-power factor))))
            (cons (make-term coef power)
                  (poly-eval (cdr poly) factor))))))
    

    giving e.g.

    (poly-eval '((1 1) (5 0)) '(5 1))
    

    resulting in

    ((5 2) (25 1))