This is a simple LISP program to read in three sides of a triangle and report what kind of triangle it is (or isn't).  Any feedback would be much appreciated.(defun read-side (side) (format t Enter a value for side ~d: ~% side) (read))(defun is-a-triangle (a b c) (if (and (< a (+ b c)) (< b (+ a c)) (< c (+ a b))) t nil))(defun is-equilateral (a b c) (if (and (= a b c)) t nil))(defun is-isoceles (a b c) (if (or (= a b) (= b c)) t nil))(defun is-right-triangle (a b c)   (let ((square-of-short-sides-sum 0) (short-sides ()) (large-side 0) (sides (list a b c)))     (loop for p in sides do       (if (> p large-side)         (progn (if (/= 0 large-side) (setq short-sides (append short-sides (list large-side))))         (setq large-side p))        (setq short-sides (append short-sides (list p)))))    (format t short-sides: ~a ~% short-sides)    (format t large-side: ~a ~% large-side)    (loop for p in short-sides do       (setq square-of-short-sides-sum (+ square-of-short-sides-sum (expt p 2))))    (if (= (expt large-side 2) square-of-short-sides-sum) t nil)))(defun status-message (message a b c) (format t The shape ~d,~d,~d ~a ~% a b c message))(let ((a (read-side 1)) (b (read-side 2)) (c (read-side 3)))  (status-message is being checked... a b c)  (if (is-equilateral a b c) (status-message is an equilateral triangle. a b c)      (if (is-a-triangle a b c)        (progn (if (is-isoceles a b c) (status-message is an isoceles triangle. a b c)            (if (is-right-triangle a b c) (status-message is a right triangle. a b c)                (status-message is a non-isoceles, non-equilateral, non-right triangle. a b c))))        (status-message is not a triangle. a b c))))Thanks to the previous commenters for your suggestions.  I have since modified the code based on the feedback I have received and am posting the revised code below.  If you have any further feedback on this new revision, it is welcome.  Thank you!(defun read-side (side) (format t Enter a value for side ~d: ~% side) (read))(defun triangle-p (a b c) (and (< a (+ b c)) (< b (+ a c)) (< c (+ a b))))(defun equilateral-p (a b c) (= a b c))(defun isoceles-p (a b c) (or (= a b) (= b c)))(defun right-triangle-p (a b c)   (destructuring-bind (long-side &rest short-sides) (sort (list a b c) #'>)    (= (expt long-side 2) (+ (expt (first short-sides) 2) (expt (second short-sides) 2)))))(defun status-message (message a b c) (format t The shape ~d,~d,~d ~a ~% a b c message))(defun classify-triangle (a b c)  (cond ((not (triangle-p a b c)))    ((right-triangle-p a b c) 'right)    ((equilateral-p a b c) 'equilateral)    ((isoceles-p a b c) 'isoceles)    (t 'triangle)))(let (triangle-type (a (read-side 1)) (b (read-side 2)) (c (read-side 3)))  (format t classify triangle says ~a ~% (classify-triangle a b c))  (setq triangle-type (classify-triangle a b c))  (cond ((eq 'right triangle-type) (status-message is a right triangle. a b c))    ((eq 'equilateral triangle-type) (status-message is an equilateral triangle. a b c))    ((eq 'isoceles triangle-type) (status-message is an isoceles triangle. a b c))    ((eq 'triangle triangle-type) (status-message is a non-right, non-isoceles, non-equilateral triangle. a b c))    (t (status-message is not a triangle. a b c))))Here is the latest revision:(defun read-side (side) (format t Enter a value for side ~d: ~% side) (read))(defun triangle-p (a b c) (and (< a (+ b c)) (< b (+ a c)) (< c (+ a b))))(defun equilateral-p (a b c) (= a b c))(defun isoceles-p (a b c) (or (= a b) (= b c)))(defun right-triangle-p (a b c)   (destructuring-bind (long-side &rest short-sides) (sort (list a b c) #'>)    (= (expt long-side 2) (+ (expt (first short-sides) 2) (expt (second short-sides) 2)))))(defun status-message (message a b c) (format t The shape ~d,~d,~d ~a ~% a b c message))(defun classify-triangle (a b c)  (cond ((not (triangle-p a b c)))    ((right-triangle-p a b c) 'right)    ((equilateral-p a b c) 'equilateral)    ((isoceles-p a b c) 'isoceles)    (t 'triangle)))(let* ((a (read-side 1)) (b (read-side 2)) (c (read-side 3)) (triangle-type (classify-triangle a b c)))  (format t classify triangle says ~a ~% triangle-type)  (cond ((eq 'right triangle-type) (status-message is a right triangle. a b c))    ((eq 'equilateral triangle-type) (status-message is an equilateral triangle. a b c))    ((eq 'isoceles triangle-type) (status-message is an isoceles triangle. a b c))    ((eq 'triangle triangle-type) (status-message is a non-right, non-isoceles, non-equilateral triangle. a b c))    (t (status-message is not a triangle. a b c))))After reading through your suggestion on my sorting question and then reading up on 'format', I tried to write a format statement to simplify the logic at the bottom of the code.  I couldn't figure out how to do a format conditional based on a symbol, so instead I defined the triangle types as global variables with 'defineparameter' (is there a better way to define constants?).  I also used the format loop which you described in your response to the my-sort-3 question to shorten the expression. The new code is as follows:(defparameter *right* 0)(defparameter *equilateral* 1)(defparameter *isoceles* 2)(defparameter *triangle* 3)(defparameter *non-triangle* 4)(defun read-side (side) (format t Enter a value for side ~d: ~% side) (read))(defun triangle-p (a b c) (and (< a (+ b c)) (< b (+ a c)) (< c (+ a b))))(defun equilateral-p (a b c) (= a b c))(defun isoceles-p (a b c) (or (= a b) (= b c) (= a c)))(defun right-triangle-p (a b c)   (destructuring-bind (long-side &rest short-sides) (sort (list a b c) #'>)    (= (expt long-side 2) (+ (expt (first short-sides) 2) (expt (second short-sides) 2)))))(defun status-message (message a b c) (format t The shape ~d,~d,~d ~a ~% a b c message))(defun classify-triangle (a b c)  (cond ((not (triangle-p a b c)) *non-triangle*)    ((right-triangle-p a b c) *right*)    ((equilateral-p a b c) *equilateral*)    ((isoceles-p a b c) *isoceles*)    (t *triangle*)))(let* ((a (read-side 1)) (b (read-side 2)) (c (read-side 3)) (triangle-type (classify-triangle a b c)))  (format t classify triangle says ~a ~% triangle-type)  (format t The shape (~{~d~^,  ~}) is ~[a right~;an equilateral~;an isoceles~;a non-right, non-isoceles, non-equilateral~;not a~] triangle. (list a b c) triangle-type))Thanks, everyone, for your continued feedback.  Here is the latest revision.(defun read-side (side) (format t Enter a value for side ~d: ~% side) (read))(defun triangle-p (a b c) (and (< a (+ b c)) (< b (+ a c)) (< c (+ a b))))(defun equilateral-p (a b c) (= a b c))(defun isoceles-p (a b c) (or (= a b) (= b c)))(defun right-triangle-p (a b c)     (destructuring-bind (long-side short-side-1 short-side-2) (sort (list a b c) #'>)          (= (expt long-side 2) (+ (expt short-side-1 2) (expt short-side-2 2)))))(defun status-message (message a b c) (format t The shape ~d,~d,~d ~a ~% a b c message))(defun classify-triangle (a b c)    (cond ((not (triangle-p a b c)) nil)          ((right-triangle-p a b c) 'right)              ((equilateral-p a b c) 'equilateral)              ((isoceles-p a b c) 'isoceles)                  (t 'triangle)))(let* ((a (read-side 1)) (b (read-side 2)) (c (read-side 3))     (triangle-type (classify-triangle a b c))    (article (if (member triangle-type '(isoceles equilateral)) an a))    (tri-name (if (eq triangle-type 'triangle) non-right, non-isoceles, non-equilateral triangle-type)))    (format t The shape (~d, ~d, ~d) is ~:[not a triangle~;~a ~(~a~) triangle~]. a b c triangle-type article tri-name))
Determine type of triangle in LISP
lisp;common lisp
Much better.You seem to like assignment a bit more than I do, though. You can rewrite that last let as(let* ((a (read-side 1)) (b (read-side 2)) (c (read-side 3)) (triangle-type (classify-triangle a b c)))  (format t classify triangle says ~a ~% triangle-type)  (cond ((eq 'right triangle-type) (status-message is a right triangle. a b c))        ((eq 'equilateral triangle-type) (status-message is an equilateral triangle. a b c))        ((eq 'isoceles triangle-type) (status-message is an isoceles triangle. a b c))        ((eq 'triangle triangle-type) (status-message is a non-right, non-isoceles, non-equilateral triangle. a b c))        (t (status-message is not a triangle. a b c))))let* is basically let, except that its arguments are guaranteed to be evaluated in the given order (which means that later bindings can refer to previous ones from the same let* statement). It's good style to use let where you can, but let* is better than creating a temporary nil binding and setqing it later.