docs: def evaluate_impl(expression, params=None):
      '''Implementation of CalculatorImpl::evaluate(), also shared by
      FunctionImpl::call().  In the latter case, `params` are the parameter
      values passed to the function; in the former case, `params` is just an
      empty list.'''
  
      which = expression.which()
  
      if which == 'literal':
          return capnp.Promise(expression.literal)
      elif which == 'previousResult':
          return read_value(expression.previousResult)
      elif which == 'parameter':
          assert expression.parameter < len(params)
          return capnp.Promise(params[expression.parameter])
      elif which == 'call':
          call = expression.call
          func = call.function
  
          # Evaluate each parameter.
          paramPromises = [evaluate_impl(param, params) for param in call.params]
  
          joinedParams = capnp.join_promises(paramPromises)
          # When the parameters are complete, call the function.
          ret = (joinedParams
                 .then(lambda vals: func.call(vals))
                 .then(lambda result: result.value))
  
          return ret
      else:
          raise ValueError("Unknown expression type: " + which)