Sharmaine Cstll
Sharmaine Cstll

Reputation: 65

If condition with and operator

How to use IF condition with AND operator? I'm getting an error

(princ"Enter a year: ")
(defvar y(read))
(defun leap-year(y)
    (if(and(= 0(mod y 400)(= 0(mod y 4))
       (print"Is a leap year"))
       (print"Is not"))))

(leap-year y)

Upvotes: 0

Views: 195

Answers (2)

Rainer Joswig
Rainer Joswig

Reputation: 139381

Note that your code should ideally look like this:

(princ "Enter a year: ")
(finish-output)             ; make sure that output is done

(defvar *year*              ; use the usual naming convention for
                            ;  global variables.
  (let ((*read-eval* nil))  ; don't run code during reading
    (read)))

(defun leap-year-p (y)
  ; your implementation here
  ; return a truth value
  )

(print (if (leap-year-p *year*) "yes" "no"))

Alternatively it also is a good idea to not work on the top-level with function calls and global variables. Write procedures/functions for everything. That way your code automatically is more modular, testable and reusable.

(defun prompt-for-year ()
  (princ "Enter a year: ")
  (finish-output)
  (let ((*read-eval* nil))
    (read)))

(defun leap-year-p (y)
  ; your implementation here
  ; return a truth value
  )

(defun check-leap-year ()
  (print (if (leap-year-p (prompt-for-year))
             "yes"
           "no")))

(check-leap-year)

Upvotes: 3

Renzo
Renzo

Reputation: 27434

How often happens in lisp languages, the problem is in missing (or extra) parentheses.

In your case you have multiple parentheses issues in the definition of the function, which should be:

(defun leap-year (y)
  (if (and (= 0 (mod y 400)) (= 0(mod y 4)))
      (print "Is a leap year")
      (print "Is not")))

A good discipline on expression alignments and a good program editor like for instance Emacs are in fact very important (I would say “essential”) in programming in these languages.

Note that if you use the function in a REPL, you could omit the print:

(defun leap-year (y)
  (if (and (= 0 (mod y 400)) (= 0(mod y 4)))
      "Is a leap year"
      "Is not"))

Finally, note that the check for a leap year is incorrect. A correct definition could be the following:

(defun leap-year (y)
  (cond ((/= 0 (mod y 4)) "no")
        ((/= 0 (mod y 100)) "yes")
        ((/= 0 (mod y 400)) "no")
        (t "yes")))

or, with the if:

(defun leap-year (y)
  (if (or (and (zerop (mod y 4))
               (not (zerop (mod y 100))))
          (zerop (mod y 400)))
      "yes"
      "no"))

Upvotes: 3

Related Questions