What is tail call optimization?

前端 未结 10 1268
一整个雨季
一整个雨季 2020-11-21 06:36

Very simply, what is tail-call optimization?

More specifically, what are some small code snippets where it could be applied, and where not, with an explanation of wh

10条回答
  •  不知归路
    2020-11-21 07:06

    In a functional language, tail call optimization is as if a function call could return a partially evaluated expression as the result, which would then be evaluated by the caller.

    f x = g x
    

    f 6 reduces to g 6. So if the implementation could return g 6 as the result, and then call that expression it would save a stack frame.

    Also

    f x = if c x then g x else h x.
    

    Reduces to f 6 to either g 6 or h 6. So if the implementation evaluates c 6 and finds it is true then it can reduce,

    if true then g x else h x ---> g x
    
    f x ---> h x
    

    A simple non tail call optimization interpreter might look like this,

    class simple_expresion
    {
        ...
    public:
        virtual ximple_value *DoEvaluate() const = 0;
    };
    
    class simple_value
    {
        ...
    };
    
    class simple_function : public simple_expresion
    {
        ...
    private:
        simple_expresion *m_Function;
        simple_expresion *m_Parameter;
    
    public:
        virtual simple_value *DoEvaluate() const
        {
            vector parameterList;
            parameterList->push_back(m_Parameter);
            return m_Function->Call(parameterList);
        }
    };
    
    class simple_if : public simple_function
    {
    private:
        simple_expresion *m_Condition;
        simple_expresion *m_Positive;
        simple_expresion *m_Negative;
    
    public:
        simple_value *DoEvaluate() const
        {
            if (m_Condition.DoEvaluate()->IsTrue())
            {
                return m_Positive.DoEvaluate();
            }
            else
            {
                return m_Negative.DoEvaluate();
            }
        }
    }
    

    A tail call optimization interpreter might look like this,

    class tco_expresion
    {
        ...
    public:
        virtual tco_expresion *DoEvaluate() const = 0;
        virtual bool IsValue()
        {
            return false;
        }
    };
    
    class tco_value
    {
        ...
    public:
        virtual bool IsValue()
        {
            return true;
        }
    };
    
    class tco_function : public tco_expresion
    {
        ...
    private:
        tco_expresion *m_Function;
        tco_expresion *m_Parameter;
    
    public:
        virtual tco_expression *DoEvaluate() const
        {
            vector< tco_expression *> parameterList;
            tco_expression *function = const_cast(this);
            while (!function->IsValue())
            {
                function = function->DoCall(parameterList);
            }
            return function;
        }
    
        tco_expresion *DoCall(vector &p_ParameterList)
        {
            p_ParameterList.push_back(m_Parameter);
            return m_Function;
        }
    };
    
    class tco_if : public tco_function
    {
    private:
        tco_expresion *m_Condition;
        tco_expresion *m_Positive;
        tco_expresion *m_Negative;
    
        tco_expresion *DoEvaluate() const
        {
            if (m_Condition.DoEvaluate()->IsTrue())
            {
                return m_Positive;
            }
            else
            {
                return m_Negative;
            }
        }
    }
    

提交回复
热议问题