code: def _create_joint(fwdbwd, func, wrt, input_derivative):
    
    # Correct return to be a non-tuple if there's only one element
    retval = fwdbwd.body[-1]
    if len(retval.value.elts) == 1:
      retval.value = retval.value.elts[0]
  
    # Make a stack init statement
    init_stack = quoting.quote('%s = tangent.Stack()' % fwdbwd.args.args[0].id)
    init_stack = comments.add_comment(init_stack, 'Initialize the tape')
  
    # Prepend the stack init to the top of the function
    fwdbwd.body = [init_stack] + fwdbwd.body
  
    # Replace the function arguments with the original ones
    grad_name = fwdbwd.args.args[1].id
    fwdbwd.args = quoting.parse_function(func).body[0].args
  
    # Give the function a nice name
    fwdbwd.name = naming.joint_name(func, wrt)
  
    # Allow the initial gradient to be passed as a keyword argument
    fwdbwd = ast_.append_args(fwdbwd, [grad_name])
    if input_derivative == INPUT_DERIVATIVE.DefaultOne:
      fwdbwd.args.defaults.append(quoting.quote('1.0'))
    return fwdbwd
docs: Create a user-friendly gradient function.
  
    By default, gradient functions expect the stack to be passed to them
    explicitly. This function modifies the function so that the stack doesn't
    need to be passed and gets initialized in the function body instead.
  
    For consistency, gradient functions always return a tuple, even if the
    gradient of only one input was required. We unpack the tuple if it is of
    length one.
  
    Args:
      fwdbwd: An AST. The function definition of the joint primal and adjoint.
      func: A function handle. The original function that was differentiated.
      wrt: A tuple of integers. The arguments with respect to which we differentiated.
  
    Returns:
      The function definition of the new function.