title: What is the idiomatic way to implement lazy thunks
body: <p>Assume you have graph structure. The neighbors of a node can be obtained by a costly operation <code>get_neighbor(server, node)</code> (e.g., fetching something from the web) that requires an administrative parameter <code>server</code>. Your task is to find a path from a given start node.</p>
  
  <p>You already have a search routine that is smart enough to compute the neighborhood on demand. But you are not allowed to change that routine's interface, as it is used somewhere else. In particular you cannot inject the administrative parameter:</p>
  
  <pre><code>def search(p, node, todo, graph, visited):
    visited[n] = True
    if p(n): 
      return n
    # Note, we evaluate the neighborship relation on demand
    for n in graph[node]():
        if n not in visited:
            todo.append(n)
    if len(todo) == 0:
      return None
  
    next = todo.pop(0)
    return search(p, next, todo, graph, visited)
  
  </code></pre>
  
  <p>We could use plain thunks (lambdas) to evaluate the neighborhood relation only when needed:</p>
  
  <pre><code>for node in all_nodes():
    tree[node] = (lambda node : lambda : get_neighbor(server, node))(node)
  </code></pre>
  
  <p>(The double lambda is necessary to enforce value capturing.)</p>
  
  <p>This should work fine for a single evaluation of the search, as every costly operation occurs at most once. But for repeated searches across the same graph, the same queries can be repeated. So ideally, the returned lambda should cache its value, i.e., become effectively lazy.</p>
  
  <p>How do I create such a thunk in the most idiomatic way in python, preferrably without additional dependencies?</p>