Text substitution based interpreter: introduction of continuation

Source: Internet
Author: User
Tags eval expression final naming convention

When I wrote here, I was surprised. Environment, storage these comparisons are so familiar, continuation came out first. Wikipedia's translation of continuation is "continuity." The translator always feels a bit Shong and that item is also too unpleasant to look directly at. In short, continuation seems to have no good Chinese translation, as if there is no continuation concept in Chinese computer science.

The concept of continuation is equivalent to the function call stack in procedural languages. It is the data structure that is used to save "things that are not available now, to be dealt with later". This is a bit abstract, for example, the evaluation procedure for a function applying that expression (Call-by-value) is this: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} eval (M \; N) &=& eval (l[x \leftarrow eval (N))) \ && \text{where} eval (M) = \lambda x.l \end{array}\end{equation*} This procedure Do these three things in turn:

1. Calculate $eval (M) $, the result is $\lambda x.l$,
2. Calculate $eval (N) $,
3. Replace $l[x \leftarrow eval (N)]$.
The interpreter can only compute one expression at a time, so when it calculates $eval (M) $, you must first remember the second and third steps to continuation.

Suppose $m$ is still a function call $m= (m_1 \; M_2) $. Then, the calculation of $eval (M) $ is also divided into three steps: First compute $eval (m_1) =\lambda x.l_1$, the second calculates $eval (m_2) $, and the third step replaces $l_1[x \leftarrow eval (m_2)]$. The interpreter can only calculate the $eval (m_1) =\lambda x.l_1$, the second step calculates $eval (m_2) $, and the third step replaces $l_1[x \leftarrow eval (m_2)]$ to continuation. As a result, the continuation things are in the order in which they are to be processed:

1. Compute $eval (m_2) $,
2. Replace $l_1[x \leftarrow eval (m_2)]$.
3. Calculate $eval (N) $,
4. Replace $l[x \leftarrow eval (N)]$.
As you can see, continuation is a filo (advanced out) data structure, which is the stack.

Continuation was not mentioned in the previous interpreter, but the interpreter still works because it explains the interpreter--racket interpreter, which helps us manage the continuation. The goal of this section is to manage continuation yourself.

Starting with a simple recursive function

First, a concept: tail call. Suppose a function called a function call expression $ (f \ n) $, this function call is called the tail call, if this expression is the last evaluated expression in the function body. such as $\lambda N. (f; n) $, and $\lambda N. ({if} \; ({Iszero} \ n) \; 0 \; (f; n)) The $ (f \ n) $ in $ is the tail call. and $\lambda N. (+ \; 1 \; (f; n)) $ (f \ n) in $ is not a tail call because after the $ (f \ n) $ is calculated, an addition is added. A simple way to determine whether a tail call is to see if this invocation expression is not in a parameter position (let expression and if expression is first expanded).

Have learned C or C + + know that the call function is to save information to the function call stack (I learned this in school, I do not know other language classes will speak function call stack). The tail call is characterized by the fact that the tail call does not theoretically need to save the information to the function call stack-it is not actually needed, but some languages do not support it, such as Python. In other words, the tail call does not cause continuation growth. This is very well understood, because the tail call is the final evaluation of the expression, do not need to be left behind to do things (after nothing), so it will not lead to continuation growth. Later, from the continuation point of view, why the tail call does not make continuation grow.

Digression: Just mentioned "theoretically" and "actually". You can often hear this sentence: Theoretically how, unfortunately, in fact, it is. One of them is the negation of "how". I think this is the subconscious of science and the futility of reading, and sometimes it is an excuse to evade responsibility. In theory, it should be. If the conclusion of a set of theories differs from the actual results, then this cannot be called a theory, a maximum conjecture, and a false conjecture.

If a tail call is a recursive call, then it is called tail recursion. tail recursion is also called Iteration . What we're going to do now is to change the non-tail recursion in a recursive program (previously written interpreter) to tail recursion, which is recursive iteration .

To familiarize yourself with the recursive iteration routines, take a simple recursive function to practice practicing. This function is the previous double function: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} double (0) &=& 0 \ Double (n) &=& 2 + double (n-1 ), the procedure for calculating the double function in \text{{\NEQ 0 \end{array}\end{equation*} has a state amount: The currently evaluated expression $double (n) $ or a number $n$ (computed result). Now add another State amount continuation, as $\kappa$ (because continuation the first letter C pronunciation K, so use a long like a K Greek alphabet ... )。 The procedure for calculating the double function is only the second row is a recursive process, and the memo is plus 2. $\kappa$ is defined as: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \kappa &=& {MT} \ &|& \left<\kappa, +2\right> \ end{array}\end{equation*} MT represents an empty continuation, which means there is no subsequent thing.

The evaluation process after adding continuation is as follows: \BEGIN{EQUATION*}\BEGIN{ARRAY}{LCL} \left<double (0), \kappa\right>_v &\ rightarrow_{v}& \left<0, \kappa\right>_c \ \left<double (n), \kappa\right>_v &\rightarrow_{v} & \left<double (M), \left<\kappa, +2\right>\right>_v \ && \text{where} n \neq 0, m = n-1 \ \LEFT&L T;n, \left<\kappa, +2\right>\right>_c &\rightarrow_{c}& \left<m, \kappa\right>_c \ && \text{where} m = n + 2 \ \left<n, {mt}\right>_c &\rightarrow_{c}& \text{output} N \end{array}\end{equation*} is explained below Under The state at the start of the calculation is expressed as $\left<double (n), {mt}\right>_v$. Subscript v indicates that the first state amount is an expression to evaluate for this expression. With the arrow $\rightarrow$ to represent a step, the arrow with the subscript v $\rightarrow_v$ indicates that this step is evaluated for the expression, and the arrow with the subscript C $\rightarrow_c$ indicates that this step takes a memo out of the continuation to execute. For $n \neq 0$,$\left<double (n), \kappa\right>_v$ 's next step is to compute the $double (n-1) $ and add 2 to the $\kappa$, which is $\left< Double (m), \left<\kappa, +2\right>\right>_v$, of which $m=n-1$. When $n = 0$, $double (0) $ evaluates to $0$, so $\left<double (0), \kaPpa\right>_v \rightarrow_{v} \left<0, \kappa\right>_c$. Using subscript c to indicate that the first state is a number, the next step is to remove the memo from the continuation. The last is $\left<n, \kappa\right>_c$ case, if $\kappa$ is not empty: $\kappa=\left<\kappa ', +2\right>$, add 2 to $n$; if $\kappa$ is empty: $\kappa={mt}$, indicating that continuation is OK, and then the expression is also finished, so return the final result of $n$.

Then write the code. Two functions are required for $\rightarrow_v$ and $\rightarrow_c$. The function value-of/k is the $\rightarrow_v$ (the Lisp naming convention generally uses a slash to denote the meaning of with). function Apply-cont is $\rightarrow_c$.

This column more highlights: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/project/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.