def dfs(node, predicate):
    """
    Returns the first node in the tree such that ``predicate(node)`` is True, searching depth-first left-to-right.

    :param node: The root node of the tree.
    :type node: d20.ast.ChildMixin
    :param predicate: A predicate function.
    :type predicate: typing.Callable[[d20.ast.ChildMixin], bool]
    :rtype: d20.ast.ChildMixin
    """
    if predicate(node):
        return node

    for child in node.children:
        result = dfs(child, predicate)
        if result is not None:
            return result

    return None