docs: def join(self, inner_iterable, outer_key_selector=identity,
               inner_key_selector=identity,
               result_selector=lambda outer, inner: (outer, inner)):
          '''Perform an inner join with a second sequence using selected keys.
  
          The order of elements from outer is maintained. For each of these the
          order of elements from inner is also preserved.
  
          Note: This method uses deferred execution.
  
          Args:
              inner_iterable: The sequence to join with the outer sequence.
  
              outer_key_selector: An optional unary function to extract keys from
                  elements of the outer (source) sequence. The first positional
                  argument of the function should accept outer elements and the
                  result value should be the key. If omitted, the identity
                  function is used.
  
              inner_key_selector: An optional  unary function to extract keys
                  from elements of the inner_iterable. The first positional
                  argument of the function should accept outer elements and the
                  result value should be the key.  If omitted, the identity
                  function is used.
  
              result_selector: An optional binary function to create a result
                  element from two matching elements of the outer and inner. If
                  omitted the result elements will be a 2-tuple pair of the
                  matching outer and inner elements.
  
          Returns:
              A Queryable whose elements are the result of performing an inner-
              join on two sequences.
  
          Raises:
              ValueError: If the Queryable has been closed.
              TypeError: If the inner_iterable is not in fact iterable.
              TypeError: If the outer_key_selector is not callable.
              TypeError: If the inner_key_selector is not callable.
              TypeError: If the result_selector is not callable.
          '''
          if self.closed():
              raise ValueError("Attempt to call join() on a closed Queryable.")
  
          if not is_iterable(inner_iterable):
              raise TypeError("Cannot compute join() with inner_iterable of "
                     "non-iterable {0}".format(str(type(inner_iterable))[7: -1]))
  
          if not is_callable(outer_key_selector):
              raise TypeError("join() parameter outer_key_selector={0} is not "
                              "callable".format(repr(outer_key_selector)))
  
          if not is_callable(inner_key_selector):
              raise TypeError("join() parameter inner_key_selector={0} is not "
                              "callable".format(repr(inner_key_selector)))
  
          if not is_callable(result_selector):
              raise TypeError("join() parameter result_selector={0} is not "
                              "callable".format(repr(result_selector)))
  
          return self._create(self._generate_join_result(inner_iterable, outer_key_selector,
                                                         inner_key_selector, result_selector))