Checking for even and odd values in a loop with Lisp

Viewed 525

I do not understand why the following lisp program displays 15 lines of output as opposed to 10:

(defparameter x 1)
(dotimes (x 10)
  (if (oddp x)
    (format t "x is odd~%"))
    (format t "x is even~%"))

I am using CLISP 2.49 on a Windows 10 machine.

2 Answers

In addition to the accepted answer, note that with an auto-indenting editor (e.g. with Emacs) those kinds of mistakes can be spotted easily. Your code auto-indents as follows:

(dotimes (x 10)
  (if (oddp x)
      (format t "x is odd~%"))
  (format t "x is even~%"))

The if and second format expressions are aligned vertically (they are siblings in the tree rooted at dotimes) whereas you want the second format to happen only when the test fails, at the same depth as the first one.

Remark

You can also factor some code:

(format t 
        (if (oddp x) 
          "x is odd~%" 
          "x is even~%"))

Or even:

(format t
        "x is ~:[even~;odd~]~%" 
        (oddp x))

The above relies on conditional formatting.

Current:

(if (oddp x)
    (format t "x is odd~%"))    ; <- extra parenthesis
    (format t "x is even~%"))

Wanted:

(if (oddp x)
    (format t "x is odd~%")
    (format t "x is even~%"))

You are escaping the if form before the else statement so the else statement gets always printed while the if statement gets printed 5 times.

Related