title: Why is this Groovy closure not returning the value that I expect?
body: <p>In a Grails application, I am trying to prevent the creation of cycles in a directed graph. The user is able to assign a parent to a node, but no node should be its own parent's ancestor. I have written a simple setup function that calls checkLineageForTarget, which is the recursive function that does the heavy lifting:</p>
  
  <pre><code>boolean checkLineageForTarget(Integer target, Collection&lt;Node&gt;stillToProcess){
  // true means that this is a safe addition
  // false means that this addition creates a cycle
  
      boolean retVal = stillToProcess.each {
          Collection&lt;Node&gt; itsParents = getParentNodes(it)
  
          if (it.id == target){
              println("found a loop on " + target);
              return false; // loop detected!
          }
          if (itsParents.empty){ return true; } // end of the line
  
          return checkLineageForTarget(target, itsParents)
      }
  
      // at this point, retVal is always true, even when the "found a loop [...]" condition is met
      return retVal;
  }
  </code></pre>
  
  <p>This "works," in that it prints the "found a loop [...]" message, but outside of the closure, retVal is true, the calling function attempts to add the new parent/child relationship, and my stack runneth over.</p>
  
  <p>What is my misunderstanding?</p>