So I'm, trying to learn lisp, and I figured an easy program to help me learn it is just a program that checks for primes. It worked at first:
(dotimes (i 100)
(let ((devisors 0))
(if (> i 2)
(progn
(dotimes (j (+ (/ i 2) 1))
(if (> j 1)
(if (= (rem i j) 0) (setq devisors 1) )
))
(if (= devisors 0) (print i))
)
)
)
)
I then tried to abstract the prime checking into a function, and wrote this code:
(defun isprime (num)
(defvar devisors 0)
(dotimes (j (+ (/ num 2) 1))
(if (> j 1)
(if (= (rem num j) 0) (setq devisors 1) )
))
(if (= devisors 0) num 0)
)
(dotimes (i 100)
(if (/= (isprime i) 0) (print i))
)
But this one doesn't work. It prints 123 and finishes. The thing is, I tried to just print (print (isprime 5)) and IT WORKS but it doesn't when in the loop.
Why is this? Also keep in mind I'm new to lisp... (I'm using clisp if it helps)
Important note: this code shouldn't work. Documentation for
dotimessays:Imagine that
iis 3. Then the value ofjis5/2, and that isn't an integer.But for some reason, this code works in CLISP. Your error is caused by
defvar- look again into documentation:When you call
isprimewith a new number,devisorsis already set to 1, so it won't reset to 0.Quick fix- replace
(defvar devisors 0)with(let ((devisors 0)) ...insideisprime.I also made some other changes (
zerop,1+andfloor,wheninstead ofifwith only one branch, and also directly returningt(true) ornil(false) instead of some 0 or 1):