# Is there a name for this technique of simplifying recursion code by passing some logic from the caller to the callee?

The technique involves moving some logic from the caller to the callee. Usually the logic that is moved is a check. Here's an example of the technique applied to code that solves the "Construct BST (Binary Search Tree) from the Preorder Traversal Values" problem leetcode link:

``````INF = float('inf')

class Solution:
def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]:
def pre(i, lo, hi):
val = preorder[i]
left = right = None
if i+1 < N and lo < preorder[i+1] < val:
left, i = pre(i+1, lo, val)
if i+1 < N and val < preorder[i+1] < hi:
right, i = pre(i+1, val, hi)
node = TreeNode(val, left, right)
return node, i
N = len(preorder)
root, _ = pre(0, -INF, INF)
return root
``````

Then we move the check from the caller to the callee, which simplifies the code somewhat:

``````INF = float('inf')

class Solution:
def bstFromPreorder(self, preorder: List[int]) -> Optional[TreeNode]:
def pre(i, lo, hi):
if i == N or not lo < preorder[i] < hi:
return None, i-1
val = preorder[i]
left, i = pre(i+1, lo, val)
right, i = pre(i+1, val, hi)
node = TreeNode(val, left, right)
return node, i
N = len(preorder)
root, _ = pre(0, -INF, INF)
return root
``````

Depending on the problem/code and the snippets being moved around, the simplification can be significant.

• please don't cross-post: stackoverflow.com/questions/69590507/… "Cross-posting is frowned upon as it leads to fragmented answers splattered all over the network..."
– gnat
Oct 15 at 21:50
• @gnat he was told to ask here Oct 15 at 22:08
• @gnat Thanks. As db said, someone from S/O said this was a better place to post this particular question, so I did. I've since deleted this question from S/O, so it's no longer a cross-post. For future reference, is there a way to move a question from one stackexchange site to another? Oct 15 at 23:09

While I'm not immediately convinced that these two are 100% equivalent, I would call this reverse inlining.

A goal of inlining is to eliminate function call overhead, while also making contextual improvements; for example, sometimes an argument is a constant and inlining can capitalize on such arguments in the context of the inlined expansion.

We can partially inline functions that call other functions to a significant level of depth, but at each level, the code typically gets harder to understand — fortunately, in many cases, we can let compilers to that work and not even look at the resulting code.  In the case of direct recursion, inlining code such as this would have an effect to move such checks from callee to caller, in part to prevent the additional recursive call from being made when checks fail.

If we do the reverse: move some of the code from caller to callee, we are in some sense doing opposite of inlining — and indeed, often the code becomes clearer or simpler!