Search code examples
lispcommon-lisp

Error when trying to set variable on LISP in a BMI problem


It's a simple college problem. I have to get the result using the BMI calc

My code below:

(write-line "BMI CALC")
(defun calc nil
  (prog (w h) ; define p e h as local variables init with nil
      (print "Weight: ")
      (setq w (read))
      (print "Height: ")
      (setq h (read))
      (return (/ w (* h h)))
  )
)

(format t "BMI: ~D~%" (calc))


(setq bmi calc)

(cond 
  ((< bmi 18.5) (print "Under weight"))
  ((< bmi 24.9) (print "Normal weight"))
  ((< bmi 29.9) (print "Overweight"))
  ((< bmi 34.9) (print "Obesity 1"))
  ((< bmi 39.9) (print "Obesity 2"))
  (t (print "Obesity 3"))
)

And I got this result below:

BMI CALC
"Weight: " 78
"Height: " 1.7
BMI: 26.989618
*** - SETQ:variable CALC has no value

I really don't understand why this error.

I expected to print the BMI result, like "Under weight" or "Obesity 1".


Solution

  • What value do you think variable calc has on this line: (setq bmi calc)?

    Because, as that error says, it doesn't have any.

    Also, ending parentheses belong to the same line and you should read about let (a special operator for creating local variables).

    Here is an improved version, which you can test by calling (my-bmi):

    (defun calc ()
      (prog (w h)
        (print "Weight: ")
        (setq w (read *query-io*))
        (print "Height: ")
        (setq h (read *query-io*))
        (return (/ w (* h h)))))
    
    (defun my-bmi ()
      (print "BMI CALC")
      (let ((bmi (calc)))
        (format t "BMI: ~D~%" bmi)
        (print 
         (cond 
          ((< bmi 18.5) "Under weight")
          ((< bmi 24.9) "Normal weight")
          ((< bmi 29.9) "Overweight")
          ((< bmi 34.9) "Obesity 1")
          ((< bmi 39.9) "Obesity 2")
          (t "Obesity 3")))))