<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def roots(expr, types=(ops.PhysicalTable,)):
 """Yield every node of a particular type on which an expression depends. Parameters expr : Expr The expression to analyze types : tuple(type), optional, default (:mod:`ibis.expr.operations.PhysicalTable`,) The node types to traverse Yields ------ table : Expr Unique node types on which an expression depends Notes ----- If your question is: "What nodes of type T does `expr` depend on?", then you've come to the right place. By default, we yield the physical tables that an expression depends on. """

    stack = [
        arg.to_expr()
        for arg in reversed(expr.op().root_tables())
        if isinstance(arg, types)
    ]

    def extender(op):
        return reversed(
            list(
                itertools.chain.from_iterable(
                    arg.op().root_tables()
                    for arg in op.flat_args()
                    if isinstance(arg, types)
                )
            )
        )

    return _search_for_nodes(stack, extender, types)