CaitlinG
CaitlinG

Reputation: 2015

Checking for even and odd values in a loop with Lisp

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.

Upvotes: 4

Views: 770

Answers (2)

coredump
coredump

Reputation: 38799

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.

Upvotes: 7

claasic
claasic

Reputation: 1050

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.

Upvotes: 6

Related Questions