0

I'm a "Nil" or () in Lisp World.
I wanted to get a list of all nodes in edge list and I wrote a code to solve this problem. But I met some unexpected problem.

(Codes from 'Land of Lisp' - chapter 8)

;; Creating edge list

(defun random-node ()
  (1+ (random *node-num*)))    

(defun edge-pair (a b)
  (unless (eql a b)
    (list (cons a b) (cons b a))))

(defun make-edge-list ()
  (apply #'append (loop repeat *edge-num*
                        collect (edge-pair (random-node) (random-node)))))

(defparameter el (make-edge-list))

I wrote a code to extract all node as a list like below.

;; el : list of dotted list
;; I want to extract all the first element from every dotted lists in el.

;; el : ((25 . 6) (6 . 25) (2 . 13) (13 . 2) (25 . 16) (16 . 25) ....)
;; What I want to get: (25 6 2 13 25 16 ... )

(defun extract-nodes (el)
  (let ((nodes nil))
    (labels ((addNode (edgeList)
               (push (caar edgeList) nodes)
               (addNode (cdr edgeList))))
      (addNode el))
    nodes))

I thought that my code was not so bad, but the result showed me a embarrassing error message.

"Stack overflow (deep)" 

Stack overflow? I think that it is caused by the recursive function in my code. How can I fix this properly?

TylerH
  • 19,065
  • 49
  • 65
  • 86
Larynx
  • 337
  • 1
  • 12

1 Answers1

2

Your recursive addNode (better called add-node if you are a lisper) needs a stop condition. E.g.,

         (add-node (edge-list)
           (push (car (pop edge-list)) nodes)
           (when edge-list
             (add-node (cdr edge-list))))

Note that there is no reason to use recursion here, a simple mapcar would do just fine:

(defun extract-nodes (el)
  (mapcar #'car el))
sds
  • 52,616
  • 20
  • 134
  • 226