code: def pipe(self, f, *args, **kwargs):
          
          if isinstance(f, tuple):
              f, data_keyword = f
              kwargs = kwargs.copy()
              kwargs[data_keyword] = self
              return f(*args, **kwargs)
          else:
              return f(self, *args, **kwargs)
docs: Generic composition function to enable expression pipelining.
  
          Parameters
          ----------
          f : function or (function, arg_name) tuple
            If the expression needs to be passed as anything other than the first
            argument to the function, pass a tuple with the argument name. For
            example, (f, 'data') if the function f expects a 'data' keyword
          args : positional arguments
          kwargs : keyword arguments
  
          Examples
          --------
          >>> import ibis
          >>> t = ibis.table([('a', 'int64'), ('b', 'string')], name='t')
          >>> f = lambda a: (a + 1).name('a')
          >>> g = lambda a: (a * 2).name('a')
          >>> result1 = t.a.pipe(f).pipe(g)
          >>> result1  # doctest: +NORMALIZE_WHITESPACE
          ref_0
          UnboundTable[table]
            name: t
            schema:
              a : int64
              b : string
          a = Multiply[int64*]
            left:
              a = Add[int64*]
                left:
                  a = Column[int64*] 'a' from table
                    ref_0
                right:
                  Literal[int8]
                    1
            right:
              Literal[int8]
                2
          >>> result2 = g(f(t.a))  # equivalent to the above
          >>> result1.equals(result2)
          True
  
          Returns
          -------
          result : result type of passed function