I have a recursive function which needs to recurse until it finds a certain result. However in the body of my function after my first recursive call I might do some other calculations or possibly recurse again. But, if I recurse and find the result I'm looking for, then I'd like to just stop out of any recursive I've been doing and return that result to avoid doing unnecessary computations.
In a normal recursive call once you get to the "base case" that gets returned to the function that called, then that gets returned to the one that called it, and so on. I'd like to know how to just return to the very first time the function was called, and not have to return something for all those intermediate steps.
For my basic recursion I could write a function like this:
(defun recurse (x)
(if (= x 10)
(return-from recurse x)
(progn (recurse (+ x 1)) (print "Recursed!")))))
(recurse 1)
It has been written to illustrate what I mean about the function running more computations after a recursive call. And, as written this doesn't even return the value I'm interested in since I do some printings after I've returned the value I care about. (Note: The return-from command is extraneous here as I could just write "x" in its place. It's just there to draw parallels for when I try to return to the top level recursion in my second example below.)
Now, if I want to ditch all those extra "Recursed!" printings I could encase everything in a block and then just return to that block instead:
EDIT: Here is a function wrapper for my original example. This example should be clearer now.
(defun recurse-to-top (start)
(block top-level
(labels ((recurse (x)
(if (= x 10)
(return-from top-level x)
(progn (recurse (+ x 1)) (print "Recursed!")))))
(recurse start))))
And running this block keeps going until 10 "is found" and then returns to from the top-level block with no extraneous printing, just like I wanted. But, this seems like a really clunky way to get this feature. I'd like to know if there's a standard or "best" way for getting this type of behavior.
(defun recurse (x) (if (= x 10) x (recurse (+ x 1))))
does just what you want. – Vanmeter