def wrap_func_output(f):

    """
    Transforms a Python function into an expression that can return
    the result of 'f', but generally as a Semi_formal_expr object
    (unless its evaluation does not involve variables [Semi_formal_var
    objects], in which case 'f' simply returns its usual result).
    """
    
    def f_with_expr_output(*args):
        
        #! The following does not seem to go into the expression returned
        # by wrap_func_output().  Why?
        """
        Version of %s(...) that returns a semi-formal expression
        (Semi_formal_expr object), if its result depends on variables
        (Semi_formal_var objects).  The new version returns a simple
        constant, when applied to constant arguments.
        
        Original documentation:
        %s
        """ % (f.__name__, f.__doc__)
        
        # Coercion of all arguments to semi-formal expressions:
        sub_exprs = map(to_func, args)

        # We keep track of all Semi_formal_var leaves:
        variables = set()
        for sub_expr in sub_exprs:
            variables |= sub_expr._variables

        # Formal version of 'f': its value can be calculated through
        # the specificaton of the values of the variables used in the
        # arguments 'args'.
        def f_evaluation():
            """
            Returns the value of function 'f', calculated at the
            nominal values of its arguments sub_exprs.
            """
            return f(*(sub_expr.nominal_value for sub_expr in sub_exprs))

        if variables:
            # Delayed evaluation:
            return Semi_formal_expr_node(f_evaluation, variables)
        else:
            # Constant functions do not have to be complicated
            # objects:
            return f_evaluation()

    return f_with_expr_output

    Transforms a Python function into an expression that can return
    the result of 'f', but generally as a Semi_formal_expr object
    (unless its evaluation does not involve variables [Semi_formal_var
    objects], in which case 'f' simply returns its usual result).
    
recipes/Python/576721_Calculations_error_propagatisemiformal/recipe-576721.py