Ask a Jedi: Dealing with Recursion

This question came in today and I just had to answer it quickly: (Sorry to the 200 other people who have email in my queue!)

How do I return a value from a recursive function? This does not seem to work in cf. I'm basically walking up a hierarchy returning needed items when I find them.

Luckily s/he sent the code. The problem will probably jump out as soon as you see it:

<cffunction name="recursive" returntype="struct"> <cfargument name="id" type="numeric" required="yes" /> <cfset var stThing = structnew() />

&lt;!--- do some lookup based on id ---&gt;
&lt;cfif lookup succesful&gt;
	&lt;cfreturn stThing /&gt;
&lt;cfelse&gt;
	&lt;!--- get parent id ---&gt;
	&lt;cfset recursive(parentid) /&gt;
&lt;/cfif&gt;

</cffunction> </code>

Let’s trace this line by line to see where the error occurs.

  1. The first thing we do is create stThing as a new structure.
  2. Then we do a look up. This is the part of the code that is assumed.
  3. If the look up was successful, we return the value.
  4. If not.... and here comes the important part - we call the method again, but notice we don't set a value. Whenever you do, cfset foo(), which is allowed, you are basically running a function and ignoring the result. </ol> So basically his code does call itself recursively, but each time the result gets "lost" in the ether and isn't returned to the user. If he changed the cfset to: <cfreturn recursive(parentid)> It should work correctly. Recursion is like sushi - you need to be very careful when preparing it or the end result is crap (or even better, a server that loops until it crashes).
Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Comments