'How to exit a loop in lisp once the function is performed?

I am very beginner in LISP and hope that you can solve my confusion for me. My code is as follow:

(defun retrieve (element closed)
            (if (= (length closed) 0)
             (setf closedlist '(a))
              (dolist (count closed)
              (when (equal element (car count))
               (progn (check (childvalue (symbol-value count)) count) 
               (return)));;;endif
              );;;endouterloop
            )
           )

This is the first function, where it will take in an object called "element", and a list called "closed". The next function is as below:

(defun check (child close)
           (setf tempvalue child)
           (dotimes (count (length tempvalue));;;1st loop
             (setf front (car tempvalue))
             (setf templist close)
             (dotimes (count1 (length close));;;2nd loop
               (if (= (length close) 1) 
                (if (string= front (car templist)) 
                    ((remove (nth count) child) (return));;;true
                    (setf templist (car templist));;;else
                 )
                 (if (string= front (car templist)) 
                    (setf child (remove (nth count child) child))
                    (setf templist (cdr templist));;;else
                   )
                 )
               );;;2nd loop
             (setf tempvalue (cdr tempvalue))
             );;;1stloop
           (format t "child ~S~%" child)
           )

My question is, from the 1st function, when I am inside the first function and if the condition is met, I will call the second function (check). However, after I call the 2nd function (check) from the 1st function (retrieve) and successfully performed the operations, I want to exit the dotimes loop from the 1st function but I can't do it.

If I try to add (return) to it, the program will just exit the loop, without performing other things inside the statement. In this case, (check (childvalue (symbol-value temp)) (nth count closed)).

Could anybody provide any suggestion on how to exit the loop after calling the secondary function? Thanks.



Solution 1:[1]

if has a format (if <condition> <if-true> <if-false>).

You wrote (if <condition> (check ...) (break) ), so the break was in the <if-false> position and went off first time the condition was false. To group multiple statements into one, use progn.

(if (equal element temp)
    (progn (check (childvalue (symbol-value temp)) (nth count closed)) 
           (return)))

Progn doesn't do anything except groups statements together and returns the result of the last one.

You can as well use when instead of if. When works like (when <condition> <if-true>... ). It can have multiple if-trues but no if-false. I think that's perfect for your situation.

Just for completeness, the opposite of when is unless. It has multiple if-falses and no if-true. (unless cond ...) is equivalent to (when (not cond) ...)

SIDE-NOTE: As a side note, put closing parentheses on same line, don't put ) on separate lines. Your editor should indent stuff for you, then just look and navigate yourself by indentation and forget those closing parens. Once you start doing that, the code will seem more clear than many traditional languages.

SECOND-SIDE-NOTE: if you want local variables, use let, or you'd get undeclared variable notices in certain implementation. Example:

(defun check (child close)
  (let ((tempvalue child)
        (front)
        (templist))
    (dotimes (count (length tempvalue))
      (setf front (car tempvalue))
      (setf templist close)
      (dotimes (count1 (length close))
        (if (= (length close) 1) 
            (if (string= front (car templist)) 
                ((remove (nth count) child) (return))
                (setf templist (car templist)))
            (if (string= front (car templist)) 
                (setf child (remove (nth count child) child))
                (setf templist (cdr templist)))))
      (setf tempvalue (cdr tempvalue)))
    (format t "child ~S~%" child)))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1