code: def join(self, other, join_type="inner"):
          
          return self._transform(transformations.join_t(other, join_type))
docs: Sequence and other must be composed of (Key, Value) pairs. If self.sequence contains (K, V)
          pairs and other contains (K, W) pairs, the return result is a sequence of (K, (V, W)) pairs.
          If join_type is "left", V values will always be present, W values may be present or None.
          If join_type is "right", W values will always be present, W values may be present or None.
          If join_type is "outer", V or W may be present or None,
          but never at the same time.
  
          >>> seq([('a', 1), ('b', 2), ('c', 3)]).join([('a', 2), ('c', 5)], "inner")
          [('a', (1, 2)), ('c', (3, 5))]
  
          >>> seq([('a', 1), ('b', 2), ('c', 3)]).join([('a', 2), ('c', 5)])
          [('a', (1, 2)), ('c', (3, 5))]
  
          >>> seq([('a', 1), ('b', 2)]).join([('a', 3), ('c', 4)], "left")
          [('a', (1, 3)), ('b', (2, None)]
  
          >>> seq([('a', 1), ('b', 2)]).join([('a', 3), ('c', 4)], "right")
          [('a', (1, 3)), ('c', (None, 4)]
  
          >>> seq([('a', 1), ('b', 2)]).join([('a', 3), ('c', 4)], "outer")
          [('a', (1, 3)), ('b', (2, None)), ('c', (None, 4))]
  
          :param other: sequence to join with
          :param join_type: specifies join_type, may be "left", "right", or "outer"
          :return: side joined sequence of (K, (V, W)) pairs