diff categorical/imperative.html @ 2:b4de894a1e2e

initial import
author Robert McIntyre <rlm@mit.edu>
date Fri, 28 Oct 2011 00:03:05 -0700
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/categorical/imperative.html	Fri Oct 28 00:03:05 2011 -0700
     1.3 @@ -0,0 +1,1207 @@
     1.4 +<?xml version="1.0" encoding="utf-8"?>
     1.5 +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     1.6 +               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
     1.7 +<html xmlns="http://www.w3.org/1999/xhtml"
     1.8 +lang="en" xml:lang="en">
     1.9 +<head>
    1.10 +<title>LAMBDA: The Ultimate Imperative</title>
    1.11 +<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    1.12 +<meta name="generator" content="Org-mode"/>
    1.13 +<meta name="generated" content="2011-07-15 02:49:04 EDT"/>
    1.14 +<meta name="author" content="Guy Lewis Steele Jr. and Gerald Jay Sussman"/>
    1.15 +<meta name="description" content=""/>
    1.16 +<meta name="keywords" content=""/>
    1.17 +<style type="text/css">
    1.18 + <!--/*--><![CDATA[/*><!--*/
    1.19 +  html { font-family: Times, serif; font-size: 12pt; }
    1.20 +  .title  { text-align: center; }
    1.21 +  .todo   { color: red; }
    1.22 +  .done   { color: green; }
    1.23 +  .tag    { background-color: #add8e6; font-weight:normal }
    1.24 +  .target { }
    1.25 +  .timestamp { color: #bebebe; }
    1.26 +  .timestamp-kwd { color: #5f9ea0; }
    1.27 +  .right  {margin-left:auto; margin-right:0px;  text-align:right;}
    1.28 +  .left   {margin-left:0px;  margin-right:auto; text-align:left;}
    1.29 +  .center {margin-left:auto; margin-right:auto; text-align:center;}
    1.30 +  p.verse { margin-left: 3% }
    1.31 +  pre {
    1.32 +	border: 1pt solid #AEBDCC;
    1.33 +	background-color: #F3F5F7;
    1.34 +	padding: 5pt;
    1.35 +	font-family: courier, monospace;
    1.36 +        font-size: 90%;
    1.37 +        overflow:auto;
    1.38 +  }
    1.39 +  table { border-collapse: collapse; }
    1.40 +  td, th { vertical-align: top;  }
    1.41 +  th.right  { text-align:center;  }
    1.42 +  th.left   { text-align:center;   }
    1.43 +  th.center { text-align:center; }
    1.44 +  td.right  { text-align:right;  }
    1.45 +  td.left   { text-align:left;   }
    1.46 +  td.center { text-align:center; }
    1.47 +  dt { font-weight: bold; }
    1.48 +  div.figure { padding: 0.5em; }
    1.49 +  div.figure p { text-align: center; }
    1.50 +  textarea { overflow-x: auto; }
    1.51 +  .linenr { font-size:smaller }
    1.52 +  .code-highlighted {background-color:#ffff00;}
    1.53 +  .org-info-js_info-navigation { border-style:none; }
    1.54 +  #org-info-js_console-label { font-size:10px; font-weight:bold;
    1.55 +                               white-space:nowrap; }
    1.56 +  .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
    1.57 +                                 font-weight:bold; }
    1.58 +  /*]]>*/-->
    1.59 +</style>
    1.60 +<script type="text/javascript">
    1.61 +<!--/*--><![CDATA[/*><!--*/
    1.62 + function CodeHighlightOn(elem, id)
    1.63 + {
    1.64 +   var target = document.getElementById(id);
    1.65 +   if(null != target) {
    1.66 +     elem.cacheClassElem = elem.className;
    1.67 +     elem.cacheClassTarget = target.className;
    1.68 +     target.className = "code-highlighted";
    1.69 +     elem.className   = "code-highlighted";
    1.70 +   }
    1.71 + }
    1.72 + function CodeHighlightOff(elem, id)
    1.73 + {
    1.74 +   var target = document.getElementById(id);
    1.75 +   if(elem.cacheClassElem)
    1.76 +     elem.className = elem.cacheClassElem;
    1.77 +   if(elem.cacheClassTarget)
    1.78 +     target.className = elem.cacheClassTarget;
    1.79 + }
    1.80 +/*]]>*///-->
    1.81 +</script>
    1.82 +<script type="text/javascript" src="http://orgmode.org/mathjax/MathJax.js">
    1.83 +<!--/*--><![CDATA[/*><!--*/
    1.84 +    MathJax.Hub.Config({
    1.85 +        // Only one of the two following lines, depending on user settings
    1.86 +        // First allows browser-native MathML display, second forces HTML/CSS
    1.87 +        //  config: ["MMLorHTML.js"], jax: ["input/TeX"],
    1.88 +            jax: ["input/TeX", "output/HTML-CSS"],
    1.89 +        extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js",
    1.90 +                     "TeX/noUndefined.js"],
    1.91 +        tex2jax: {
    1.92 +            inlineMath: [ ["\\(","\\)"] ],
    1.93 +            displayMath: [ ['$$','$$'], ["\\[","\\]"], ["\\begin{displaymath}","\\end{displaymath}"] ],
    1.94 +            skipTags: ["script","noscript","style","textarea","pre","code"],
    1.95 +            ignoreClass: "tex2jax_ignore",
    1.96 +            processEscapes: false,
    1.97 +            processEnvironments: true,
    1.98 +            preview: "TeX"
    1.99 +        },
   1.100 +        showProcessingMessages: true,
   1.101 +        displayAlign: "center",
   1.102 +        displayIndent: "2em",
   1.103 +
   1.104 +        "HTML-CSS": {
   1.105 +             scale: 100,
   1.106 +             availableFonts: ["STIX","TeX"],
   1.107 +             preferredFont: "TeX",
   1.108 +             webFont: "TeX",
   1.109 +             imageFont: "TeX",
   1.110 +             showMathMenu: true,
   1.111 +        },
   1.112 +        MMLorHTML: {
   1.113 +             prefer: {
   1.114 +                 MSIE:    "MML",
   1.115 +                 Firefox: "MML",
   1.116 +                 Opera:   "HTML",
   1.117 +                 other:   "HTML"
   1.118 +             }
   1.119 +        }
   1.120 +    });
   1.121 +/*]]>*///-->
   1.122 +</script>
   1.123 +</head>
   1.124 +<body>
   1.125 +
   1.126 +<div id="content">
   1.127 +
   1.128 +
   1.129 +
   1.130 +<div id="table-of-contents">
   1.131 +<h2>Table of Contents</h2>
   1.132 +<div id="text-table-of-contents">
   1.133 +<ul>
   1.134 +<li><a href="#sec-1">1 Abstract </a></li>
   1.135 +<li><a href="#sec-2">2 Introduction </a>
   1.136 +<ul>
   1.137 +<li><a href="#sec-2-1">2.1 Simple Loops </a>
   1.138 +<ul>
   1.139 +<li><a href="#sec-2-1-1">2.1.1 Simple Recursion </a></li>
   1.140 +<li><a href="#sec-2-1-2">2.1.2 Iteration </a></li>
   1.141 +</ul></li>
   1.142 +</ul>
   1.143 +</li>
   1.144 +<li><a href="#sec-3">3 Imperative Programming </a>
   1.145 +<ul>
   1.146 +<li><a href="#sec-3-1">3.1 Compound Statements </a></li>
   1.147 +<li><a href="#sec-3-2">3.2 2.2. The G0 TO Statement </a></li>
   1.148 +<li><a href="#sec-3-3">3.3 2.3. Simple Assignment </a></li>
   1.149 +<li><a href="#sec-3-4">3.4 Compound Expressions ' </a></li>
   1.150 +</ul>
   1.151 +</li>
   1.152 +<li><a href="#sec-4">4 Continuations </a>
   1.153 +<ul>
   1.154 +<li><a href="#sec-4-1">4.1 Continuation-Passing Recursion </a></li>
   1.155 +<li><a href="#sec-4-2">4.2 Escape Expressions </a></li>
   1.156 +</ul>
   1.157 +</li>
   1.158 +</ul>
   1.159 +</div>
   1.160 +</div>
   1.161 +
   1.162 +<div id="outline-container-1" class="outline-2">
   1.163 +<h2 id="sec-1"><span class="section-number-2">1</span> Abstract </h2>
   1.164 +<div class="outline-text-2" id="text-1">
   1.165 +
   1.166 +
   1.167 +<p>
   1.168 +We demonstrate how to model the following common programming constructs in
   1.169 +terms of an applicative order language similar to LISP:
   1.170 +</p><ul>
   1.171 +<li>Simple Recursion
   1.172 +</li>
   1.173 +<li>Iteration 
   1.174 +</li>
   1.175 +<li>Compound Statements and Expressions
   1.176 +</li>
   1.177 +<li>GO TO and Assignment
   1.178 +</li>
   1.179 +<li>Continuation—Passing
   1.180 +</li>
   1.181 +<li>Escape Expressions
   1.182 +</li>
   1.183 +<li>Fluid Variables
   1.184 +</li>
   1.185 +<li>Call by Name, Call by Need, and Call by Reference
   1.186 +</li>
   1.187 +</ul>
   1.188 +
   1.189 +<p>The models require only (possibly self-referent) lambda application,
   1.190 +conditionals, and (rarely) assignment. No complex data structures such as
   1.191 +stacks are used. The models are transparent, involving only local syntactic
   1.192 +transformations.
   1.193 +Some of these models, such as those for GO TO and assignment, are already well
   1.194 +known, and appear in the work of Landin, Reynolds, and others. The models for
   1.195 +escape expressions, fluid variables, and call by need with side effects are
   1.196 +new. This paper is partly tutorial in intent, gathering all the models
   1.197 +together for purposes of context.
   1.198 +This report describes research done at the Artificial Intelligence Laboratory
   1.199 +of the Massachusetts Institute of Teehnology. Support for the laboratory's
   1.200 +artificial intelligence research is provided in part by the Advanced Research
   1.201 +Projects Agency of the Department of Defense under Office of Naval Research
   1.202 +contract N000l4-75-C-0643.
   1.203 +</p>
   1.204 +</div>
   1.205 +
   1.206 +</div>
   1.207 +
   1.208 +<div id="outline-container-2" class="outline-2">
   1.209 +<h2 id="sec-2"><span class="section-number-2">2</span> Introduction </h2>
   1.210 +<div class="outline-text-2" id="text-2">
   1.211 +
   1.212 +
   1.213 +<p>
   1.214 + We catalogue a number of common programming constructs. For each
   1.215 +construct we examine "typical" usage in well-known programming languages, and
   1.216 +then capture the essence of the semantics of the construct in terms of a
   1.217 +common meta-language.
   1.218 +The lambda calculus {Note Alonzowins} is often used as such a meta-
   1.219 +language. Lambda calculus offers clean semantics, but it is clumsy because it
   1.220 +was designed to be a minimal language rather than a convenient one. All
   1.221 +lambda calculus "functions" must take exactly one "argument"; the only "data
   1.222 +type" is lambda expressions; and the only "primitive operation‘ is variable‘
   1.223 +substitution. While its utter simplicity makes lambda calculus ideal for
   1.224 +logicians, it is too primitive for use by programmers. The meta-language we
   1.225 +use is a programming language called SCHEME {Note Schemepaper) which is based
   1.226 +on lambda calculus.
   1.227 +SCHEME is a dialect of LISP. [McCarthy 62] It is an expression-
   1.228 +oriented, applicative order, interpreter-based language which allows one to
   1.229 +manipulate programs as data. It differs from most current dialects of LISP in
   1.230 +that it closes all lambda expressions in the environment of their definition
   1.231 +or declaration, rather than in the execution environment. {Note Closures}
   1.232 +This preserves the substitution semantics of lambda calculus, and has the
   1.233 +consequence that all variables are lexically scoped, as in ALGOL. [Naur 63]
   1.234 +Another difference is that SCHEME is implemented in such a way that tail-
   1.235 +recursions execute without net growth of the interpreter stack. {Note
   1.236 +Schemenote} We have chosen to use LISP syntax rather than, say, ALGOL syntax
   1.237 +because we want to treat programs as data for the purpose of describing
   1.238 +transformations on the code. LISP supplies names for the parts of an
   1.239 +executable expression and standard operators for constructing expressions and
   1.240 +extracting their components. The use of LISP syntax makes the structure of
   1.241 +such expressions manifest. We use ALGOL as an expository language, because it
   1.242 +is familiar to many people, but ALGOL is not sufficiently powerful to express
   1.243 +the necessary concepts; in particular, it does not allow functions to return
   1.244 +functions as values. we are thus forced to use a dialect of LISP in many
   1.245 +cases.
   1.246 +We will consider various complex programming language constructs and
   1.247 +show how to model them in terms of only a few simple ones. As far as possible
   1.248 +we will use only three control constructs from SCHEME: LAMBDA expressions, as
   1.249 +in LISP, which are Just functions with lexically scoped free variables;
   1.250 +LABELS, which allows declaration of mutually recursive procedures (Note
   1.251 +Labelsdef}; and IF, a primitive conditional expression. For more complex
   1.252 +modelling we will introduce an assignment primitive (ASET).i We will freely
   1.253 +assume the existence of other comon primitives, such as arithmetic functions.
   1.254 +The constructs we will examine are divided into four broad classes.
   1.255 +The first is sfinph?Lo0pl; this contains simple recursions and iterations, and
   1.256 +an introduction to the notion of continuations. The second is hmponflivo
   1.257 +Connrucls; this includes compound statements, G0 T0, and simple variable
   1.258 +assignments. The third is continuations, which encompasses the distinction between statements and expressions, escape operators (such as Landin's J-
   1.259 +operator [Landin 65] and Reynold's escape expression [Reynolds 72]). and fluid
   1.260 +(dynamically bound) variables. The fourth is Parameter Passing Mechanisms, such
   1.261 +as ALGOL call—by-name and FORTRAN call-by-location.
   1.262 +Some of the models presented here are already well-known, particularly
   1.263 +those for G0 T0 and assignment. [McCarthy 60] [Landin 65] [Reynolds 72]
   1.264 +Those for escape operators, fluid variables, and call-by-need with side
   1.265 +effects are new.
   1.266 +</p>
   1.267 +</div>
   1.268 +
   1.269 +<div id="outline-container-2-1" class="outline-3">
   1.270 +<h3 id="sec-2-1"><span class="section-number-3">2.1</span> Simple Loops </h3>
   1.271 +<div class="outline-text-3" id="text-2-1">
   1.272 +
   1.273 +<p>By <i>simple loops</i> we mean constructs which enable programs to execute the
   1.274 +same piece of code repeatedly in a controlled manner. Variables may be made
   1.275 +to take on different values during each repetition, and the number of
   1.276 +repetitions may depend on data given to the program.
   1.277 +</p>
   1.278 +</div>
   1.279 +
   1.280 +<div id="outline-container-2-1-1" class="outline-4">
   1.281 +<h4 id="sec-2-1-1"><span class="section-number-4">2.1.1</span> Simple Recursion </h4>
   1.282 +<div class="outline-text-4" id="text-2-1-1">
   1.283 +
   1.284 +<p>One of the easiest ways to produce a looping control structure is to
   1.285 +use a recursive function, one which calls itself to perform a subcomputation.
   1.286 +For example, the familiar factorial function may be written recursively in
   1.287 +ALGOL: '
   1.288 +</p>
   1.289 +
   1.290 +
   1.291 +<pre class="src src-algol">integer procedure fact(n) value n: integer n:
   1.292 +fact := if n=0 then 1 else n*fact(n-1);
   1.293 +
   1.294 +</pre>
   1.295 +
   1.296 +
   1.297 +
   1.298 +
   1.299 +<p>
   1.300 +The invocation <code>fact(n)</code> computes the product of the integers from 1 to n using
   1.301 +the identity n!=n(n-1)! (n&gt;0). If \(n\) is zero, 1 is returned; otherwise <code>fact</code>:
   1.302 +calls itself recursively to compute \((n-1)!\) , then multiplies the result by \(n\)
   1.303 +and returns it.
   1.304 +</p>
   1.305 +<p>
   1.306 +This same function may be written in Clojure as follows:
   1.307 +</p>
   1.308 +
   1.309 +
   1.310 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">ns</span> categorical.imperative)
   1.311 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact</span>[n]
   1.312 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (<span style="color: #8cd0d3;">=</span> n 0) 1 (<span style="color: #8cd0d3;">*</span> n (fact (<span style="color: #8cd0d3;">dec</span> n))))
   1.313 +)
   1.314 +
   1.315 +</pre>
   1.316 +
   1.317 +
   1.318 +
   1.319 +
   1.320 +
   1.321 +<p>
   1.322 +Clojure does not require an assignment to the ``variable'' fan: to return a value
   1.323 +as ALGOL does. The IF primitive is the ALGOL if-then-else rendered in LISP
   1.324 +syntax. Note that the arithmetic primitives are prefix operators in SCHEME.
   1.325 +</p>
   1.326 +</div>
   1.327 +
   1.328 +</div>
   1.329 +
   1.330 +<div id="outline-container-2-1-2" class="outline-4">
   1.331 +<h4 id="sec-2-1-2"><span class="section-number-4">2.1.2</span> Iteration </h4>
   1.332 +<div class="outline-text-4" id="text-2-1-2">
   1.333 +
   1.334 +<p>There are many other ways to compute factorial. One important way is
   1.335 +through the use of <i>iteration</i>.
   1.336 +A comon iterative construct is the DO loop. The most general form we
   1.337 +have seen in any programming language is the MacLISP DO [Moon 74]. It permits
   1.338 +the simultaneous initialization of any number of control variables and the
   1.339 +simultaneous stepping of these variables by arbitrary functions at each
   1.340 +iteration step. The loop is terminated by an arbitrary predicate, and an
   1.341 +arbitrary value may be returned. The DO loop may have a body, a series of
   1.342 +expressions executed for effect on each iteration. A version of the MacLISP
   1.343 +DO construct has been adopted in SCHEME.
   1.344 +</p>
   1.345 +<p>
   1.346 +The general form of a SCHEME DO is:
   1.347 +</p>
   1.348 +
   1.349 +
   1.350 +<pre class="src src-nothing">(DO ((&lt;var1&gt; (init1&gt; &lt;stepl&gt;)
   1.351 +((var2&gt; &lt;init2&gt; &lt;step2&gt;)
   1.352 +(&lt;varn&gt; &lt;intn&gt; (stepn&gt;))
   1.353 +(&lt;pred&gt; (value&gt;)
   1.354 +(optional body&gt;)
   1.355 +
   1.356 +</pre>
   1.357 +
   1.358 +
   1.359 +
   1.360 +<p>
   1.361 +The semantics of this are that the variables are bound and initialized to the
   1.362 +values of the &lt;initi&gt; expressions, which must all be evaluated in the
   1.363 +environment outside the D0; then the predicate &lt;pred&gt; is evaluated in the new
   1.364 +environment, and if TRUE, the (value) is evaluated and returned. Otherwise
   1.365 +the (optional body) is evaluated, then each of the steppers &lt;stepi&gt; is
   1.366 +evaluated in the current environment, all the variables made to have the
   1.367 +results as their values, the predicate evaluated again, and so on.
   1.368 +Using D0 loops in both ALGOL and SCHEME, we may express FACT by means
   1.369 +of iteration.
   1.370 +</p>
   1.371 +
   1.372 +
   1.373 +<pre class="src src-algol">integer procedure fact(n); value n; integer n:
   1.374 +begin
   1.375 +integer m, ans;
   1.376 +ans := 1;
   1.377 +for m := n step -l until 0 do ans := m*ans;
   1.378 +fact := ans;
   1.379 +end;
   1.380 +
   1.381 +</pre>
   1.382 +
   1.383 +
   1.384 +
   1.385 +
   1.386 +
   1.387 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.388 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact-do</span>[n]
   1.389 +)
   1.390 +
   1.391 +</pre>
   1.392 +
   1.393 +
   1.394 +
   1.395 +
   1.396 +<p>
   1.397 +Note that the SCHEME D0 loop in FACT has no body &ndash; the stepping functions do
   1.398 +all the work. The ALGOL DO loop has an assignment in its body; because an
   1.399 +ALGOL DO loop can step only one variable, we need the assignment to step the
   1.400 +the variable "manually'.
   1.401 +In reality the SCHEME DO construct is not a primitive; it is a macro
   1.402 +which expands into a function which performs the iteration by tail—recursion.
   1.403 +Consider the following definition of FACT in SCHEME. Although it appears to
   1.404 +be recursive, since it "calls itself", it is entirely equivalent to the DO
   1.405 +loop given above, for it is the code that the DO macro expands into! It
   1.406 +captures the essence of our intuitive notion of iteration, because execution
   1.407 +of this program will not produce internal structures (e.g. stacks or variable
   1.408 +bindings) which increase in size with the number of iteration steps.
   1.409 +</p>
   1.410 +
   1.411 +
   1.412 +
   1.413 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.414 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact-do-expand</span>[n]
   1.415 +  (<span style="color: #f0dfaf; font-weight: bold;">let</span> [fact1
   1.416 +        (<span style="color: #8cd0d3;">fn</span>[m ans]
   1.417 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? m) ans
   1.418 +              (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">dec</span> m) (<span style="color: #8cd0d3;">*</span> m ans))))]
   1.419 +    (fact1 n 1)))
   1.420 +
   1.421 +</pre>
   1.422 +
   1.423 +
   1.424 +
   1.425 +
   1.426 +<p>
   1.427 +From this we can infer a general way to express iterations in SCHEME in
   1.428 +a manner isomorphic to the HacLISP D0. The expansion of the general D0 loop
   1.429 +</p>
   1.430 +
   1.431 +
   1.432 +<pre class="src src-nothing">(DO ((&lt;varl&gt; &lt;init1&gt; &lt;step1&gt;)
   1.433 +(&lt;var2&gt; (init2) &lt;step2&gt;)
   1.434 +...
   1.435 +(&lt;varn&gt; &lt;initn&gt; &lt;stepn&gt;))
   1.436 +(&lt;pred&gt; &lt;va1ue&gt;)
   1.437 +&lt;body&gt;)
   1.438 +
   1.439 +</pre>
   1.440 +
   1.441 +
   1.442 +
   1.443 +<p>
   1.444 +is this:
   1.445 +</p>
   1.446 +
   1.447 +
   1.448 +<pre class="src src-nothing">(let [doloop
   1.449 +(fn [dummy &lt;var1&gt; &lt;var2&gt; ... &lt;varn&gt;)
   1.450 +(if &lt;pred&gt; &lt;value&gt;
   1.451 +(recur &lt;body&gt; &lt;step1&gt; &lt;step2&gt; ... &lt;stepn&gt;)))]
   1.452 +
   1.453 +(doloop nil &lt;init1&gt; &lt;init2&gt; ... &lt;initn&gt;))
   1.454 +
   1.455 +</pre>
   1.456 +
   1.457 +
   1.458 +
   1.459 +<p>
   1.460 +The identifiers <code>doloop</code> and <code>dummy</code> are chosen so as not to conflict with any
   1.461 +other identifiers in the program.
   1.462 +Note that, unlike most implementations of D0, there are no side effects
   1.463 +in the steppings of the iteration variables. D0 loops are usually modelled
   1.464 +using assignment statements. For example:
   1.465 +</p>
   1.466 +
   1.467 +
   1.468 +<pre class="src src-nothing">for r :1 0 step b until c do &lt;statement&gt;;
   1.469 +
   1.470 +</pre>
   1.471 +
   1.472 +
   1.473 +
   1.474 +
   1.475 +<p>
   1.476 +can be modelled as follows: [Naur 63]
   1.477 +</p>
   1.478 +
   1.479 +
   1.480 +<pre class="src src-nothing">begin
   1.481 +x := a;
   1.482 +L: if (x-c)*sign(n) &gt; 0 then go to Endloop;
   1.483 +&lt;statement&gt;;
   1.484 +x := x+b;
   1.485 +go to L:
   1.486 +Endloop:
   1.487 +end;
   1.488 +
   1.489 +</pre>
   1.490 +
   1.491 +
   1.492 +
   1.493 +<p>
   1.494 +Later we will see how such assignment statements can in general be
   1.495 +modelled without using side effects.
   1.496 +</p>
   1.497 +</div>
   1.498 +</div>
   1.499 +</div>
   1.500 +
   1.501 +</div>
   1.502 +
   1.503 +<div id="outline-container-3" class="outline-2">
   1.504 +<h2 id="sec-3"><span class="section-number-2">3</span> Imperative Programming </h2>
   1.505 +<div class="outline-text-2" id="text-3">
   1.506 +
   1.507 +<p>Lambda calculus (and related languages, such as ``pure LISP'') is often
   1.508 +used for modelling the applicative constructs of programming languages.
   1.509 +However, they are generally thought of as inappropriate for modelling
   1.510 +imperative constructs. In this section we show how imperative constructs may
   1.511 +be modelled by applicative SCHEME constructs.
   1.512 +</p>
   1.513 +</div>
   1.514 +
   1.515 +<div id="outline-container-3-1" class="outline-3">
   1.516 +<h3 id="sec-3-1"><span class="section-number-3">3.1</span> Compound Statements </h3>
   1.517 +<div class="outline-text-3" id="text-3-1">
   1.518 +
   1.519 +<p>The simplest kind of imperative construct is the statement sequencer,
   1.520 +for example the compound statement in ALGOL:
   1.521 +</p>
   1.522 +
   1.523 +
   1.524 +<pre class="src src-algol">begin
   1.525 +S1;
   1.526 +S2;
   1.527 +end
   1.528 +
   1.529 +</pre>
   1.530 +
   1.531 +
   1.532 +
   1.533 +
   1.534 +<p>
   1.535 +This construct has two interesting properties:
   1.536 +</p><ul>
   1.537 +<li>(1) It performs statement S1 before S2, and so may be used for
   1.538 +  sequencing.
   1.539 +</li>
   1.540 +<li>(2) S1 is useful only for its side effects. (In ALGOL, S2 must also
   1.541 +  be a statement, and so is also useful only for side effects, but
   1.542 +  other languages have compound expressions containing a statement
   1.543 +  followed by an expression.)
   1.544 +</li>
   1.545 +</ul>
   1.546 +
   1.547 +
   1.548 +<p>
   1.549 +The ALGOL compound statement may actually contain any number of statements,
   1.550 +but such statements can be expressed as a series of nested two-statement
   1.551 +compounds. That is:
   1.552 +</p>
   1.553 +
   1.554 +
   1.555 +<pre class="src src-algol">begin
   1.556 +S1;
   1.557 +S2;
   1.558 +...
   1.559 +Sn-1;
   1.560 +Sn;
   1.561 +end
   1.562 +
   1.563 +</pre>
   1.564 +
   1.565 +
   1.566 +
   1.567 +<p>
   1.568 +is equivalent to:
   1.569 +</p>
   1.570 +
   1.571 +
   1.572 +
   1.573 +<pre class="src src-algol">begin
   1.574 +S1;
   1.575 +begin
   1.576 +S2;
   1.577 +begin
   1.578 +...
   1.579 +
   1.580 +begin
   1.581 +Sn-1;
   1.582 +Sn;
   1.583 +end;
   1.584 +end;
   1.585 +end:
   1.586 +end
   1.587 +
   1.588 +</pre>
   1.589 +
   1.590 +
   1.591 +
   1.592 +
   1.593 +<p>
   1.594 +It is not immediately apparent that this sequencing can be expressed in a
   1.595 +purely applicative language. We can, however, take advantage of the implicit
   1.596 +sequencing of applicative order evaluation. Thus, for example, we may write a
   1.597 +two-statement sequence as follows:
   1.598 +</p>
   1.599 +
   1.600 +
   1.601 +
   1.602 +<pre class="src src-clojure">((<span style="color: #8cd0d3;">fn</span>[dummy] S2) S1)
   1.603 +
   1.604 +</pre>
   1.605 +
   1.606 +
   1.607 +
   1.608 +
   1.609 +<p>
   1.610 +where <code>dummy</code> is an identifier not used in S2. From this it is
   1.611 +manifest that the value of S1 is ignored, and so is useful only for
   1.612 +side effects. (Note that we did not claim that S1 is expressed in a
   1.613 +purely applicative language, but only that the sequencing can be so
   1.614 +expressed.) From now on we will use the form <code>(BLOCK S1 S2)</code> as an
   1.615 +abbreviation for this expression, and <code>(BLOCK S1 S2...Sn-1 Sn)</code> as an
   1.616 +abbreviation for 
   1.617 +</p>
   1.618 +
   1.619 +
   1.620 +
   1.621 +<pre class="src src-algol">(BLOCK S1 (BLOCK S2 (BLOCK ... (BLOCK Sn-1 Sn)...))) 
   1.622 +
   1.623 +</pre>
   1.624 +
   1.625 +
   1.626 +
   1.627 +
   1.628 +</div>
   1.629 +
   1.630 +</div>
   1.631 +
   1.632 +<div id="outline-container-3-2" class="outline-3">
   1.633 +<h3 id="sec-3-2"><span class="section-number-3">3.2</span> 2.2. The G0 TO Statement </h3>
   1.634 +<div class="outline-text-3" id="text-3-2">
   1.635 +
   1.636 +
   1.637 +<p>
   1.638 +A more general imperative structure is the compound statement with
   1.639 +labels and G0 T0s. Consider the following code fragment due to
   1.640 +Jacopini, taken from Knuth: [Knuth 74] 
   1.641 +</p>
   1.642 +
   1.643 +
   1.644 +<pre class="src src-algol">begin 
   1.645 +L1: if B1 then go to L2; S1;
   1.646 +    if B2 then go to L2; S2;
   1.647 +    go to L1;
   1.648 +L2: S3;
   1.649 +
   1.650 +</pre>
   1.651 +
   1.652 +
   1.653 +
   1.654 +
   1.655 +<p>
   1.656 +It is perhaps surprising that this piece of code can be <i>syntactically</i>
   1.657 +transformed into a purely applicative style. For example, in SCHEME we
   1.658 +could write:
   1.659 +</p>
   1.660 +
   1.661 +
   1.662 +
   1.663 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.664 +(<span style="color: #f0dfaf; font-weight: bold;">let</span>
   1.665 +    [L1 (<span style="color: #8cd0d3;">fn</span>[]
   1.666 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> B1 (L2) (<span style="color: #f0dfaf; font-weight: bold;">do</span> S1
   1.667 +                          (<span style="color: #f0dfaf; font-weight: bold;">if</span> B2 (L2) (<span style="color: #f0dfaf; font-weight: bold;">do</span> S2 (L1))))))
   1.668 +     L2 (<span style="color: #8cd0d3;">fn</span>[] S3)]
   1.669 +  (L1))
   1.670 +
   1.671 +</pre>
   1.672 +
   1.673 +
   1.674 +
   1.675 +
   1.676 +<p>
   1.677 +As with the D0 loop, this transformation depends critically on SCHEME's
   1.678 +treatment of tail-recursion and on lexical scoping of variables. The labels
   1.679 +are names of functions of no arguments. In order to ‘go to" the labeled code,
   1.680 +we merely call the function named by that label.
   1.681 +</p>
   1.682 +</div>
   1.683 +
   1.684 +</div>
   1.685 +
   1.686 +<div id="outline-container-3-3" class="outline-3">
   1.687 +<h3 id="sec-3-3"><span class="section-number-3">3.3</span> 2.3. Simple Assignment </h3>
   1.688 +<div class="outline-text-3" id="text-3-3">
   1.689 +
   1.690 +<p>Of course, all this sequencing of statements is useless unless the
   1.691 +statements have side effects. An important side effect is assignment. For
   1.692 +example, one often uses assignment to place intermediate results in a named
   1.693 +location (i.e. a variable) so that they may be used more than once later
   1.694 +without recomputing them:
   1.695 +</p>
   1.696 +
   1.697 +
   1.698 +
   1.699 +<pre class="src src-algol">begin
   1.700 +real a2, sqrtdisc;
   1.701 +a2 := 2*a;
   1.702 +sqrtdisc := sqrt(b^2 - 4*a*c);
   1.703 +root1 := (- b + sqrtdisc) / a2;
   1.704 +root2 := (- b - sqrtdisc) / a2;
   1.705 +print(root1);
   1.706 +print(root2);
   1.707 +print(root1 + root2);
   1.708 +end
   1.709 +
   1.710 +</pre>
   1.711 +
   1.712 +
   1.713 +
   1.714 +
   1.715 +<p>
   1.716 +It is well known that such naming of intermediate results may be accomplished
   1.717 +by calling a function and binding the formal parameter variables to the
   1.718 +results: 
   1.719 +</p>
   1.720 +
   1.721 +
   1.722 +
   1.723 +<pre class="src src-clojure">(<span style="color: #8cd0d3;">fn</span> [a2 sqrtdisc]
   1.724 +  ((<span style="color: #8cd0d3;">fn</span>[root1 root2]
   1.725 +    (<span style="color: #f0dfaf; font-weight: bold;">do</span> (<span style="color: #8cd0d3;">println</span> root1)
   1.726 +        (<span style="color: #8cd0d3;">println</span> root2)
   1.727 +        (<span style="color: #8cd0d3;">println</span> (<span style="color: #8cd0d3;">+</span> root1 root2))))
   1.728 +  (<span style="color: #8cd0d3;">/</span> (<span style="color: #8cd0d3;">+</span> (<span style="color: #8cd0d3;">-</span> b) sqrtdisc) a2)
   1.729 +  (<span style="color: #8cd0d3;">/</span> (<span style="color: #8cd0d3;">-</span> (<span style="color: #8cd0d3;">-</span> b) sqrtdisc) a2))
   1.730 +
   1.731 +  (<span style="color: #8cd0d3;">*</span> 2 a)
   1.732 +  (sqrt (<span style="color: #8cd0d3;">-</span> (<span style="color: #8cd0d3;">*</span> b b) (<span style="color: #8cd0d3;">*</span> 4 a c))))
   1.733 +
   1.734 +</pre>
   1.735 +
   1.736 +
   1.737 +
   1.738 +<p>
   1.739 +This technique can be extended to handle all simple variable assignments which
   1.740 +appear as statements in blocks, even if arbitrary G0 T0 statements also appear
   1.741 +in such blocks. {Note Mccarthywins}
   1.742 +</p>
   1.743 +<p>
   1.744 +For example, here is a program which uses G0 TO statements in the form
   1.745 +presented before; it determines the parity of a non-negative integer by
   1.746 +counting it down until it reaches zero.
   1.747 +</p>
   1.748 +
   1.749 +
   1.750 +
   1.751 +<pre class="src src-algol">begin
   1.752 +L1: if a = 0 then begin parity := 0; go to L2; end;
   1.753 +    a := a - 1;
   1.754 +    if a = 0 then begin parity := 1; go to L2; end;
   1.755 +    a := a - 1;
   1.756 +    go to L1;
   1.757 +L2: print(parity);
   1.758 +
   1.759 +</pre>
   1.760 +
   1.761 +
   1.762 +
   1.763 +
   1.764 +<p>
   1.765 +This can be expressed in SCHEME:
   1.766 +</p>
   1.767 +
   1.768 +
   1.769 +
   1.770 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">let</span>
   1.771 +    [L1 (<span style="color: #8cd0d3;">fn</span> [a parity]
   1.772 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? a) (L2 a 0)
   1.773 +              (L3 (<span style="color: #8cd0d3;">dec</span> a) parity)))
   1.774 +     L3 (<span style="color: #8cd0d3;">fn</span> [a parity]
   1.775 +          (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? a) (L2 a 1)
   1.776 +              (L1 (<span style="color: #8cd0d3;">dec</span> a) parity)))
   1.777 +     L2 (<span style="color: #8cd0d3;">fn</span> [a parity]
   1.778 +          (<span style="color: #8cd0d3;">println</span> parity))]
   1.779 +  (L1 a parity))
   1.780 +
   1.781 +</pre>
   1.782 +
   1.783 +
   1.784 +
   1.785 +
   1.786 +<p>
   1.787 +The trick is to pass the set of variables which may be altered as arguments to
   1.788 +the label functions. {Note Flowgraph} It may be necessary to introduce new
   1.789 +labels (such as L3) so that an assignment may be transformed into the binding
   1.790 +for a function call. At worst, one may need as many labels as there are
   1.791 +statements (not counting the eliminated assignment and GO TO statements).
   1.792 +</p>
   1.793 +</div>
   1.794 +
   1.795 +</div>
   1.796 +
   1.797 +<div id="outline-container-3-4" class="outline-3">
   1.798 +<h3 id="sec-3-4"><span class="section-number-3">3.4</span> Compound Expressions ' </h3>
   1.799 +<div class="outline-text-3" id="text-3-4">
   1.800 +
   1.801 +<p>At this point we are almost in a position to model the most general
   1.802 +form of compound statement. In LISP, this is called the 'PROG feature". In
   1.803 +addition to statement sequencing and G0 T0 statements, one can return a <i>value</i>
   1.804 +from a PROG by using the RETURN statement.
   1.805 +</p>
   1.806 +<p>
   1.807 +Let us first consider the simplest compound statement, which in SCHEME
   1.808 +we call BLOCK. Recall that
   1.809 +<code>(BLOCK s1 sz)</code> is defined to be <code>((lambda (dummy) s2) s1)</code>
   1.810 +</p>
   1.811 +<p>
   1.812 +Notice that this not only performs Sl before S2, but also returns the value of
   1.813 +S2. Furthermore, we defined <code>(BLOCK S1 S2 ... Sn)</code> so that it returns the value
   1.814 +of <code>Sn</code>. Thus BLOCK may be used as a compound expression, and models a LISP
   1.815 +PROGN, which is a PROG with no G0 T0 statements and an implicit RETURN of the
   1.816 +last ``statement'' (really an expression).
   1.817 +</p>
   1.818 +<p>
   1.819 +Host LISP compilers compile D0 expressions by macro-expansion. We have
   1.820 +already seen one way to do this in SCHEME using only variable binding. A more
   1.821 +common technique is to expand the D0 into a PROG, using variable assignments
   1.822 +instead of bindings. Thus the iterative factorial program:
   1.823 +</p>
   1.824 +
   1.825 +
   1.826 +
   1.827 +<pre class="src src-clojure">(oarxnz FACT .
   1.828 +(LAMaoA (n) .
   1.829 +(D0 ((M N (<span style="color: #8cd0d3;">-</span> H 1))
   1.830 +(Ans 1 (<span style="color: #8cd0d3;">*</span> M Ans)))
   1.831 +((<span style="color: #8cd0d3;">-</span> H 0) A<span style="color: #cc9393;">"$))))</span>
   1.832 +
   1.833 +</pre>
   1.834 +
   1.835 +
   1.836 +
   1.837 +
   1.838 +<p>
   1.839 +would expand into:
   1.840 +</p>
   1.841 +
   1.842 +
   1.843 +
   1.844 +<pre class="src src-clojure">(DEFINE FACT
   1.845 +. (LAMeoA (M)
   1.846 +(PRO6 (M Ans)
   1.847 +(sszro M n
   1.848 +Ans 1) ~
   1.849 +LP (tr (<span style="color: #8cd0d3;">-</span> M 0) (RETURN Ans))
   1.850 +(ssero M (<span style="color: #8cd0d3;">-</span> n 1)
   1.851 +Ans (' M Ans))
   1.852 +(60 LP))))
   1.853 +
   1.854 +</pre>
   1.855 +
   1.856 +
   1.857 +
   1.858 +
   1.859 +<p>
   1.860 +where SSETQ is a simultaneous multiple assignment operator. (SSETQ is not a
   1.861 +SCHEME (or LISP) primitive. It can be defined in terms of a single assignment
   1.862 +operator, but we are more interested here in RETURN than in simultaneous
   1.863 +assignment. The SSETQ's will all be removed anyway and modelled by lambda
   1.864 +binding.) We can apply the same technique we used before to eliminate G0 T0
   1.865 +statements and assignments from compound statements:
   1.866 +</p>
   1.867 +
   1.868 +
   1.869 +
   1.870 +<pre class="src src-clojure">(DEFINE FACT
   1.871 +(LAHBOA (I)
   1.872 +(LABELS ((L1 (LAManA (M Ans)
   1.873 +(LP n 1)))
   1.874 +(LP (LAMaoA (M Ans)
   1.875 +(IF (<span style="color: #8cd0d3;">-</span> M o) (nztunn Ans)
   1.876 +(&#163;2 H An$))))
   1.877 +(L2 (LAMaoA (M An )
   1.878 +(LP (<span style="color: #8cd0d3;">-</span> <span style="color: #cc9393;">" 1) (' H &#64258;N$)))))</span>
   1.879 +<span style="color: #e37170; background-color: #332323;">(</span><span style="color: #cc9393;">L1 NIL NlL))))</span>
   1.880 +
   1.881 +</pre>
   1.882 +
   1.883 +
   1.884 +<p>
   1.885 + clojure
   1.886 +</p>
   1.887 +<p>
   1.888 +We still haven't done anything about RETURN. Let's see&hellip;
   1.889 +</p><ul>
   1.890 +<li>==&gt; the value of (FACT 0) is the value of (Ll NIL NIL)
   1.891 +</li>
   1.892 +<li>==&gt; which is the value of (LP 0 1)
   1.893 +</li>
   1.894 +<li>==&gt; which is the value of (IF (= 0 0) (RETURN 1) (L2 0 1))
   1.895 +</li>
   1.896 +<li>==&gt; which is the value of (RETURN 1) 
   1.897 +</li>
   1.898 +</ul>
   1.899 +
   1.900 +
   1.901 +<p>
   1.902 +Notice that if RETURN were the <i>identity function</i> (LAMBDA (X) X), we would get the right answer. This is in fact a
   1.903 +general truth: if we Just replace a call to RETURN with its argument, then
   1.904 +our old transformation on compound statements extends to general compound
   1.905 +expressions, i.e. PROG.
   1.906 +</p>
   1.907 +</div>
   1.908 +</div>
   1.909 +
   1.910 +</div>
   1.911 +
   1.912 +<div id="outline-container-4" class="outline-2">
   1.913 +<h2 id="sec-4"><span class="section-number-2">4</span> Continuations </h2>
   1.914 +<div class="outline-text-2" id="text-4">
   1.915 +
   1.916 +<p>Up to now we have thought of SCHEME's LAMBDA expressions as functions,
   1.917 +and of a combination such as <code>(G (F X Y))</code> as meaning ``apply the function F to
   1.918 +the values of X and Y, and return a value so that the function G can be
   1.919 +applied and return a value &hellip;'' But notice that we have seldom used LAMBDA
   1.920 +expressions as functions. Rather, we have used them as control structures and
   1.921 +environment modifiers. For example, consider the expression:
   1.922 +<code>(BLOCK (PRINT 3) (PRINT 4))</code>
   1.923 +</p>
   1.924 +<p>
   1.925 +This is defined to be an abbreviation for:
   1.926 +<code>((LAMBDA  (DUMMY) (PRINT 4)) (PRINT 3))</code>
   1.927 +</p>
   1.928 +<p>
   1.929 +We do not care about the value of this BLOCK expression; it follows that we
   1.930 +do not care about the value of the <code>(LAMBDA (DUMMY) ...)</code>. We are not using
   1.931 +LAMBDA as a function at all.
   1.932 +</p>
   1.933 +<p>
   1.934 +It is possible to write useful programs in terms of LAHBDA expressions
   1.935 +in which we never care about the value of <i>any</i> lambda expression. We have
   1.936 +already demonstrated how one could represent any "FORTRAN" program in these
   1.937 +terms: all one needs is PROG (with G0 and SETQ), and PRINT to get the answers
   1.938 +out. The ultimate generalization of this imperative programing style is
   1.939 +<i>continuation-passing</i>. (Note Churchwins} .
   1.940 +</p>
   1.941 +
   1.942 +</div>
   1.943 +
   1.944 +<div id="outline-container-4-1" class="outline-3">
   1.945 +<h3 id="sec-4-1"><span class="section-number-3">4.1</span> Continuation-Passing Recursion </h3>
   1.946 +<div class="outline-text-3" id="text-4-1">
   1.947 +
   1.948 +<p>Consider the following alternative definition of FACT. It has an extra
   1.949 +argument, the continuation, which is a function to call with the answer, when
   1.950 +we have it, rather than return a value
   1.951 +</p>
   1.952 +
   1.953 +
   1.954 +
   1.955 +<pre class="src src-algol.">procedure Inc!(n, c); value n, c;
   1.956 +integer n: procedure c(integer value);
   1.957 +if n-=0 then c(l) else
   1.958 +begin
   1.959 +procedure l(!mp(d) value a: integer a;
   1.960 +c(mm);
   1.961 +Iacl(n-1, romp):
   1.962 +end;
   1.963 +
   1.964 +</pre>
   1.965 +
   1.966 +
   1.967 +
   1.968 +
   1.969 +
   1.970 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
   1.971 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">fact-cps</span>[n k]
   1.972 +  (<span style="color: #f0dfaf; font-weight: bold;">if</span> (zero? n) (k 1)
   1.973 +      (<span style="color: #f0dfaf; font-weight: bold;">recur</span> (<span style="color: #8cd0d3;">dec</span> n) (<span style="color: #8cd0d3;">fn</span>[a] (k (<span style="color: #8cd0d3;">*</span> n a))))))
   1.974 +
   1.975 +</pre>
   1.976 +
   1.977 +
   1.978 +<p>
   1.979 + clojure
   1.980 +It is fairly clumsy to use this version of‘ FACT in ALGOL; it is necessary to
   1.981 +do something like this:
   1.982 +</p>
   1.983 +
   1.984 +
   1.985 +
   1.986 +<pre class="src src-algol">begin
   1.987 +integer ann
   1.988 +procedure :emp(x); value 2:; integer x;
   1.989 +ans :1 x;
   1.990 +]'act(3. temp);
   1.991 +comment Now the variable <span style="color: #cc9393;">"am"</span> has 6;
   1.992 +end;
   1.993 +
   1.994 +</pre>
   1.995 +
   1.996 +
   1.997 +
   1.998 +
   1.999 +<p>
  1.1000 +Procedure <code>fact</code> does not return a value, nor does <code>temp</code>; we must use a side
  1.1001 +effect to get the answer out.
  1.1002 +</p>
  1.1003 +<p>
  1.1004 +<code>FACT</code> is somewhat easier to use in SCHEME. We can call it like an
  1.1005 +ordinary function in SCHEME if we supply an identity function as the second
  1.1006 +argument. For example, <code>(FACT 3 (LAMBDA (X) X))</code> returns 6. Alternatively, we
  1.1007 +could write <code>(FACT 3 (LAHBDA (X) (PRINT X)))</code>; we do not care about the value
  1.1008 +of this, but about what gets printed. A third way to use the value is to
  1.1009 +write
  1.1010 +<code>(FACT 3 (LAMBDA (x) (SQRT x)))</code>
  1.1011 +instead of
  1.1012 +<code>(SQRT (FACT 3 (LAMBDA (x) x)))</code>
  1.1013 +</p>
  1.1014 +<p>
  1.1015 +In either of these cases we care about the value of the continuation given to
  1.1016 +FACT. Thus we care about the value of FACT if and only if we care about the
  1.1017 +value of its continuation!
  1.1018 +</p>
  1.1019 +<p>
  1.1020 +We can redefine other functions to take continuations in the same way.
  1.1021 +For example, suppose we had arithmetic primitives which took continuations; to
  1.1022 +prevent confusion, call the version of "+" which takes a continuation '++",
  1.1023 +etc. Instead of writing
  1.1024 +<code>(- (+ B Z)(* 4 A C))</code>
  1.1025 +we can write
  1.1026 +</p>
  1.1027 +
  1.1028 +
  1.1029 +<pre class="src src-clojure">(<span style="color: #f0dfaf; font-weight: bold;">in-ns</span> 'categorical.imperative)
  1.1030 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">enable-continuation</span> <span style="color: #8fb28f;">"Makes f take a continuation as an additional argument."</span>[f]
  1.1031 +  (<span style="color: #8cd0d3;">fn</span>[&amp; args] ((<span style="color: #8cd0d3;">fn</span>[k] (k (<span style="color: #8cd0d3;">apply</span> f (<span style="color: #8cd0d3;">reverse</span> (<span style="color: #8cd0d3;">rest</span> (<span style="color: #8cd0d3;">reverse</span> args)))))) (<span style="color: #8cd0d3;">last</span> args)) ))
  1.1032 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">+&amp;</span> (enable-continuation +))
  1.1033 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">*&amp;</span> (enable-continuation *))
  1.1034 +(<span style="color: #f0dfaf; font-weight: bold;">def</span> <span style="color: #f0dfaf;">-&amp;</span> (enable-continuation -))
  1.1035 +
  1.1036 +
  1.1037 +(<span style="color: #f0dfaf; font-weight: bold;">defn</span> <span style="color: #f0dfaf;">quadratic</span>[a b c k]
  1.1038 +(*&amp; b b
  1.1039 +    (<span style="color: #8cd0d3;">fn</span>[x] (*&amp; 4 a c
  1.1040 +               (<span style="color: #8cd0d3;">fn</span>[y]
  1.1041 +                 (-&amp; x y k))))))
  1.1042 +
  1.1043 +</pre>
  1.1044 +
  1.1045 +
  1.1046 +
  1.1047 +
  1.1048 +<p>
  1.1049 +where <code>k</code> is the continuation for the entire expression.
  1.1050 +</p>
  1.1051 +<p>
  1.1052 +This is an obscure way to write an algebraic expression, and we would
  1.1053 +not advise writing code this way in general, but continuation-passing brings
  1.1054 +out certain important features of the computation:
  1.1055 +</p><ul>
  1.1056 +<li><sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup> The operations to be performed appear in the order in which they are
  1.1057 +</li>
  1.1058 +</ul>
  1.1059 +
  1.1060 +<p>performed. In fact, they <i>must</i> be performed in this
  1.1061 +order. Continuation- passing removes the need for the rule about
  1.1062 +left-to-right argument evaluation{Note Evalorder)
  1.1063 +</p><ul>
  1.1064 +<li><sup><a class="footref" name="fnr.2" href="#fn.2">2</a></sup> In the usual applicative expression there are two implicit
  1.1065 +  temporary values: those of <code>(* B B)</code> and <code>(* 4 A C)</code>. The first of
  1.1066 +  these values must be preserved over the computation of the second,
  1.1067 +  whereas the second is used as soon as it is produced. These facts
  1.1068 +  are <i>manifest</i> in the appearance and use of the variable X and Y in
  1.1069 +  the continuation-passing version.  
  1.1070 +</li>
  1.1071 +</ul>
  1.1072 +
  1.1073 +
  1.1074 +<p>
  1.1075 +In short, the continuation-passing version specifies <i>exactly</i> and
  1.1076 +  explicitly what steps are necessary to compute the value of the
  1.1077 +  expression.  One can think of conventional functional application
  1.1078 +  for value as being an abbreviation for the more explicit
  1.1079 +  continuation-passing style. Alternatively, one can think of the
  1.1080 +  interpreter as supplying to each function an implicit default
  1.1081 +  continuation of one argument. This continuation will receive the
  1.1082 +  value of the function as its argument, and then carry on the
  1.1083 +  computation. In an interpreter this implicit continuation is
  1.1084 +  represented by the control stack mechanism for function returns.
  1.1085 +  Now consider what computational steps are implied by: 
  1.1086 +</p>
  1.1087 +<p>
  1.1088 +<code>(LAMBDA (A B C ...) (F X Y Z ...))</code> when we "apply" the LAMBDA
  1.1089 +  expression we have some values to apply it to; we let the names A,
  1.1090 +  B, C &hellip; refer to these values. We then determine the values of X,
  1.1091 +  Y, Z &hellip; and pass these values (along with "the buck",
  1.1092 +  i.e. control!) to the lambda expression F (F is either a lambda
  1.1093 +  expression or a name for one).  Passing control to F is an
  1.1094 +  unconditional transfer. (Note Jrsthack) {Note Hewitthack) Note that
  1.1095 +  we want values from X, Y, Z, &hellip; If these are simple expressions,
  1.1096 +  such as variables, constants, or LAMBDA expressions, the evaluation
  1.1097 +  process is trivial, in that no temporary storage is required. In
  1.1098 +  pure continuation-passing style, all evaluations are trivial: no
  1.1099 +  combination is nested within another, and therefore no ‘hidden
  1.1100 +  temporaries" are required.  But if X is a combination, say (G P Q),
  1.1101 +  then we want to think of G as a function, because we want a value
  1.1102 +  from it, and we will need an implicit temporary place to keep the
  1.1103 +  result while evaluating Y and Z. (An interpreter usually keeps these
  1.1104 +  temporary places in the control stack!) On the other hand, we do not
  1.1105 +  necessarily need a value from F. This is what we mean by tail-
  1.1106 +  recursion: F is called tail-recursively, whereas G is not. A better
  1.1107 +  name for tail-recursion would be "tail-transfer", since no real
  1.1108 +  recursion is implied.  This is why we have made such a fuss about
  1.1109 +  tail-recursion: it can be used for transfer of control without
  1.1110 +  making any commitment about whether the expression expected to
  1.1111 +  return a value. Thus it can be used to model statement-like control
  1.1112 +  structures. Put another way, tail—recursion does not require a
  1.1113 +  control stack as nested recursion does. In our models of iteration
  1.1114 +  and imperative style all the LAMBDA expressions used for control (to
  1.1115 +  simulate GO statements, for example) are called in tail-recursive
  1.1116 +  fashion.
  1.1117 +</p>
  1.1118 +</div>
  1.1119 +
  1.1120 +</div>
  1.1121 +
  1.1122 +<div id="outline-container-4-2" class="outline-3">
  1.1123 +<h3 id="sec-4-2"><span class="section-number-3">4.2</span> Escape Expressions </h3>
  1.1124 +<div class="outline-text-3" id="text-4-2">
  1.1125 +
  1.1126 +<p>Reynolds [Reynolds 72] defines the construction
  1.1127 += escape x in r =
  1.1128 +</p>
  1.1129 +<p>
  1.1130 +to evaluate the expression \(r\) in an environment such that the variable \(x\) is
  1.1131 +bound to an escape function. If the escape function is never applied, then
  1.1132 +the value of the escape expression is the value of \(r\). If the escape function
  1.1133 +is applied to an argument \(a\), however, then evaluation of \(r\) is aborted and the
  1.1134 +escape expression returns \(a\). {Note J-operator} (Reynolds points out that
  1.1135 +this definition is not quite accurate, since the escape function may be called
  1.1136 +even after the escape expression has returned a value; if this happens, it
  1.1137 +“returns again"!)
  1.1138 +</p>
  1.1139 +<p>
  1.1140 +As an example of the use of an escape expression, consider this
  1.1141 +procedure to compute the harmonic mean of an array of numbers. If any of the
  1.1142 +numbers is zero, we want the answer to be zero. We have a function hannaunl
  1.1143 +which will sum the reciprocals of numbers in an array, or call an escape
  1.1144 +function with zero if any of the numbers is zero. (The implementation shown
  1.1145 +here is awkward because ALGOL requires that a function return its value by
  1.1146 +assignment.)
  1.1147 +</p>
  1.1148 +
  1.1149 +
  1.1150 +<pre class="src src-algol">begin
  1.1151 +real procedure Imrmsum(a, n. escfun)&#167; p
  1.1152 +real array at integer n; real procedure esciun(real);
  1.1153 +begin
  1.1154 +real sum;
  1.1155 +sum := 0;
  1.1156 +for i :1 0 until n-l do
  1.1157 +begin
  1.1158 +if a[i]=0 then cscfun(0);
  1.1159 +sum :1 sum &#162; I/a[i];
  1.1160 +enm
  1.1161 +harmsum SI sum;
  1.1162 +end: .
  1.1163 +real array b[0:99]:
  1.1164 +print(escape x in I00/hm-m.mm(b, 100, x));
  1.1165 +end
  1.1166 +
  1.1167 +</pre>
  1.1168 +
  1.1169 +
  1.1170 +
  1.1171 +
  1.1172 +<p>
  1.1173 +If harmsum exits normally, the number of elements is divided by the sum and
  1.1174 +printed. Otherwise, zero is returned from the escape expression and printed
  1.1175 +without the division ever occurring.
  1.1176 +This program can be written in SCHEME using the built-in escape
  1.1177 +operator <code>CATCH</code>:
  1.1178 +</p>
  1.1179 +
  1.1180 +
  1.1181 +
  1.1182 +<pre class="src src-clojure">abc
  1.1183 +
  1.1184 +</pre>
  1.1185 +
  1.1186 +
  1.1187 +
  1.1188 +<div id="footnotes">
  1.1189 +<h2 class="footnotes">Footnotes: </h2>
  1.1190 +<div id="text-footnotes">
  1.1191 +<p class="footnote"><sup><a class="footnum" name="fn.1" href="#fnr.1">1</a></sup> DEFINITION NOT FOUND: 1
  1.1192 +</p>
  1.1193 +
  1.1194 +<p class="footnote"><sup><a class="footnum" name="fn.2" href="#fnr.2">2</a></sup> DEFINITION NOT FOUND: 2
  1.1195 +</p>
  1.1196 +</div>
  1.1197 +</div>
  1.1198 +</div>
  1.1199 +
  1.1200 +</div>
  1.1201 +</div>
  1.1202 +<div id="postamble">
  1.1203 +<p class="date">Date: 2011-07-15 02:49:04 EDT</p>
  1.1204 +<p class="author">Author: Guy Lewis Steele Jr. and Gerald Jay Sussman</p>
  1.1205 +<p class="creator">Org version 7.6 with Emacs version 23</p>
  1.1206 +<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
  1.1207 +</div>
  1.1208 +</div>
  1.1209 +</body>
  1.1210 +</html>