functional-programminglispcommon-lispclisp

How to fix a stack overflow error in Lisp


I have a code here that is trying to get the sum of all prime numbers below a given number. When I run it, I keep on getting a stack overflow error and nothing more and I can't seem to find where I went wrong.

(format t "Enter your number ~%")

;global variables
(defvar *number* (read))

(defvar *conditional-check* nil)

(defvar *prime* nil)



;sum-of-primes function 
(defun sum-of-primes (x)
    (defvar sum 0)
    (primeCheck x 2)
    (if (equal *prime* 'yes) 
        (progn
            (setf sum (+ sum x))
            (setf z (- x 1))
            (conditional z)
            (if (equal *conditional-check* 'yes) (sum-of-primes z) ()))
        (and (setf z (- x 1)) (sum-of-primes z)))
)


;conitional function
(defun conditional (z)
    (if (>= z 1) (setf *conditional-check* 'yes) (setf *conditional-check* 'no))
)


;prime number check
(defun primeCheck (*number* y)
    (if (and (>= *number* y) (not (= (mod *number* y) 0))) 
        (progn 
            (setf z (+ y 1))
            (primeCheck *number* z)
            (setf *prime* 'yes))
    (setf *prime* 'no))
)

;function call
(sum-of-primes *number*)



Solution

  • sum-of-primes is missing some base condition, which ends recursive calling. That is main problem, but your code is very confusing and contains many useless global variables. You should avoid using global variables and use local variables (created by let or function call). For this example, you don't need any global variables at all.

    (defun sum-of-primes (num)
      (sum-of-primes-help 0 num))
    
    (defun sum-of-primes-help (i num)
      (cond ((= i num) 0)
            ((primep i) (+ i (sum-of-primes-help (+ i 1) num)))
            (t (sum-of-primes-help (+ i 1) num))))
             
    (defun primep (num)
        (primep-help 2 num))
    
    (defun primep-help (i num)
      (cond ((= num 0) nil)
            ((= num 1) nil)
            ((= i num) t)
            ((= 0 (mod num i)) nil)
            (t (primep-help (+ i 1) num))))
    
    (defun program ()
      (format t "Enter your number ~%")
      (format t "Sum of primes is: ~s" 
              (sum-of-primes (read))))
    

    Then you just call (program).