diff --git a/sicp-pocket.pdf b/sicp-pocket.pdf index 1ea3fab..91b129a 100644 Binary files a/sicp-pocket.pdf and b/sicp-pocket.pdf differ diff --git a/src/sicp-pocket.texi b/src/sicp-pocket.texi index afafdf5..bc3dfed 100644 --- a/src/sicp-pocket.texi +++ b/src/sicp-pocket.texi @@ -9,8 +9,8 @@ @settitle Structure and Interpretation of Computer Programs, 2e @comment Unofficial Texinfo Format @comment -@set utfversion 2.andresraba4 -@set utfversiondate November 23, 2012 +@set utfversion 2.andresraba4.1 +@set utfversiondate August 27, 2013 @comment @comment This file is licensed under a Creative Commons @comment Attribution-ShareAlike 3.0 Unported License @@ -50,7 +50,7 @@ @comment Pedro Kr@"oger patch to add missing Lisp example. @comment @comment * Version 2.neilvandyke4 (January 10, 2007) by Neil W. Van Dyke -@comment Brad Walker patch to add @t{@@dircategory} and @t{@@direntry}. +@comment Brad Walker patch to add @code{@@dircategory} and @code{@@direntry}. @comment @comment * Version 2.andresraba1 (May 23, 2011) by Andres Raba. @comment Mathematics typeset in TeX, figures redrawn in vector graphics, @@ -232,7 +232,7 @@ Procedures and the Processes They Generate Formulating Abstractions with Higher-Order Procedures * 1-3-1:: Procedures as Arguments -* 1-3-2:: Constructing Procedures Using @t{Lambda} +* 1-3-2:: Constructing Procedures Using @code{Lambda} * 1-3-3:: Procedures as General Methods * 1-3-4:: Procedures as Returned Values @@ -347,7 +347,7 @@ Variations on a Scheme -- Nondeterministic Computing * 4-3-1:: Amb and Search * 4-3-2:: Examples of Nondeterministic Programs -* 4-3-3:: Implementing the @t{Amb} Evaluator +* 4-3-3:: Implementing the @code{Amb} Evaluator Logic Programming @@ -446,14 +446,14 @@ figures have suffered an amateurish resurrection of the lost art of were introduced during the conversion of some of the copious superscripts (`^') and subscripts (`_'). Divining @emph{which} has been left as an exercise to the reader. But at least we don't put our brave astronauts at risk by encoding -the @emph{greater-than-or-equal} symbol as @t{>}.} +the @emph{greater-than-or-equal} symbol as @code{>}.} @i{If you modify @file{sicp.texi} to correct errors or improve the -@acronym{ASCII} art, then update the @t{@@set utfversion @value{utfversion}} +@acronym{ASCII} art, then update the @code{@@set utfversion @value{utfversion}} line to reflect your delta. For example, if you started with Lytha's version -@t{1}, and your name is Bob, then you could name your successive versions -@t{1.bob1}, @t{1.bob2}, @dots{} @t{1.bob@i{n}}. Also update -@t{utfversiondate}. If you want to distribute your version on the Web, then +@code{1}, and your name is Bob, then you could name your successive versions +@code{1.bob1}, @code{1.bob2}, @dots{} @code{1.bob@i{n}}. Also update +@code{utfversiondate}. If you want to distribute your version on the Web, then embedding the string ``sicp.texi'' somewhere in the file or Web page will make it easier for people to find with Web search engines.} @@ -940,7 +940,7 @@ Katzenelson, Hardy Mayer, Jim Miller, and especially Brian Harvey, who did unto this book as Julie did unto his book @cite{Simply Scheme}. Finally, we would like to acknowledge the support of the organizations that -have encouraged this work over the years, including suppport from +have encouraged this work over the years, including support from Hewlett-Packard, made possible by Ira Goldstein and Joel Birnbaum, and support from @acronym{DARPA}, made possible by Bob Kahn. @@ -1190,7 +1190,7 @@ characters.} @noindent Expressions representing numbers may be combined with an expression -representing a primitive procedure (such as @t{+} or @t{*}) to form a +representing a primitive procedure (such as @code{+} or @code{*}) to form a compound expression that represents the application of the procedure to those numbers. For @w{example}: @@ -1291,7 +1291,7 @@ A critical aspect of a programming language is the means it provides for using names to refer to computational objects. We say that the name identifies a @newterm{variable} whose @newterm{value} is the object. -In the Scheme dialect of Lisp, we name things with @t{define}. Typing +In the Scheme dialect of Lisp, we name things with @code{define}. Typing @lisp (define size 2) @@ -1299,9 +1299,9 @@ In the Scheme dialect of Lisp, we name things with @t{define}. Typing @noindent causes the interpreter to associate the value 2 with the name -@t{size}.@footnote{In this book, we do not show the interpreter's response +@code{size}.@footnote{In this book, we do not show the interpreter's response to evaluating definitions, since this is highly implementation-dependent.} Once -the name @t{size} has been associated with the number 2, we can refer to the +the name @code{size} has been associated with the number 2, we can refer to the value 2 by name: @lisp @@ -1312,7 +1312,7 @@ size @end lisp @noindent -Here are further examples of the use of @t{define}: +Here are further examples of the use of @code{define}: @lisp (define pi 3.14159) @@ -1325,9 +1325,9 @@ circumference @end lisp @noindent -@t{Define} is our language's simplest means of abstraction, for it allows us +@code{Define} is our language's simplest means of abstraction, for it allows us to use simple names to refer to the results of compound operations, such as the -@t{circumference} computed above. In general, computational objects may +@code{circumference} computed above. In general, computational objects may have very complex structures, and it would be extremely inconvenient to have to remember and repeat their details each time we want to use them. Indeed, complex programs are constructed by building, step by step, computational @@ -1379,7 +1379,7 @@ rule is @newterm{recursive} in nature; that is, it includes, as one of its steps, the need to invoke the rule itself.@footnote{It may seem strange that the evaluation rule says, as part of the first step, that we should evaluate the leftmost element of a combination, since at this point that can only be an -operator such as @t{+} or @t{*} representing a built-in primitive +operator such as @code{+} or @code{*} representing a built-in primitive procedure such as addition or multiplication. We will see later that it is useful to be able to work with combinations whose operators are themselves compound expressions.} @@ -1458,25 +1458,25 @@ environment. @noindent We may regard the second rule as a special case of the third one by stipulating -that symbols such as @t{+} and @t{*} are also included in the global +that symbols such as @code{+} and @code{*} are also included in the global environment, and are associated with the sequences of machine instructions that are their ``values.'' The key point to notice is the role of the environment in determining the meaning of the symbols in expressions. In an interactive language such as Lisp, it is meaningless to speak of the value of an expression -such as @t{(+ x 1)} without specifying any information about the environment -that would provide a meaning for the symbol @t{x} (or even for the symbol -@t{+}). As we shall see in @ref{Chapter 3}, the general notion of the +such as @code{(+ x 1)} without specifying any information about the environment +that would provide a meaning for the symbol @code{x} (or even for the symbol +@code{+}). As we shall see in @ref{Chapter 3}, the general notion of the environment as providing a context in which evaluation takes place will play an important role in our understanding of program execution. Notice that the evaluation rule given above does not handle definitions. For -instance, evaluating @t{(define x 3)} does not apply @t{define} to two -arguments, one of which is the value of the symbol @t{x} and the other of -which is 3, since the purpose of the @t{define} is precisely to associate -@t{x} with a value. (That is, @t{(define x 3)} is not a combination.) +instance, evaluating @code{(define x 3)} does not apply @code{define} to two +arguments, one of which is the value of the symbol @code{x} and the other of +which is 3, since the purpose of the @code{define} is precisely to associate +@code{x} with a value. (That is, @code{(define x 3)} is not a combination.) Such exceptions to the general evaluation rule are called @newterm{special -forms}. @t{Define} is the only example of a special form that we have seen +forms}. @code{Define} is the only example of a special form that we have seen so far, but we will meet others shortly. Each special form has its own evaluation rule. The various kinds of expressions (each with its associated evaluation rule) constitute the syntax of the programming language. In @@ -1540,13 +1540,13 @@ We can understand this in the following way: @noindent We have here a @newterm{compound procedure}, which has been given the name -@t{square}. The procedure represents the operation of multiplying something -by itself. The thing to be multiplied is given a local name, @t{x}, which +@code{square}. The procedure represents the operation of multiplying something +by itself. The thing to be multiplied is given a local name, @code{x}, which plays the same role that a pronoun plays in natural language. Evaluating the definition creates this compound procedure and associates it with the name -@t{square}.@footnote{Observe that there are two different operations being +@code{square}.@footnote{Observe that there are two different operations being combined here: we are creating the procedure, and we are giving it the name -@t{square}. It is possible, indeed important, to be able to separate these +@code{square}. It is possible, indeed important, to be able to separate these two notions---to create procedures without naming them, and to give names to procedures that have already been created. We will see how to do this in @ref{1.3.2}.} @@ -1574,7 +1574,7 @@ expression as the value of the procedure application.} The @math{\langle}@var{n the @math{\langle}@var{formal parameters}@math{\kern0.08em\rangle} are grouped within parentheses, just as they would be in an actual call to the procedure being defined. -Having defined @t{square}, we can now use it: +Having defined @code{square}, we can now use it: @lisp (square 21) @@ -1586,7 +1586,7 @@ Having defined @t{square}, we can now use it: @end lisp @noindent -We can also use @t{square} as a building block in defining other procedures. +We can also use @code{square} as a building block in defining other procedures. For example, @math{x^2 + y^2} can be expressed as @lisp @@ -1594,7 +1594,7 @@ For example, @math{x^2 + y^2} can be expressed as @end lisp @noindent -We can easily define a procedure @t{sum-of-squares} that, given any two +We can easily define a procedure @code{sum-of-squares} that, given any two numbers as arguments, produces the sum of their squares: @lisp @@ -1606,7 +1606,7 @@ numbers as arguments, produces the sum of their squares: @end lisp @noindent -Now we can use @t{sum-of-squares} as a building block in constructing +Now we can use @code{sum-of-squares} as a building block in constructing further procedures: @lisp @@ -1620,8 +1620,8 @@ further procedures: @noindent Compound procedures are used in exactly the same way as primitive procedures. Indeed, one could not tell by looking at the definition of -@t{sum-of-squares} given above whether @t{square} was built into the -interpreter, like @t{+} and @t{*}, or defined as a compound procedure. +@code{sum-of-squares} given above whether @code{square} was built into the +interpreter, like @code{+} and @code{*}, or defined as a compound procedure. @node 1.1.5, 1.1.6, 1.1.4, 1.1 @subsection The Substitution Model for Procedure Application @@ -1650,15 +1650,15 @@ To illustrate this process, let's evaluate the combination @end lisp @noindent -where @t{f} is the procedure defined in @ref{1.1.4}. We begin by -retrieving the body of @t{f}: +where @code{f} is the procedure defined in @ref{1.1.4}. We begin by +retrieving the body of @code{f}: @lisp (sum-of-squares (+ a 1) (* a 2)) @end lisp @noindent -Then we replace the formal parameter @t{a} by the argument 5: +Then we replace the formal parameter @code{a} by the argument 5: @lisp (sum-of-squares (+ 5 1) (* 5 2)) @@ -1666,20 +1666,20 @@ Then we replace the formal parameter @t{a} by the argument 5: @noindent Thus the problem reduces to the evaluation of a combination with two operands -and an operator @t{sum-of-squares}. Evaluating this combination involves +and an operator @code{sum-of-squares}. Evaluating this combination involves three subproblems. We must evaluate the operator to get the procedure to be -applied, and we must evaluate the operands to get the arguments. Now @t{(+ -5 1)} produces 6 and @t{(* 5 2)} produces 10, so we must apply the -@t{sum-of-squares} procedure to 6 and 10. These values are substituted for -the formal parameters @t{x} and @t{y} in the body of -@t{sum-of-squares}, reducing the expression to +applied, and we must evaluate the operands to get the arguments. Now @code{(+ +5 1)} produces 6 and @code{(* 5 2)} produces 10, so we must apply the +@code{sum-of-squares} procedure to 6 and 10. These values are substituted for +the formal parameters @code{x} and @code{y} in the body of +@code{sum-of-squares}, reducing the expression to @lisp (+ (square 6) (square 10)) @end lisp @noindent -If we use the definition of @t{square}, this reduces to +If we use the definition of @code{square}, this reduces to @lisp (+ (* 6 6) (* 10 10)) @@ -1748,7 +1748,7 @@ perform evaluation. An alternative evaluation model would not evaluate the operands until their values were needed. Instead it would first substitute operand expressions for parameters until it obtained an expression involving only primitive operators, and would then perform the evaluation. If we used -this method, the evaluation of @t{(f 5)} would proceed according to the +this method, the evaluation of @code{(f 5)} would proceed according to the sequence of expansions @lisp @@ -1768,10 +1768,10 @@ followed by the reductions @noindent This gives the same answer as our previous evaluation model, but the process is -different. In particular, the evaluations of @t{(+ 5 1)} and @t{(* 5 2)} +different. In particular, the evaluations of @code{(+ 5 1)} and @code{(* 5 2)} are each performed twice here, corresponding to the reduction of the expression -@t{(* x x)} with @t{x} replaced respectively by @t{(+ 5 1)} and -@t{(* 5 2)}. +@code{(* x x)} with @code{x} replaced respectively by @code{(+ 5 1)} and +@code{(* 5 2)}. This alternative ``fully expand and then reduce'' evaluation method is known as @newterm{normal-order evaluation}, in contrast to the ``evaluate the arguments @@ -1785,7 +1785,7 @@ normal-order and applicative-order evaluation do not give the same result.) Lisp uses applicative-order evaluation, partly because of the additional efficiency obtained from avoiding multiple evaluations of expressions such as -those illustrated with @t{(+ 5 1)} and @t{(* 5 2)} above and, more +those illustrated with @code{(+ 5 1)} and @code{(* 5 2)} above and, more significantly, because normal-order evaluation becomes much more complicated to deal with when we leave the realm of procedures that can be modeled by substitution. On the other hand, normal-order evaluation can be an extremely @@ -1822,7 +1822,7 @@ $$ |x| = \left\{\eqalign{ \hfill x &\quad{\rm if}\quad x > 0, \cr -x &\quad{\rm if}\quad x < 0. \cr}\right. $$ @end tex This construct is called a @newterm{case analysis}, and there is a special form -in Lisp for notating such a case analysis. It is called @t{cond} (which +in Lisp for notating such a case analysis. It is called @code{cond} (which stands for ``conditional''), and it is used as follows: @lisp @@ -1843,7 +1843,7 @@ The general form of a conditional expression is @end lisp @noindent -consisting of the symbol @t{cond} followed by parenthesized pairs of +consisting of the symbol @code{cond} followed by parenthesized pairs of expressions @lisp @@ -1855,11 +1855,11 @@ called @newterm{clauses}. The first expression in each pair is a @newterm{predicate}---that is, an expression whose value is interpreted as either true or false.@footnote{``Interpreted as either true or false'' means this: In Scheme, there are two distinguished values that are denoted by the -constants @t{#t} and @t{#f}. When the interpreter checks a predicate's -value, it interprets @t{#f} as false. Any other value is treated as true. -(Thus, providing @t{#t} is logically unnecessary, but it is convenient.) In -this book we will use names @t{true} and @t{false}, which are associated -with the values @t{#t} and @t{#f} respectively.} +constants @code{#t} and @code{#f}. When the interpreter checks a predicate's +value, it interprets @code{#f} as false. Any other value is treated as true. +(Thus, providing @code{#t} is logically unnecessary, but it is convenient.) In +this book we will use names @code{true} and @code{false}, which are associated +with the values @code{#t} and @code{#f} respectively.} Conditional expressions are evaluated as follows. The predicate @math{\langle{p_1}\kern0.08em\rangle} is evaluated first. If its value is false, then @math{\langle{p_2}\kern0.08em\rangle} is evaluated. If @@ -1867,14 +1867,14 @@ evaluated first. If its value is false, then @math{\langle{p_2}\kern0.08em\rang continues until a predicate is found whose value is true, in which case the interpreter returns the value of the corresponding @newterm{consequent expression} @math{\langle{e}\kern0.08em\rangle} of the clause as the value of the conditional expression. -If none of the @math{\langle{p}\kern0.08em\rangle}'s is found to be true, the value of the @t{cond} is +If none of the @math{\langle{p}\kern0.08em\rangle}'s is found to be true, the value of the @code{cond} is undefined. The word @newterm{predicate} is used for procedures that return true or false, as well as for expressions that evaluate to true or false. The absolute-value -procedure @t{abs} makes use of the primitive predicates @t{>}, @t{<}, -and @t{=}.@footnote{@t{Abs} also uses the ``minus'' operator @t{-}, -which, when used with a single operand, as in @t{(- x)}, indicates +procedure @code{abs} makes use of the primitive predicates @code{>}, @code{<}, +and @code{=}.@footnote{@code{Abs} also uses the ``minus'' operator @code{-}, +which, when used with a single operand, as in @code{(- x)}, indicates negation.} These take two numbers as arguments and test whether the first number is, respectively, greater than, less than, or equal to the second number, returning true or false accordingly. @@ -1889,9 +1889,9 @@ Another way to write the absolute-value procedure is @noindent which could be expressed in English as ``If @math{x} is less than zero return -@math{-x}; otherwise return @math{x}.'' @t{Else} is a special symbol that can be -used in place of the @math{\langle{p}\kern0.08em\rangle} in the final clause of a @t{cond}. This -causes the @t{cond} to return as its value the value of the corresponding +@math{-x}; otherwise return @math{x}.'' @code{Else} is a special symbol that can be +used in place of the @math{\langle{p}\kern0.08em\rangle} in the final clause of a @code{cond}. This +causes the @code{cond} to return as its value the value of the corresponding @math{\langle{e}\kern0.08em\rangle} whenever all previous clauses have been bypassed. In fact, any expression that always evaluates to a true value could be used as the @math{\langle{p}\kern0.08em\rangle} here. @@ -1906,28 +1906,28 @@ Here is yet another way to write the absolute-value procedure: @end lisp @noindent -This uses the special form @t{if}, a restricted type of conditional that can +This uses the special form @code{if}, a restricted type of conditional that can be used when there are precisely two cases in the case analysis. The general -form of an @t{if} expression is +form of an @code{if} expression is @lisp (if @math{\langle\kern0.07em}@var{predicate}@math{\kern0.06em\rangle} @math{\langle\kern0.07em}@var{consequent}@math{\kern0.05em\rangle} @math{\langle\kern0.06em}@var{alternative}@math{\kern0.06em\rangle}) @end lisp @noindent -To evaluate an @t{if} expression, the interpreter starts by evaluating the +To evaluate an @code{if} expression, the interpreter starts by evaluating the @math{\langle}@var{predicate}@math{\kern0.08em\rangle} part of the expression. If the @math{\langle}@var{predicate}@math{\kern0.08em\rangle} evaluates to a true value, the interpreter then evaluates the @math{\langle}@var{consequent}@math{\kern0.08em\rangle} and returns its value. Otherwise it evaluates the @math{\langle}@var{alternative}@math{\kern0.08em\rangle} and returns -its value.@footnote{A minor difference between @t{if} and @t{cond} is -that the @math{\langle{e}\kern0.08em\rangle} part of each @t{cond} clause may be a sequence of +its value.@footnote{A minor difference between @code{if} and @code{cond} is +that the @math{\langle{e}\kern0.08em\rangle} part of each @code{cond} clause may be a sequence of expressions. If the corresponding @math{\langle{p}\kern0.08em\rangle} is found to be true, the expressions @math{\langle{e}\kern0.08em\rangle} are evaluated in sequence and the value of the final -expression in the sequence is returned as the value of the @t{cond}. In an -@t{if} expression, however, the @math{\langle}@var{consequent}@math{\kern0.08em\rangle} and @math{\langle}@var{alternative}@math{\kern0.08em\rangle} +expression in the sequence is returned as the value of the @code{cond}. In an +@code{if} expression, however, the @math{\langle}@var{consequent}@math{\kern0.08em\rangle} and @math{\langle}@var{alternative}@math{\kern0.08em\rangle} must be single expressions.} -In addition to primitive predicates such as @t{<}, @t{=}, and @t{>}, +In addition to primitive predicates such as @code{<}, @code{=}, and @code{>}, there are logical composition operations, which enable us to construct compound predicates. The three most frequently used are these: @@ -1938,30 +1938,30 @@ predicates. The three most frequently used are these: The interpreter evaluates the expressions @math{\langle{e}\kern0.08em\rangle} one at a time, in left-to-right order. If any @math{\langle{e}\kern0.08em\rangle} evaluates to false, the value of the -@t{and} expression is false, and the rest of the @math{\langle{e}\kern0.08em\rangle}'s are not +@code{and} expression is false, and the rest of the @math{\langle{e}\kern0.08em\rangle}'s are not evaluated. If all @math{\langle{e}\kern0.08em\rangle}'s evaluate to true values, the value of the -@t{and} expression is the value of the last one. +@code{and} expression is the value of the last one. @item @math{\hbox{\tt(or }\langle{e_1}\rangle\;\;\dots\;\;\langle{e_n}\rangle\hbox{\tt)}} The interpreter evaluates the expressions @math{\langle{e}\kern0.08em\rangle} one at a time, in left-to-right order. If any @math{\langle{e}\kern0.08em\rangle} evaluates to a true value, that value is -returned as the value of the @t{or} expression, and the rest of the +returned as the value of the @code{or} expression, and the rest of the @math{\langle{e}\kern0.08em\rangle}'s are not evaluated. If all @math{\langle{e}\kern0.08em\rangle}'s evaluate to false, the value -of the @t{or} expression is false. +of the @code{or} expression is false. @item @math{\hbox{\tt(not }\langle{e}\rangle\hbox{\tt)}} -The value of a @t{not} expression is true when the expression @math{\langle{e}\kern0.08em\rangle} +The value of a @code{not} expression is true when the expression @math{\langle{e}\kern0.08em\rangle} evaluates to false, and false otherwise. @end itemize @noindent -Notice that @t{and} and @t{or} are special forms, not procedures, because -the subexpressions are not necessarily all evaluated. @t{Not} is an +Notice that @code{and} and @code{or} are special forms, not procedures, because +the subexpressions are not necessarily all evaluated. @code{Not} is an ordinary procedure. As an example of how these are used, the condition that a number @math{x} be in @@ -1973,7 +1973,7 @@ the range @math{5 < x < 10} may be expressed as @noindent As another example, we can define a predicate to test whether one number is -greater than or equal to another as @math{\kern0.9ex}@t{(define (>= x y) (or (> x y) (= x y)))} +greater than or equal to another as @math{\kern0.9ex}@code{(define (>= x y) (or (> x y) (= x y)))} @noindent or alternatively as @@ -2066,7 +2066,7 @@ Then he evaluates the expression What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer. (Assume that the evaluation -rule for the special form @t{if} is the same whether the interpreter is +rule for the special form @code{if} is the same whether the interpreter is using normal or applicative order: The predicate expression is evaluated first, and the result determines whether to evaluate the consequent or the alternative expression.) @@ -2223,7 +2223,7 @@ of 1.0 forces all subsequent values to be decimals.} @end lisp @noindent -If we type these definitions to the interpreter, we can use @t{sqrt} just as +If we type these definitions to the interpreter, we can use @code{sqrt} just as we can use any procedure: @lisp @@ -2238,11 +2238,11 @@ we can use any procedure: @end lisp @noindent -The @t{sqrt} program also illustrates that the simple procedural language we +The @code{sqrt} program also illustrates that the simple procedural language we have introduced so far is sufficient for writing any purely numerical program that one could write in, say, C or Pascal. This might seem surprising, since we have not included in our language any iterative (looping) constructs that -direct the computer to do something over and over again. @t{Sqrt-iter}, on +direct the computer to do something over and over again. @code{Sqrt-iter}, on the other hand, demonstrates how iteration can be accomplished using no special construct other than the ordinary ability to call a procedure.@footnote{Readers who are worried about the efficiency issues involved in using procedure calls @@ -2251,10 +2251,10 @@ to implement iteration should note the remarks on ``tail recursion'' in @quotation @strong{@anchor{Exercise 1.6}Exercise 1.6:} Alyssa P. Hacker doesn't see why -@t{if} needs to be provided as a special form. ``Why can't I just define it -as an ordinary procedure in terms of @t{cond}?'' she asks. Alyssa's friend +@code{if} needs to be provided as a special form. ``Why can't I just define it +as an ordinary procedure in terms of @code{cond}?'' she asks. Alyssa's friend Eva Lu Ator claims this can indeed be done, and she defines a new version of -@t{if}: +@code{if}: @lisp (define (new-if predicate @@ -2273,7 +2273,7 @@ Eva demonstrates the program for Alyssa: @i{0} @end lisp -Delighted, Alyssa uses @t{new-if} to rewrite the square-root program: +Delighted, Alyssa uses @code{new-if} to rewrite the square-root program: @lisp (define (sqrt-iter guess x) @@ -2287,13 +2287,13 @@ Explain. @end quotation @quotation -@strong{@anchor{Exercise 1.7}Exercise 1.7:} The @t{good-enough?} test used +@strong{@anchor{Exercise 1.7}Exercise 1.7:} The @code{good-enough?} test used in computing square roots will not be very effective for finding the square roots of very small numbers. Also, in real computers, arithmetic operations are almost always performed with limited precision. This makes our test inadequate for very large numbers. Explain these statements, with examples showing how the test fails for small and large numbers. An alternative -strategy for implementing @t{good-enough?} is to watch how @t{guess} +strategy for implementing @code{good-enough?} is to watch how @code{guess} changes from one iteration to the next and to stop when the change is a very small fraction of the guess. Design a square-root procedure that uses this kind of end test. Does this work better for small and large numbers? @@ -2325,19 +2325,19 @@ procedures.) @node 1.1.8, , 1.1.7, 1.1 @subsection Procedures as Black-Box Abstractions -@t{Sqrt} is our first example of a process defined by a set of mutually -defined procedures. Notice that the definition of @t{sqrt-iter} is +@code{Sqrt} is our first example of a process defined by a set of mutually +defined procedures. Notice that the definition of @code{sqrt-iter} is @newterm{recursive;} that is, the procedure is defined in terms of itself. The idea of being able to define a procedure in terms of itself may be disturbing; it may seem unclear how such a ``circular'' definition could make sense at all, much less specify a well-defined process to be carried out by a computer. This will be addressed more carefully in @ref{1.2}. But first let's -consider some other important points illustrated by the @t{sqrt} example. +consider some other important points illustrated by the @code{sqrt} example. Observe that the problem of computing square roots breaks up naturally into a number of subproblems: how to tell whether a guess is good enough, how to improve a guess, and so on. Each of these tasks is accomplished by a separate -procedure. The entire @t{sqrt} program can be viewed as a cluster of +procedure. The entire @code{sqrt} program can be viewed as a cluster of procedures (shown in @ref{Figure 1.2}) that mirrors the decomposition of the problem into subproblems. @@ -2346,7 +2346,7 @@ problem into subproblems. @quotation @anchor{Figure 1.2} @ifinfo -@strong{Figure 1.2:} Procedural decomposition of the @t{sqrt} program. +@strong{Figure 1.2:} Procedural decomposition of the @code{sqrt} program. @end ifinfo @example @@ -2360,7 +2360,7 @@ problem into subproblems. @end example @iftex @sp 0.9 -@strong{Figure 1.2:} Procedural decomposition of the @t{sqrt} program. +@strong{Figure 1.2:} Procedural decomposition of the @code{sqrt} program. @sp 0.7 @end iftex @end quotation @@ -2372,13 +2372,13 @@ dividing the program into parts. After all, we could take any large program and divide it into parts---the first ten lines, the next ten lines, the next ten lines, and so on. Rather, it is crucial that each procedure accomplishes an identifiable task that can be used as a module in defining other procedures. -For example, when we define the @t{good-enough?} procedure in terms of -@t{square}, we are able to regard the @t{square} procedure as a ``black +For example, when we define the @code{good-enough?} procedure in terms of +@code{square}, we are able to regard the @code{square} procedure as a ``black box.'' We are not at that moment concerned with @emph{how} the procedure computes its result, only with the fact that it computes the square. The details of how the square is computed can be suppressed, to be considered at a -later time. Indeed, as far as the @t{good-enough?} procedure is concerned, -@t{square} is not quite a procedure but rather an abstraction of a +later time. Indeed, as far as the @code{good-enough?} procedure is concerned, +@code{square} is not quite a procedure but rather an abstraction of a procedure, a so-called @newterm{procedural abstraction}. At this level of abstraction, any procedure that computes the square is equally good. @@ -2421,7 +2421,7 @@ This principle---that the meaning of a procedure should be independent of the parameter names used by its author---seems on the surface to be self-evident, but its consequences are profound. The simplest consequence is that the parameter names of a procedure must be local to the body of the procedure. For -example, we used @t{square} in the definition of @t{good-enough?} in our +example, we used @code{square} in the definition of @code{good-enough?} in our square-root procedure: @lisp @@ -2430,23 +2430,23 @@ square-root procedure: @end lisp @noindent -The intention of the author of @t{good-enough?} is to determine if the +The intention of the author of @code{good-enough?} is to determine if the square of the first argument is within a given tolerance of the second -argument. We see that the author of @t{good-enough?} used the name -@t{guess} to refer to the first argument and @t{x} to refer to the second -argument. The argument of @t{square} is @t{guess}. If the author of -@t{square} used @t{x} (as above) to refer to that argument, we see that -the @t{x} in @t{good-enough?} must be a different @t{x} than the one -in @t{square}. Running the procedure @t{square} must not affect the -value of @t{x} that is used by @t{good-enough?}, because that value of -@t{x} may be needed by @t{good-enough?} after @t{square} is done +argument. We see that the author of @code{good-enough?} used the name +@code{guess} to refer to the first argument and @code{x} to refer to the second +argument. The argument of @code{square} is @code{guess}. If the author of +@code{square} used @code{x} (as above) to refer to that argument, we see that +the @code{x} in @code{good-enough?} must be a different @code{x} than the one +in @code{square}. Running the procedure @code{square} must not affect the +value of @code{x} that is used by @code{good-enough?}, because that value of +@code{x} may be needed by @code{good-enough?} after @code{square} is done computing. If the parameters were not local to the bodies of their respective procedures, -then the parameter @t{x} in @t{square} could be confused with the -parameter @t{x} in @t{good-enough?}, and the behavior of -@t{good-enough?} would depend upon which version of @t{square} we used. -Thus, @t{square} would not be the black box we desired. +then the parameter @code{x} in @code{square} could be confused with the +parameter @code{x} in @code{good-enough?}, and the behavior of +@code{good-enough?} would depend upon which version of @code{square} we used. +Thus, @code{square} would not be the black box we desired. A formal parameter of a procedure has a very special role in the procedure definition, in that it doesn't matter what name the formal parameter has. Such @@ -2461,18 +2461,18 @@ The set of expressions for which a binding defines a name is called the declared as the formal parameters of the procedure have the body of the procedure as their scope. -In the definition of @t{good-enough?} above, @t{guess} and @t{x} are -bound variables but @t{<}, @t{-}, @t{abs}, and @t{square} are free. -The meaning of @t{good-enough?} should be independent of the names we choose -for @t{guess} and @t{x} so long as they are distinct and different from -@t{<}, @t{-}, @t{abs}, and @t{square}. (If we renamed @t{guess} -to @t{abs} we would have introduced a bug by @newterm{capturing} the -variable @t{abs}. It would have changed from free to bound.) The meaning -of @t{good-enough?} is not independent of the names of its free variables, +In the definition of @code{good-enough?} above, @code{guess} and @code{x} are +bound variables but @code{<}, @code{-}, @code{abs}, and @code{square} are free. +The meaning of @code{good-enough?} should be independent of the names we choose +for @code{guess} and @code{x} so long as they are distinct and different from +@code{<}, @code{-}, @code{abs}, and @code{square}. (If we renamed @code{guess} +to @code{abs} we would have introduced a bug by @newterm{capturing} the +variable @code{abs}. It would have changed from free to bound.) The meaning +of @code{good-enough?} is not independent of the names of its free variables, however. It surely depends upon the fact (external to this definition) that -the symbol @t{abs} names a procedure for computing the absolute value of a -number. @t{Good-enough?} will compute a different function if we substitute -@t{cos} for @t{abs} in its definition. +the symbol @code{abs} names a procedure for computing the absolute value of a +number. @code{Good-enough?} will compute a different function if we substitute +@code{cos} for @code{abs} in its definition. @subsubheading Internal definitions and block structure @@ -2495,18 +2495,18 @@ the use of names. The existing program consists of separate procedures: @noindent The problem with this program is that the only procedure that is important to -users of @t{sqrt} is @t{sqrt}. The other procedures (@t{sqrt-iter}, -@t{good-enough?}, and @t{improve}) only clutter up their minds. They may -not define any other procedure called @t{good-enough?} as part of another -program to work together with the square-root program, because @t{sqrt} +users of @code{sqrt} is @code{sqrt}. The other procedures (@code{sqrt-iter}, +@code{good-enough?}, and @code{improve}) only clutter up their minds. They may +not define any other procedure called @code{good-enough?} as part of another +program to work together with the square-root program, because @code{sqrt} needs it. The problem is especially severe in the construction of large systems by many separate programmers. For example, in the construction of a large library of numerical procedures, many numerical functions are computed as successive approximations and thus might have procedures named -@t{good-enough?} and @t{improve} as auxiliary procedures. We would like -to localize the subprocedures, hiding them inside @t{sqrt} so that -@t{sqrt} could coexist with other successive approximations, each having its -own private @t{good-enough?} procedure. To make this possible, we allow a +@code{good-enough?} and @code{improve} as auxiliary procedures. We would like +to localize the subprocedures, hiding them inside @code{sqrt} so that +@code{sqrt} could coexist with other successive approximations, each having its +own private @code{good-enough?} procedure. To make this possible, we allow a procedure to have internal definitions that are local to that procedure. For example, in the square-root problem we can write @@ -2528,13 +2528,13 @@ example, in the square-root problem we can write Such nesting of definitions, called @newterm{block structure}, is basically the right solution to the simplest name-packaging problem. But there is a better idea lurking here. In addition to internalizing the definitions of the -auxiliary procedures, we can simplify them. Since @t{x} is bound in the -definition of @t{sqrt}, the procedures @t{good-enough?}, @t{improve}, -and @t{sqrt-iter}, which are defined internally to @t{sqrt}, are in the -scope of @t{x}. Thus, it is not necessary to pass @t{x} explicitly to -each of these procedures. Instead, we allow @t{x} to be a free variable in -the internal definitions, as shown below. Then @t{x} gets its value from the -argument with which the enclosing procedure @t{sqrt} is called. This +auxiliary procedures, we can simplify them. Since @code{x} is bound in the +definition of @code{sqrt}, the procedures @code{good-enough?}, @code{improve}, +and @code{sqrt-iter}, which are defined internally to @code{sqrt}, are in the +scope of @code{x}. Thus, it is not necessary to pass @code{x} explicitly to +each of these procedures. Instead, we allow @code{x} to be a free variable in +the internal definitions, as shown below. Then @code{x} gets its value from the +argument with which the enclosing procedure @code{sqrt} is called. This discipline is called @newterm{lexical scoping}.@footnote{Lexical scoping dictates that free variables in a procedure are taken to refer to bindings made by enclosing procedure definitions; that is, they are looked up in the environment in which the @@ -2707,7 +2707,7 @@ exceeds @math{n}. Once again, we can recast our description as a procedure for computing factorials:@footnote{In a real program we would probably use the block structure introduced in the last section to hide the definition of -@t{fact-iter}: +@code{fact-iter}: @lisp (define (factorial n) @@ -2788,7 +2788,7 @@ needed to keep track of it, grows linearly with @math{n} (is proportional to By contrast, the second process does not grow and shrink. At each step, all we need to keep track of, for any @math{n}, are the current values of the variables -@t{product}, @t{counter}, and @t{max-count}. We call this an +@code{product}, @code{counter}, and @code{max-count}. We call this an @newterm{iterative process}. In general, an iterative process is one whose state can be summarized by a fixed number of @newterm{state variables}, together with a fixed rule that describes how the state variables should be @@ -2820,7 +2820,7 @@ directly or indirectly) to the procedure itself. But when we describe a process as following a pattern that is, say, linearly recursive, we are speaking about how the process evolves, not about the syntax of how a procedure is written. It may seem disturbing that we refer to a recursive procedure such -as @t{fact-iter} as generating an iterative process. However, the process +as @code{fact-iter} as generating an iterative process. However, the process really is iterative: Its state is captured completely by its three state variables, and an interpreter need keep track of only three variables in order to execute the process. @@ -2831,8 +2831,8 @@ are designed in such a way that the interpretation of any recursive procedure consumes an amount of memory that grows with the number of procedure calls, even when the process described is, in principle, iterative. As a consequence, these languages can describe iterative processes only by resorting to -special-purpose ``looping constructs'' such as @t{do}, @t{repeat}, -@t{until}, @t{for}, and @t{while}. The implementation of Scheme we +special-purpose ``looping constructs'' such as @code{do}, @code{repeat}, +@code{until}, @code{for}, and @code{while}. The implementation of Scheme we shall consider in @ref{Chapter 5} does not share this defect. It will execute an iterative process in constant space, even if the iterative process is described by a recursive procedure. An implementation with this property is @@ -2852,7 +2852,7 @@ Scheme requires that Scheme implementations be tail-recursive.} @quotation @strong{@anchor{Exercise 1.9}Exercise 1.9:} Each of the following two procedures defines a method for adding two positive integers in terms of the -procedures @t{inc}, which increments its argument by 1, and @t{dec}, +procedures @code{inc}, which increments its argument by 1, and @code{dec}, which decrements its argument by 1. @lisp @@ -2863,7 +2863,7 @@ which decrements its argument by 1. @end lisp Using the substitution model, illustrate the process generated by each -procedure in evaluating @t{(+ 4 5)}. Are these processes iterative or +procedure in evaluating @code{(+ 4 5)}. Are these processes iterative or recursive? @end quotation @@ -2888,7 +2888,7 @@ What are the values of the following expressions? (A 3 3) @end lisp -Consider the following procedures, where @t{A} is the procedure +Consider the following procedures, where @code{A} is the procedure defined above: @lisp @@ -2899,8 +2899,8 @@ defined above: @end lisp Give concise mathematical definitions for the functions computed by the -procedures @t{f}, @t{g}, and @t{h} for positive integer values of -@math{n}. For example, @t{(k n)} computes @math{5n^2}. +procedures @code{f}, @code{g}, and @code{h} for positive integer values of +@math{n}. For example, @code{(k n)} computes @math{5n^2}. @end quotation @node 1.2.2, 1.2.3, 1.2.1, 1.2 @@ -2943,18 +2943,18 @@ computing Fibonacci numbers: @end lisp @noindent -Consider the pattern of this computation. To compute @t{(fib 5)}, we -compute @t{(fib 4)} and @t{(fib 3)}. To compute @t{(fib 4)}, we -compute @t{(fib 3)} and @t{(fib 2)}. In general, the evolved process +Consider the pattern of this computation. To compute @code{(fib 5)}, we +compute @code{(fib 4)} and @code{(fib 3)}. To compute @code{(fib 4)}, we +compute @code{(fib 3)} and @code{(fib 2)}. In general, the evolved process looks like a tree, as shown in @ref{Figure 1.5}. Notice that the branches split into two at each level (except at the bottom); this reflects the fact -that the @t{fib} procedure calls itself twice each time it is invoked. +that the @code{fib} procedure calls itself twice each time it is invoked. @float @anchor{Figure 1.5} @ifinfo @quotation -@strong{Figure 1.5:} The tree-recursive process generated in computing @t{(fib 5)}. +@strong{Figure 1.5:} The tree-recursive process generated in computing @code{(fib 5)}. @example @@ -2984,7 +2984,7 @@ V / . \ . 1 . . 1 . . 0 . . 1 . . 0 .. @center @image{fig/chap1/Fig1.5d,147mm,,,.pdf} @sp 0.5 @quotation -@strong{Figure 1.5:} The tree-recursive process generated in computing @t{(fib 5)}. +@strong{Figure 1.5:} The tree-recursive process generated in computing @code{(fib 5)}. @end quotation @sp 0.7 @end iftex @@ -2994,9 +2994,9 @@ V / . \ . 1 . . 1 . . 0 . . 1 . . 0 .. This procedure is instructive as a prototypical tree recursion, but it is a terrible way to compute Fibonacci numbers because it does so much redundant computation. Notice in @ref{Figure 1.5} that the entire computation of -@t{(fib 3)}---almost half the work---is duplicated. In fact, it is not hard -to show that the number of times the procedure will compute @t{(fib 1)} or -@t{(fib 0)} (the number of leaves in the above tree, in general) is +@code{(fib 3)}---almost half the work---is duplicated. In fact, it is not hard +to show that the number of times the procedure will compute @code{(fib 1)} or +@code{(fib 0)} (the number of leaves in the above tree, in general) is precisely Fib(@math{n+1}). To get an idea of how bad this is, one can show that the value of Fib(@math{n}) grows exponentially with @math{n}. More precisely (see @ref{Exercise 1.13}), Fib(@math{n}) is the closest integer @@ -3075,7 +3075,7 @@ tool.@footnote{An example of this was hinted at in @ref{1.1.3}: The interpreter itself evaluates expressions using a tree-recursive process.} But even in numerical operations, tree-recursive processes can be useful in helping us to understand and design programs. For instance, although the first -@t{fib} procedure is much less efficient than the second one, it is more +@code{fib} procedure is much less efficient than the second one, it is more straightforward, being little more than a translation into Lisp of the definition of the Fibonacci sequence. To formulate the iterative algorithm required noticing that the computation could be recast as an iteration with @@ -3162,7 +3162,7 @@ We can easily translate this description into a recursive procedure: @end lisp @noindent -(The @t{first-denomination} procedure takes as input the number of kinds of +(The @code{first-denomination} procedure takes as input the number of kinds of coins available and returns the denomination of the first kind. Here we are thinking of the coins as arranged in order from largest to smallest, but any order would do as well.) We can now answer our original question about @@ -3174,8 +3174,8 @@ changing a dollar: @end lisp @noindent -@t{Count-change} generates a tree-recursive process with redundancies -similar to those in our first implementation of @t{fib}. (It will take +@code{Count-change} generates a tree-recursive process with redundancies +similar to those in our first implementation of @code{fib}. (It will take quite a while for that 292 to be computed.) On the other hand, it is not obvious how to design a better algorithm for computing the result, and we leave this problem as a challenge. The observation that a tree-recursive process may @@ -3190,7 +3190,7 @@ in the table, in which case we avoid performing the redundant computation. This strategy, known as @newterm{tabulation} or @newterm{memoization}, can be implemented in a straightforward way. Tabulation can sometimes be used to transform processes that require an exponential number of steps (such as -@t{count-change}) into processes whose space and time requirements grow +@code{count-change}) into processes whose space and time requirements grow linearly with the input. See @ref{Exercise 3.27}.} @c Original version, where the long f(n) expression spreads to two lines: @@ -3327,7 +3327,7 @@ constant amount. @quotation @strong{@anchor{Exercise 1.14}Exercise 1.14:} Draw the tree illustrating the -process generated by the @t{count-change} procedure of @ref{1.2.2} +process generated by the @code{count-change} procedure of @ref{1.2.2} in making change for 11 cents. What are the orders of growth of the space and number of steps used by this process as the amount to be changed increases? @end quotation @@ -3367,13 +3367,13 @@ procedures: @enumerate a @item -How many times is the procedure @t{p} applied when @t{(sine 12.15)} is +How many times is the procedure @code{p} applied when @code{(sine 12.15)} is evaluated? @item What is the order of growth in space and number of steps (as a function of -@math{a}) used by the process generated by the @t{sine} procedure when -@t{(sine a)} is evaluated? +@math{a}) used by the process generated by the @code{sine} procedure when +@code{(sine a)} is evaluated? @end enumerate @end quotation @@ -3478,7 +3478,7 @@ We can express this method as a procedure: @noindent where the predicate to test whether an integer is even is defined in terms of -the primitive procedure @t{remainder} by +the primitive procedure @code{remainder} by @lisp (define (even? n) @@ -3486,9 +3486,9 @@ the primitive procedure @t{remainder} by @end lisp @noindent -The process evolved by @t{fast-expt} grows logarithmically with @math{n} in +The process evolved by @code{fast-expt} grows logarithmically with @math{n} in both space and number of steps. To see this, observe that computing -@math{b^{2n}} using @t{fast-expt} requires only one more multiplication +@math{b^{2n}} using @code{fast-expt} requires only one more multiplication than computing @math{b^n}. The size of the exponent we can compute therefore doubles (approximately) with every new multiplication we are allowed. Thus, the number of multiplications required for an exponent of @math{n} grows about as @@ -3503,7 +3503,7 @@ processes are described as @math{\Theta(\log n)}.} The difference between @math{\Theta(\log n)} growth and @math{\Theta(n)} growth becomes striking as @math{n} becomes large. For -example, @t{fast-expt} for @math{n} = 1000 requires only 14 +example, @code{fast-expt} for @math{n} = 1000 requires only 14 multiplications.@footnote{You may wonder why anyone would care about raising numbers to the 1000th power. See @ref{1.2.6}.} It is also possible to use the idea of successive squaring to devise an iterative algorithm that @@ -3518,7 +3518,7 @@ exponentiation.} @quotation @strong{@anchor{Exercise 1.16}Exercise 1.16:} Design a procedure that evolves an iterative exponentiation process that uses successive squaring and uses a -logarithmic number of steps, as does @t{fast-expt}. (Hint: Using the +logarithmic number of steps, as does @code{fast-expt}. (Hint: Using the observation that @math{(b^{n / 2})^2 = (b^2)^{n / 2}}, keep, along with the exponent @math{n} and the base @math{b}, an additional state variable @math{a}, and define the state transformation in such a way that the product @math{ab^n} @@ -3535,7 +3535,7 @@ this section are based on performing exponentiation by means of repeated multiplication. In a similar way, one can perform integer multiplication by means of repeated addition. The following multiplication procedure (in which it is assumed that our language can only add, not multiply) is analogous to the -@t{expt} procedure: +@code{expt} procedure: @lisp (define (* a b) @@ -3544,10 +3544,10 @@ it is assumed that our language can only add, not multiply) is analogous to the (+ a (* a (- b 1))))) @end lisp -This algorithm takes a number of steps that is linear in @t{b}. Now suppose -we include, together with addition, operations @t{double}, which doubles an -integer, and @t{halve}, which divides an (even) integer by 2. Using these, -design a multiplication procedure analogous to @t{fast-expt} that uses a +This algorithm takes a number of steps that is linear in @code{b}. Now suppose +we include, together with addition, operations @code{double}, which doubles an +integer, and @code{halve}, which divides an (even) integer by 2. Using these, +design a multiplication procedure analogous to @code{fast-expt} that uses a logarithmic number of steps. @end quotation @@ -3565,7 +3565,7 @@ oldest mathematical documents in existence, written about 1700 @acronym{B.C.} @quotation @strong{@anchor{Exercise 1.19}Exercise 1.19:} There is a clever algorithm for computing the Fibonacci numbers in a logarithmic number of steps. Recall the -transformation of the state variables @math{a} and @math{b} in the @t{fib-iter} +transformation of the state variables @math{a} and @math{b} in the @code{fib-iter} process of @ref{1.2.2}: @math{a \gets a + b} and @math{b \gets a}. Call this transformation @math{T}, and observe that applying @math{T} over and over again @math{n} times, starting with 1 and 0, produces the pair Fib(@math{n+1}) and @@ -3579,7 +3579,7 @@ Show that if we apply such a transformation @math{T_{pq}} twice, the effect is the same as using a single transformation @math{T_{p'q'}} of the same form, and compute @math{p'} and @math{q'} in terms of @math{p} and @math{q}. This gives us an explicit way to square these transformations, and thus we can -compute @math{T^n} using successive squaring, as in the @t{fast-expt} +compute @math{T^n} using successive squaring, as in the @code{fast-expt} procedure. Put this all together to complete the following procedure, which runs in a logarithmic number of steps:@footnote{This exercise was suggested to us by Joe Stoy, based on an example in @ref{Kaldewaij 1990}.} @@ -3718,14 +3718,14 @@ growth is @math{\Theta(\log n)}. @quotation @strong{@anchor{Exercise 1.20}Exercise 1.20:} The process that a procedure generates is of course dependent on the rules used by the interpreter. As an -example, consider the iterative @t{gcd} procedure given above. Suppose we +example, consider the iterative @code{gcd} procedure given above. Suppose we were to interpret this procedure using normal-order evaluation, as discussed in -@ref{1.1.5}. (The normal-order-evaluation rule for @t{if} is +@ref{1.1.5}. (The normal-order-evaluation rule for @code{if} is described in @ref{Exercise 1.5}.) Using the substitution method (for normal -order), illustrate the process generated in evaluating @t{(gcd 206 40)} and -indicate the @t{remainder} operations that are actually performed. How many -@t{remainder} operations are actually performed in the normal-order -evaluation of @t{(gcd 206 40)}? In the applicative-order evaluation? +order), illustrate the process generated in evaluating @code{(gcd 206 40)} and +indicate the @code{remainder} operations that are actually performed. How many +@code{remainder} operations are actually performed in the normal-order +evaluation of @code{(gcd 206 40)}? In the applicative-order evaluation? @end quotation @node 1.2.6, , 1.2.5, 1.2 @@ -3773,7 +3773,7 @@ We can test whether a number is prime as follows: @math{n} is prime if and only @end lisp @noindent -The end test for @t{find-divisor} is based on the fact that if @math{n} is not +The end test for @code{find-divisor} is based on the fact that if @math{n} is not prime it must have a divisor less than or equal to @math{\sqrt{n}}.@footnote{If @math{d} is a divisor of @math{n}, then so is @math{n \big/ d}. But @math{d} and @math{n \big/ d} cannot both be greater than @@ -3839,7 +3839,7 @@ of a number modulo another number: @end lisp @noindent -This is very similar to the @t{fast-expt} procedure of @ref{1.2.4}. +This is very similar to the @code{fast-expt} procedure of @ref{1.2.4}. It uses successive squaring, so that the number of steps grows logarithmically with the exponent.@footnote{The reduction steps in the cases where the exponent @math{e} is greater than 1 are based on the fact that, for any integers @math{x}, @@ -3855,10 +3855,10 @@ computation without ever having to deal with numbers much larger than @math{m}. The Fermat test is performed by choosing at random a number @math{a} between 1 and @math{n-1} inclusive and checking whether the remainder modulo @math{n} of the @math{n^{\hbox{\ordrm th}}} power of @math{a} is equal to @math{a}. The random number @math{a} is chosen -using the procedure @t{random}, which we assume is included as a primitive -in Scheme. @t{Random} returns a nonnegative integer less than its integer +using the procedure @code{random}, which we assume is included as a primitive +in Scheme. @code{Random} returns a nonnegative integer less than its integer input. Hence, to obtain a random number between 1 and @math{n-1}, we call -@t{random} with an input of @math{n-1} and add 1 to the result: +@code{random} with an input of @math{n-1} and add 1 to the result: @lisp (define (fermat-test n) @@ -3937,16 +3937,16 @@ now turns out to have important practical applications to cryptography, electronic funds transfer, and information retrieval.} @quotation -@strong{@anchor{Exercise 1.21}Exercise 1.21:} Use the @t{smallest-divisor} +@strong{@anchor{Exercise 1.21}Exercise 1.21:} Use the @code{smallest-divisor} procedure to find the smallest divisor of each of the following numbers: 199, 1999, 19999. @end quotation @quotation @strong{@anchor{Exercise 1.22}Exercise 1.22:} Most Lisp implementations include -a primitive called @t{runtime} that returns an integer that specifies the +a primitive called @code{runtime} that returns an integer that specifies the amount of time the system has been running (measured, for example, in -microseconds). The following @t{timed-prime-test} procedure, when called +microseconds). The following @code{timed-prime-test} procedure, when called with an integer @math{n}, prints @math{n} and checks to see if @math{n} is prime. If @math{n} is prime, the procedure prints three asterisks followed by the amount of time used in performing the test. @@ -3971,7 +3971,7 @@ time used in performing the test. (display elapsed-time)) @end lisp -Using this procedure, write a procedure @t{search-@/for-@/primes} that checks +Using this procedure, write a procedure @code{search-@/for-@/primes} that checks the primality of consecutive odd integers in a specified range. Use your procedure to find the three smallest primes larger than 1000; larger than 10,000; larger than 100,000; larger than 1,000,000. Note the time needed to @@ -3985,17 +3985,17 @@ proportional to the number of steps required for the computation? @end quotation @quotation -@strong{@anchor{Exercise 1.23}Exercise 1.23:} The @t{smallest-divisor} +@strong{@anchor{Exercise 1.23}Exercise 1.23:} The @code{smallest-divisor} procedure shown at the start of this section does lots of needless testing: After it checks to see if the number is divisible by 2 there is no point in checking to see if it is divisible by any larger even numbers. This suggests -that the values used for @t{test-divisor} should not be 2, 3, 4, 5, 6, +that the values used for @code{test-divisor} should not be 2, 3, 4, 5, 6, @dots{}, but rather 2, 3, 5, 7, 9, @dots{}. To implement this change, define a -procedure @t{next} that returns 3 if its input is equal to 2 and otherwise -returns its input plus 2. Modify the @t{smallest-divisor} procedure to use -@t{(next test-divisor)} instead of @t{(+ test-divisor 1)}. With -@t{timed-prime-test} incorporating this modified version of -@t{smallest-divisor}, run the test for each of the 12 primes found in +procedure @code{next} that returns 3 if its input is equal to 2 and otherwise +returns its input plus 2. Modify the @code{smallest-divisor} procedure to use +@code{(next test-divisor)} instead of @code{(+ test-divisor 1)}. With +@code{timed-prime-test} incorporating this modified version of +@code{smallest-divisor}, run the test for each of the 12 primes found in @ref{Exercise 1.22}. Since this modification halves the number of test steps, you should expect it to run about twice as fast. Is this expectation confirmed? If not, what is the observed ratio of the speeds of the two @@ -4004,8 +4004,8 @@ algorithms, and how do you explain the fact that it is different from 2? @quotation @strong{@anchor{Exercise 1.24}Exercise 1.24:} Modify the -@t{timed-prime-test} procedure of @ref{Exercise 1.22} to use -@t{fast-prime?} (the Fermat method), and test each of the 12 primes you +@code{timed-prime-test} procedure of @ref{Exercise 1.22} to use +@code{fast-prime?} (the Fermat method), and test each of the 12 primes you found in that exercise. Since the Fermat test has @math{\Theta(\log n)} growth, how would you expect the time to test primes near 1,000,000 to compare with the time needed to test primes near 1000? Do your data bear this @@ -4014,7 +4014,7 @@ out? Can you explain any discrepancy you find? @quotation @strong{@anchor{Exercise 1.25}Exercise 1.25:} Alyssa P. Hacker complains that -we went to a lot of extra work in writing @t{expmod}. After all, she says, +we went to a lot of extra work in writing @code{expmod}. After all, she says, since we already know how to compute exponentials, we could have simply written @lisp @@ -4028,11 +4028,11 @@ Explain. @quotation @strong{@anchor{Exercise 1.26}Exercise 1.26:} Louis Reasoner is having great -difficulty doing @ref{Exercise 1.24}. His @t{fast-prime?} test seems to run -more slowly than his @t{prime?} test. Louis calls his friend Eva Lu Ator +difficulty doing @ref{Exercise 1.24}. His @code{fast-prime?} test seems to run +more slowly than his @code{prime?} test. Louis calls his friend Eva Lu Ator over to help. When they examine Louis's code, they find that he has rewritten -the @t{expmod} procedure to use an explicit multiplication, rather than -calling @t{square}: +the @code{expmod} procedure to use an explicit multiplication, rather than +calling @code{square}: @lisp (define (expmod base exp m) @@ -4071,8 +4071,8 @@ which states that if @math{n} is a prime number and @math{a} is any positive int less than @math{n}, then @math{a} raised to the (@math{n-1})-st power is congruent to 1 modulo @math{n}. To test the primality of a number @math{n} by the Miller-Rabin test, we pick a random number @math{a < n} and raise @math{a} to the (@math{n-1})-st -power modulo @math{n} using the @t{expmod} procedure. However, whenever we -perform the squaring step in @t{expmod}, we check to see if we have +power modulo @math{n} using the @code{expmod} procedure. However, whenever we +perform the squaring step in @code{expmod}, we check to see if we have discovered a ``nontrivial square root of 1 modulo @math{n},'' that is, a number not equal to 1 or @math{n-1} whose square is equal to 1 modulo @math{n}. It is possible to prove that if such a nontrivial square root of 1 exists, then @math{n} @@ -4080,10 +4080,10 @@ is not prime. It is also possible to prove that if @math{n} is an odd number th is not prime, then, for at least half the numbers @math{a < n}, computing @math{a^{n-1}} in this way will reveal a nontrivial square root of 1 modulo @math{n}. (This is why the Miller-Rabin test cannot be fooled.) Modify the -@t{expmod} procedure to signal if it discovers a nontrivial square root of +@code{expmod} procedure to signal if it discovers a nontrivial square root of 1, and use this to implement the Miller-Rabin test with a procedure analogous -to @t{fermat-test}. Check your procedure by testing various known primes -and non-primes. Hint: One convenient way to make @t{expmod} signal is to +to @code{fermat-test}. Check your procedure by testing various known primes +and non-primes. Hint: One convenient way to make @code{expmod} signal is to have it return 0. @end quotation @@ -4111,7 +4111,7 @@ without ever defining this procedure, by always writing expressions such as @end lisp @noindent -and never mentioning @t{cube} explicitly. This would place us at a serious +and never mentioning @code{cube} explicitly. This would place us at a serious disadvantage, forcing us to work always at the level of the particular operations that happen to be primitives in the language (multiplication, in this case) rather than in terms of higher-level operations. Our programs would @@ -4134,7 +4134,7 @@ expressive power of our language. @menu * 1-3-1:: Procedures as Arguments -* 1-3-2:: Constructing Procedures Using @t{Lambda} +* 1-3-2:: Constructing Procedures Using @code{Lambda} * 1-3-3:: Procedures as General Methods * 1-3-4:: Procedures as Returned Values @end menu @@ -4143,7 +4143,7 @@ expressive power of our language. @subsection Procedures as Arguments Consider the following three procedures. The first computes the sum of the -integers from @t{a} through @t{b}: +integers from @code{a} through @code{b}: @lisp (define (sum-integers a b) @@ -4194,8 +4194,8 @@ fancy numerical tricks in @ref{3.5.3}.} @noindent These three procedures clearly share a common underlying pattern. They are for the most part identical, differing only in the name of the procedure, the -function of @t{a} used to compute the term to be added, and the function -that provides the next value of @t{a}. We could generate each of the +function of @code{a} used to compute the term to be added, and the function +that provides the next value of @code{a}. We could generate each of the procedures by filling in slots in the same template: @lisp @@ -4245,11 +4245,11 @@ and transforming the ``slots'' into formal parameters: @end lisp @noindent -Notice that @t{sum} takes as its arguments the lower and upper bounds -@t{a} and @t{b} together with the procedures @t{term} and @t{next}. -We can use @t{sum} just as we would any procedure. For example, we can use -it (along with a procedure @t{inc} that increments its argument by 1) to -define @t{sum-cubes}: +Notice that @code{sum} takes as its arguments the lower and upper bounds +@code{a} and @code{b} together with the procedures @code{term} and @code{next}. +We can use @code{sum} just as we would any procedure. For example, we can use +it (along with a procedure @code{inc} that increments its argument by 1) to +define @code{sum-cubes}: @lisp (define (inc n) (+ n 1)) @@ -4267,7 +4267,7 @@ Using this, we can compute the sum of the cubes of the integers from 1 to 10: @noindent With the aid of an identity procedure to compute the term, we can define -@t{sum-integers} in terms of @t{sum}: +@code{sum-integers} in terms of @code{sum}: @lisp (define (identity x) x) @@ -4284,9 +4284,9 @@ Then we can add up the integers from 1 to 10: @end lisp @noindent -We can also define @t{pi-sum} in the same way:@footnote{Notice that we have +We can also define @code{pi-sum} in the same way:@footnote{Notice that we have used block structure (@ref{1.1.8}) to embed the definitions of -@t{pi-next} and @t{pi-term} within @t{pi-sum}, since these procedures +@code{pi-next} and @code{pi-term} within @code{pi-sum}, since these procedures are unlikely to be useful for any other purpose. We will see how to get rid of them altogether in @ref{1.3.2}.} @@ -4308,7 +4308,7 @@ Using these procedures, we can compute an approximation to @math{\pi}: @end lisp @noindent -Once we have @t{sum}, we can use it as a building block in formulating +Once we have @code{sum}, we can use it as a building block in formulating further concepts. For instance, the definite integral of a function @math{f} between the limits @math{a} and @math{b} can be approximated numerically using the formula @@ -4344,7 +4344,7 @@ for small values of @math{d\!x}. We can express this directly as a procedure: @end lisp @noindent -(The exact value of the integral of @t{cube} between 0 and 1 is 1/4.) +(The exact value of the integral of @code{cube} between 0 and 1 is 1/4.) @quotation @strong{@anchor{Exercise 1.29}Exercise 1.29:} Simpson's Rule is a more accurate @@ -4369,13 +4369,13 @@ where @math{h = (b - a) \big/\!n}, for some even integer @math{n}, and @math{y_k = f(a + kh)}. (Increasing @math{n} increases the accuracy of the approximation.) Define a procedure that takes as arguments @math{f}, @math{a}, @math{b}, and @math{n} and returns the value of the integral, computed -using Simpson's Rule. Use your procedure to integrate @t{cube} between 0 +using Simpson's Rule. Use your procedure to integrate @code{cube} between 0 and 1 (with @math{n = 100} and @math{n = 1000}), and compare the results to those of -the @t{integral} procedure shown above. +the @code{integral} procedure shown above. @end quotation @quotation -@strong{@anchor{Exercise 1.30}Exercise 1.30:} The @t{sum} procedure above +@strong{@anchor{Exercise 1.30}Exercise 1.30:} The @code{sum} procedure above generates a linear recursion. The procedure can be rewritten so that the sum is performed iteratively. Show how to do this by filling in the missing expressions in the following definition: @@ -4395,7 +4395,7 @@ expressions in the following definition: @strong{@anchor{Exercise 1.31}Exercise 1.31:} @enumerate a @item -The @t{sum} procedure is only the simplest of a vast number of similar +The @code{sum} procedure is only the simplest of a vast number of similar abstractions that can be captured as higher-order procedures.@footnote{The intent of @ref{Exercise 1.31} through @ref{Exercise 1.33} is to demonstrate the expressive power that is attained by using an appropriate abstraction to @@ -4407,9 +4407,9 @@ of combination for these abstractions. We will return to these ideas in for combining filters and accumulators to build even more powerful abstractions. We will see there how these methods really come into their own as a powerful and elegant approach to designing programs.} Write an analogous -procedure called @t{product} that returns the product of the values of a -function at points over a given range. Show how to define @t{factorial} in -terms of @t{product}. Also use @t{product} to compute approximations to +procedure called @code{product} that returns the product of the values of a +function at points over a given range. Show how to define @code{factorial} in +terms of @code{product}. Also use @code{product} to compute approximations to @math{\pi} using the formula@footnote{This formula was discovered by the seventeenth-century English mathematician John Wallis.} @ifinfo @@ -4426,7 +4426,7 @@ $$ {\pi\over 4} = {2\cdot 4\cdot 4\cdot 6\cdot 6\cdot 8\cdot\dots\over 3\cdot 3\cdot 5\cdot 5\cdot 7\cdot 7\cdot\dots}\,. $$ @end tex @item -If your @t{product} procedure generates a recursive process, write one that +If your @code{product} procedure generates a recursive process, write one that generates an iterative process. If it generates an iterative process, write one that generates a recursive process. @@ -4438,8 +4438,8 @@ one that generates a recursive process. @strong{@anchor{Exercise 1.32}Exercise 1.32:} @enumerate a @item -Show that @t{sum} and @t{product} (@ref{Exercise 1.31}) are both special -cases of a still more general notion called @t{accumulate} that combines a +Show that @code{sum} and @code{product} (@ref{Exercise 1.31}) are both special +cases of a still more general notion called @code{accumulate} that combines a collection of terms, using some general accumulation function: @lisp @@ -4447,16 +4447,16 @@ collection of terms, using some general accumulation function: combiner null-value term a next b) @end lisp -@t{Accumulate} takes as arguments the same term and range specifications as -@t{sum} and @t{product}, together with a @t{combiner} procedure (of +@code{Accumulate} takes as arguments the same term and range specifications as +@code{sum} and @code{product}, together with a @code{combiner} procedure (of two arguments) that specifies how the current term is to be combined with the -accumulation of the preceding terms and a @t{null-value} that specifies what -base value to use when the terms run out. Write @t{accumulate} and show how -@t{sum} and @t{product} can both be defined as simple calls to -@t{accumulate}. +accumulation of the preceding terms and a @code{null-value} that specifies what +base value to use when the terms run out. Write @code{accumulate} and show how +@code{sum} and @code{product} can both be defined as simple calls to +@code{accumulate}. @item -If your @t{accumulate} procedure generates a recursive process, write one +If your @code{accumulate} procedure generates a recursive process, write one that generates an iterative process. If it generates an iterative process, write one that generates a recursive process. @@ -4466,19 +4466,19 @@ write one that generates a recursive process. @quotation @strong{@anchor{Exercise 1.33}Exercise 1.33:} You can obtain an even more -general version of @t{accumulate} (@ref{Exercise 1.32}) by introducing the +general version of @code{accumulate} (@ref{Exercise 1.32}) by introducing the notion of a @newterm{filter} on the terms to be combined. That is, combine only those terms derived from values in the range that satisfy a specified -condition. The resulting @t{filtered-accumulate} abstraction takes the same +condition. The resulting @code{filtered-accumulate} abstraction takes the same arguments as accumulate, together with an additional predicate of one argument -that specifies the filter. Write @t{filtered-accumulate} as a procedure. -Show how to express the following using @t{filtered-accumulate}: +that specifies the filter. Write @code{filtered-accumulate} as a procedure. +Show how to express the following using @code{filtered-accumulate}: @enumerate a @item the sum of the squares of the prime numbers in the interval @math{a} to @math{b} -(assuming that you have a @t{prime?} predicate already written) +(assuming that you have a @code{prime?} predicate already written) @item the product of all the positive integers less than @math{n} that are relatively @@ -4489,16 +4489,16 @@ prime to @math{n} (i.e., all positive integers @math{i < n} such that @end quotation @node 1.3.2, 1.3.3, 1.3.1, 1.3 -@subsection Constructing Procedures Using @t{Lambda} +@subsection Constructing Procedures Using @code{Lambda} -In using @t{sum} as in @ref{1.3.1}, it seems terribly awkward to -have to define trivial procedures such as @t{pi-term} and @t{pi-next} +In using @code{sum} as in @ref{1.3.1}, it seems terribly awkward to +have to define trivial procedures such as @code{pi-term} and @code{pi-next} just so we can use them as arguments to our higher-order procedure. Rather -than define @t{pi-next} and @t{pi-term}, it would be more convenient to +than define @code{pi-next} and @code{pi-term}, it would be more convenient to have a way to directly specify ``the procedure that returns its input incremented by 4'' and ``the procedure that returns the reciprocal of its input times its input plus 2.'' We can do this by introducing the special form -@t{lambda}, which creates procedures. Using @t{lambda} we can describe +@code{lambda}, which creates procedures. Using @code{lambda} we can describe what we want as @lisp @@ -4513,7 +4513,7 @@ and @end lisp @noindent -Then our @t{pi-sum} procedure can be expressed without defining any +Then our @code{pi-sum} procedure can be expressed without defining any auxiliary procedures as @lisp @@ -4525,8 +4525,8 @@ auxiliary procedures as @end lisp @noindent -Again using @t{lambda}, we can write the @t{integral} procedure without -having to define the auxiliary procedure @t{add-dx}: +Again using @code{lambda}, we can write the @code{integral} procedure without +having to define the auxiliary procedure @code{add-dx}: @lisp (define (integral f a b dx) @@ -4537,8 +4537,8 @@ having to define the auxiliary procedure @t{add-dx}: @end lisp @noindent -In general, @t{lambda} is used to create procedures in the same way as -@t{define}, except that no name is specified for the procedure: +In general, @code{lambda} is used to create procedures in the same way as +@code{define}, except that no name is specified for the procedure: @lisp (lambda (@math{\langle}@var{formal-parameters}@math{\rangle}) @math{\langle}@var{body}@math{\rangle}) @@ -4546,7 +4546,7 @@ In general, @t{lambda} is used to create procedures in the same way as @noindent The resulting procedure is just as much a procedure as one that is created -using @t{define}. The only difference is that it has not been associated +using @code{define}. The only difference is that it has not been associated with any name in the environment. In fact, @lisp @@ -4561,7 +4561,7 @@ is equivalent to @end lisp @noindent -We can read a @t{lambda} expression as follows: +We can read a @code{lambda} expression as follows: @smalllisp (lambda (x) (+ x 4)) @@ -4570,7 +4570,7 @@ the procedure of an argument x that adds x and 4 @end smalllisp @noindent -Like any expression that has a procedure as its value, a @t{lambda} +Like any expression that has a procedure as its value, a @code{lambda} expression can be used as the operator in a combination such as @lisp @@ -4581,7 +4581,7 @@ expression can be used as the operator in a combination such as @noindent or, more generally, in any context where we would normally use a procedure name.@footnote{It would be clearer and less intimidating to people learning -Lisp if a name more obvious than @t{lambda}, such as @t{make-procedure}, +Lisp if a name more obvious than @code{lambda}, such as @code{make-procedure}, were used. But the convention is firmly entrenched. The notation is adopted from the @math{\lambda}-calculus, a mathematical formalism introduced by the mathematical logician Alonzo @ref{Church (1941)}. Church developed the @@ -4590,9 +4590,9 @@ notions of function and function application. The @math{\lambda}-calculus has become a basic tool for mathematical investigations of the semantics of programming languages.} -@subsubheading Using @t{let} to create local variables +@subsubheading Using @code{let} to create local variables -Another use of @t{lambda} is in creating local variables. We often need +Another use of @code{lambda} is in creating local variables. We often need local variables in our procedures other than those that have been bound as formal parameters. For example, suppose we wish to compute the function @ifinfo @@ -4636,8 +4636,8 @@ auxiliary procedure to bind the local variables: @end lisp @noindent -Of course, we could use a @t{lambda} expression to specify an anonymous -procedure for binding our local variables. The body of @t{f} then becomes a +Of course, we could use a @code{lambda} expression to specify an anonymous +procedure for binding our local variables. The body of @code{f} then becomes a single call to that procedure: @lisp @@ -4649,8 +4649,8 @@ single call to that procedure: @end lisp @noindent -This construct is so useful that there is a special form called @t{let} to -make its use more convenient. Using @t{let}, the @t{f} procedure could +This construct is so useful that there is a special form called @code{let} to +make its use more convenient. Using @code{let}, the @code{f} procedure could be written as @lisp @@ -4663,7 +4663,7 @@ be written as @end lisp @noindent -The general form of a @t{let} expression is +The general form of a @code{let} expression is @lisp (let ((@math{\langle}@math{var_1}@math{\rangle} @math{\langle}@math{exp_1}@math{\rangle}) @@ -4685,10 +4685,10 @@ in @math{\langle}@var{body}@math{\rangle} @end example @noindent -The first part of the @t{let} expression is a list of name-expression pairs. -When the @t{let} is evaluated, each name is associated with the value of the -corresponding expression. The body of the @t{let} is evaluated with these -names bound as local variables. The way this happens is that the @t{let} +The first part of the @code{let} expression is a list of name-expression pairs. +When the @code{let} is evaluated, each name is associated with the value of the +corresponding expression. The body of the @code{let} is evaluated with these +names bound as local variables. The way this happens is that the @code{let} expression is interpreted as an alternate syntax for @lisp @@ -4701,17 +4701,17 @@ expression is interpreted as an alternate syntax for @noindent No new mechanism is required in the interpreter in order to provide local -variables. A @t{let} expression is simply syntactic sugar for the -underlying @t{lambda} application. +variables. A @code{let} expression is simply syntactic sugar for the +underlying @code{lambda} application. We can see from this equivalence that the scope of a variable specified by a -@t{let} expression is the body of the @t{let}. This implies that: +@code{let} expression is the body of the @code{let}. This implies that: @itemize @bullet @item -@t{Let} allows one to bind variables as locally as possible to where they -are to be used. For example, if the value of @t{x} is 5, the value of the +@code{Let} allows one to bind variables as locally as possible to where they +are to be used. For example, if the value of @code{x} is 5, the value of the expression @lisp @@ -4721,15 +4721,15 @@ expression @end lisp @noindent -is 38. Here, the @t{x} in the body of the @t{let} is 3, so the value of -the @t{let} expression is 33. On the other hand, the @t{x} that is the -second argument to the outermost @t{+} is still 5. +is 38. Here, the @code{x} in the body of the @code{let} is 3, so the value of +the @code{let} expression is 33. On the other hand, the @code{x} that is the +second argument to the outermost @code{+} is still 5. @item -The variables' values are computed outside the @t{let}. This matters when +The variables' values are computed outside the @code{let}. This matters when the expressions that provide the values for the local variables depend upon variables having the same names as the local variables themselves. For -example, if the value of @t{x} is 2, the expression +example, if the value of @code{x} is 2, the expression @lisp (let ((x 3) @@ -4738,14 +4738,14 @@ example, if the value of @t{x} is 2, the expression @end lisp @noindent -will have the value 12 because, inside the body of the @t{let}, @t{x} -will be 3 and @t{y} will be 4 (which is the outer @t{x} plus 2). +will have the value 12 because, inside the body of the @code{let}, @code{x} +will be 3 and @code{y} will be 4 (which is the outer @code{x} plus 2). @end itemize @noindent Sometimes we can use internal definitions to get the same effect as with -@t{let}. For example, we could have defined the procedure @t{f} above as +@code{let}. For example, we could have defined the procedure @code{f} above as @lisp (define (f x y) @@ -4758,8 +4758,8 @@ Sometimes we can use internal definitions to get the same effect as with @end lisp @noindent -We prefer, however, to use @t{let} in situations like this and to use -internal @t{define} only for internal procedures.@footnote{Understanding +We prefer, however, to use @code{let} in situations like this and to use +internal @code{define} only for internal procedures.@footnote{Understanding internal definitions well enough to be sure a program means what we intend it to mean requires a more elaborate model of the evaluation process than we have presented in this chapter. The subtleties do not arise with internal @@ -4784,7 +4784,7 @@ Then we have @end lisp What happens if we (perversely) ask the interpreter to evaluate the combination -@t{(f f)}? Explain. +@code{(f f)}? Explain. @end quotation @node 1.3.3, 1.3.4, 1.3.2, 1.3 @@ -4793,7 +4793,7 @@ What happens if we (perversely) ask the interpreter to evaluate the combination We introduced compound procedures in @ref{1.1.4} as a mechanism for abstracting patterns of numerical operations so as to make them independent of the particular numbers involved. With higher-order procedures, such as the -@t{integral} procedure of @ref{1.3.1}, we began to see a more +@code{integral} procedure of @ref{1.3.1}, we began to see a more powerful kind of abstraction: procedures used to express general methods of computation, independent of the particular functions involved. In this section we discuss two more elaborate examples---general methods for finding zeros and @@ -4860,14 +4860,14 @@ other kind of magician.} @end lisp @noindent -@t{Search} is awkward to use directly, because we can accidentally give it +@code{Search} is awkward to use directly, because we can accidentally give it points at which @math{f}'s values do not have the required sign, in which case we -get a wrong answer. Instead we will use @t{search} via the following +get a wrong answer. Instead we will use @code{search} via the following procedure, which checks to see which of the endpoints has a negative function -value and which has a positive value, and calls the @t{search} procedure +value and which has a positive value, and calls the @code{search} procedure accordingly. If the function has the same sign on the two given points, the half-interval method cannot be used, in which case the procedure signals an -error.@footnote{This can be accomplished using @t{error}, which takes as +error.@footnote{This can be accomplished using @code{error}, which takes as arguments a number of items that are printed as error messages.} @lisp @@ -4924,7 +4924,7 @@ $$ f(x),\quad f(f(x)),\quad f(f(f(x))), \quad\dots, $$ @end tex @noindent until the value does not change very much. Using this idea, we can devise a -procedure @t{fixed-point} that takes as inputs a function and an initial +procedure @code{fixed-point} that takes as inputs a function and an initial guess and produces an approximation to a fixed point of the function. We apply the function repeatedly until we find two successive values whose difference is less than some prescribed tolerance: @@ -4947,7 +4947,7 @@ less than some prescribed tolerance: For example, we can use this method to approximate the fixed point of the cosine function, starting with 1 as an initial approximation:@footnote{Try this during a boring lecture: Set your calculator to radians mode and then -repeatedly press the @t{cos} button until you obtain the fixed point.} +repeatedly press the @code{cos} button until you obtain the fixed point.} @lisp (fixed-point cos 1.0) @@ -4973,7 +4973,7 @@ Computing the square root of some number @math{x} requires finding a @math{y} su that @math{y^2 = x}. Putting this equation into the equivalent form @math{y = x \big/\! y}, we recognize that we are looking for a fixed point of the function@footnote{@math{\mapsto} (pronounced ``maps to'') is the mathematician's way of -writing @t{lambda}. @math{y \mapsto x \big/\! y} means @t{(lambda (y) (/ x y))}, +writing @code{lambda}. @math{y \mapsto x \big/\! y} means @code{(lambda (y) (/ x y))}, that is, the function whose value at @math{y} is @math{x \big/\! y}.} @math{y \mapsto x \big/\! y}, and we can therefore try to compute square roots as @@ -5022,18 +5022,18 @@ averaging successive approximations to a solution, a technique that we call @strong{@anchor{Exercise 1.35}Exercise 1.35:} Show that the golden ratio @math{\varphi} (@ref{1.2.2}) is a fixed point of the transformation @math{x \mapsto 1 + 1 \big/\! x}, and use this fact to compute @math{\varphi} by means -of the @t{fixed-point} procedure. +of the @code{fixed-point} procedure. @end quotation @quotation -@strong{@anchor{Exercise 1.36}Exercise 1.36:} Modify @t{fixed-point} so that -it prints the sequence of approximations it generates, using the @t{newline} -and @t{display} primitives shown in @ref{Exercise 1.22}. Then find a +@strong{@anchor{Exercise 1.36}Exercise 1.36:} Modify @code{fixed-point} so that +it prints the sequence of approximations it generates, using the @code{newline} +and @code{display} primitives shown in @ref{Exercise 1.22}. Then find a solution to @math{x^x = 1000} by finding a fixed point of @math{x \mapsto -\log(1000) \big/\! \log(x)}. (Use Scheme's primitive @t{log} +\log(1000) \big/\! \log(x)}. (Use Scheme's primitive @code{log} procedure, which computes natural logarithms.) Compare the number of steps this takes with and without average damping. (Note that you cannot start -@t{fixed-@/point} with a guess of 1, as this would cause division by +@code{fixed-@/point} with a guess of 1, as this would cause division by @math{\log(1) = 0}.) @end quotation @@ -5088,10 +5088,10 @@ D_1 + ----------- @tex $$ {N_1 \over {D_1 + {N_2 \over {\ddots + {N_k \over D_k}}}}}\,. $$ @end tex -Suppose that @t{n} and @t{d} are procedures of one argument (the term +Suppose that @code{n} and @code{d} are procedures of one argument (the term index @math{i}) that return the @math{N_i} and @math{D_i} of the terms of the -continued fraction. Define a procedure @t{cont-frac} such that evaluating -@t{(cont-frac n d k)} computes the value of the @math{k}-term finite continued +continued fraction. Define a procedure @code{cont-frac} such that evaluating +@code{(cont-frac n d k)} computes the value of the @math{k}-term finite continued fraction. Check your procedure by approximating @math{1 \big/ \varphi} using @lisp @@ -5101,11 +5101,11 @@ fraction. Check your procedure by approximating @math{1 \big/ \varphi} using @end lisp @noindent -for successive values of @t{k}. How large must you make @t{k} in order +for successive values of @code{k}. How large must you make @code{k} in order to get an approximation that is accurate to 4 decimal places? @item -If your @t{cont-frac} procedure generates a recursive process, write one +If your @code{cont-frac} procedure generates a recursive process, write one that generates an iterative process. If it generates an iterative process, write one that generates a recursive process. @@ -5118,7 +5118,7 @@ Leonhard Euler published a memoir @cite{De Fractionibus Continuis}, which included a continued fraction expansion for @math{e - 2}, where @math{e} is the base of the natural logarithms. In this fraction, the @math{N_i} are all 1, and the @math{D_i} are successively 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, @dots{}. -Write a program that uses your @t{cont-frac} procedure from @ref{Exercise 1.37} +Write a program that uses your @code{cont-frac} procedure from @ref{Exercise 1.37} to approximate @math{e}, based on Euler's expansion. @end quotation @@ -5143,9 +5143,9 @@ tan x = --------------- $$ {\tan x} = {x \over {1 - {x^2 \over {3 - {x^2 \over 5 - \dots}}}}}\,, $$ @end tex @noindent -where @math{x} is in radians. Define a procedure @t{(tan-cf x k)} that +where @math{x} is in radians. Define a procedure @code{(tan-cf x k)} that computes an approximation to the tangent function based on Lambert's formula. -@t{k} specifies the number of terms to compute, as in @ref{Exercise 1.37}. +@code{k} specifies the number of terms to compute, as in @ref{Exercise 1.37}. @end quotation @node 1.3.4, , 1.3.3, 1.3 @@ -5174,10 +5174,10 @@ We can express the idea of average damping by means of the following procedure: @end lisp @noindent -@t{Average-damp} is a procedure that takes as its argument a procedure -@t{f} and returns as its value a procedure (produced by the @t{lambda}) -that, when applied to a number @t{x}, produces the average of @t{x} and -@t{(f x)}. For example, applying @t{average-damp} to the @t{square} +@code{Average-damp} is a procedure that takes as its argument a procedure +@code{f} and returns as its value a procedure (produced by the @code{lambda}) +that, when applied to a number @code{x}, produces the average of @code{x} and +@code{(f x)}. For example, applying @code{average-damp} to the @code{square} procedure produces a procedure whose value at some number @math{x} is the average of @math{x} and @math{x^2}. Applying this resulting procedure to 10 returns the average of 10 and 100, or 55:@footnote{Observe that this is a combination whose @@ -5192,7 +5192,7 @@ that is obtained as the value returned by a higher-order procedure.} @end lisp @noindent -Using @t{average-damp}, we can reformulate the square-root procedure as +Using @code{average-damp}, we can reformulate the square-root procedure as follows: @lisp @@ -5302,7 +5302,7 @@ along with the definition @end lisp @noindent -Like @t{average-damp}, @t{deriv} is a procedure that takes a procedure as +Like @code{average-damp}, @code{deriv} is a procedure that takes a procedure as argument and returns a procedure as value. For example, to approximate the derivative of @math{x \mapsto x^3} at 5 (whose exact value is 75) we can evaluate @@ -5313,7 +5313,7 @@ derivative of @math{x \mapsto x^3} at 5 (whose exact value is 75) we can evaluat @end lisp @noindent -With the aid of @t{deriv}, we can express Newton's method as a fixed-point +With the aid of @code{deriv}, we can express Newton's method as a fixed-point process: @lisp @@ -5326,8 +5326,8 @@ process: @end lisp @noindent -The @t{newton-transform} procedure expresses the formula at the beginning of -this section, and @t{newtons-method} is readily defined in terms of this. +The @code{newton-transform} procedure expresses the formula at the beginning of +this section, and @code{newtons-method} is readily defined in terms of this. It takes as arguments a procedure that computes the function for which we want to find a zero, together with an initial guess. For instance, to find the square root of @math{x}, we can use Newton's method to find a zero of the function @@ -5361,8 +5361,8 @@ function. We can express this general idea itself as a procedure: @end lisp @noindent -This very general procedure takes as its arguments a procedure @t{g} that -computes some function, a procedure that transforms @t{g}, and an initial +This very general procedure takes as its arguments a procedure @code{g} that +computes some function, a procedure that transforms @code{g}, and an initial guess. The returned result is a fixed point of the transformed function. Using this abstraction, we can recast the first square-root computation from @@ -5443,8 +5443,8 @@ will study in @ref{4.1}, these variables are stored in the procedure's environment.} @quotation -@strong{@anchor{Exercise 1.40}Exercise 1.40:} Define a procedure @t{cubic} -that can be used together with the @t{newtons-method} procedure in +@strong{@anchor{Exercise 1.40}Exercise 1.40:} Define a procedure @code{cubic} +that can be used together with the @code{newtons-method} procedure in expressions of the form @lisp @@ -5456,10 +5456,10 @@ to approximate zeros of the cubic @math{x^3 + ax^2 + bx + c}. @end quotation @quotation -@strong{@anchor{Exercise 1.41}Exercise 1.41:} Define a procedure @t{double} +@strong{@anchor{Exercise 1.41}Exercise 1.41:} Define a procedure @code{double} that takes a procedure of one argument as argument and returns a procedure that -applies the original procedure twice. For example, if @t{inc} is a -procedure that adds 1 to its argument, then @t{(double inc)} should be a +applies the original procedure twice. For example, if @code{inc} is a +procedure that adds 1 to its argument, then @code{(double inc)} should be a procedure that adds 2. What value is returned by @lisp @@ -5471,7 +5471,7 @@ procedure that adds 2. What value is returned by @strong{@anchor{Exercise 1.42}Exercise 1.42:} Let @math{f} and @math{g} be two one-argument functions. The @newterm{composition} @math{f} after @math{g} is defined to be the function @math{x \mapsto f(g(x))}. Define a procedure -@t{compose} that implements composition. For example, if @t{inc} is a +@code{compose} that implements composition. For example, if @code{inc} is a procedure that adds 1 to its argument, @lisp @@ -5498,7 +5498,7 @@ procedure should be able to be used as follows: @i{625} @end lisp -Hint: You may find it convenient to use @t{compose} from @ref{Exercise 1.42}. +Hint: You may find it convenient to use @code{compose} from @ref{Exercise 1.42}. @end quotation @quotation @@ -5507,12 +5507,12 @@ function is an important concept in signal processing. If @math{f} is a functio and @math{d\!x} is some small number, then the smoothed version of @math{f} is the function whose value at a point @math{x} is the average of @math{f(x - d\!x)}, @math{f(x)}, and @math{f(x + d\!x)}. Write a procedure -@t{smooth} that takes as input a procedure that computes @math{f} and returns a +@code{smooth} that takes as input a procedure that computes @math{f} and returns a procedure that computes the smoothed @math{f}. It is sometimes valuable to repeatedly smooth a function (that is, smooth the smoothed function, and so on) to obtain the @newterm{@i{n}-fold smoothed function}. Show how to generate -the @i{n}-fold smoothed function of any given function using @t{smooth} and -@t{repeated} from @ref{Exercise 1.43,,Ex. 1.43}. +the @i{n}-fold smoothed function of any given function using @code{smooth} and +@code{repeated} from @ref{Exercise 1.43,,Ex. 1.43}. @end quotation @quotation @@ -5528,8 +5528,8 @@ we average damp twice (i.e., use the average damp of the average damp of to determine how many average damps are required to compute @math{n^{\hbox{\ordrm th}}} roots as a fixed-point search based upon repeated average damping of @math{y \mapsto x \big/\! y^{n-1}}. Use this to implement a simple procedure for computing -@math{n^{\hbox{\ordrm th}}} roots using @t{fixed-point}, @t{average-damp}, and the -@t{repeated} procedure of @ref{Exercise 1.43}. Assume that any arithmetic +@math{n^{\hbox{\ordrm th}}} roots using @code{fixed-point}, @code{average-damp}, and the +@code{repeated} procedure of @ref{Exercise 1.43}. Assume that any arithmetic operations you need are available as primitives. @end quotation @@ -5540,13 +5540,13 @@ strategy known as @newterm{iterative improvement}. Iterative improvement says that, to compute something, we start with an initial guess for the answer, test if the guess is good enough, and otherwise improve the guess and continue the process using the improved guess as the new guess. Write a procedure -@t{iterative-improve} that takes two procedures as arguments: a method for +@code{iterative-improve} that takes two procedures as arguments: a method for telling whether a guess is good enough and a method for improving a guess. -@t{Iterative-improve} should return as its value a procedure that takes a +@code{Iterative-improve} should return as its value a procedure that takes a guess as argument and keeps improving the guess until it is good enough. -Rewrite the @t{sqrt} procedure of @ref{1.1.7} and the -@t{fixed-point} procedure of @ref{1.3.3} in terms of -@t{iterative-improve}. +Rewrite the @code{sqrt} procedure of @ref{1.1.7} and the +@code{fixed-point} procedure of @ref{1.3.3} in terms of +@code{iterative-improve}. @end quotation @node Chapter 2, Chapter 3, Chapter 1, Top @@ -5568,7 +5568,7 @@ We concentrated in @ref{Chapter 1} on computational processes and on the role of procedures in program design. We saw how to use primitive data (numbers) and primitive operations (arithmetic operations), how to combine procedures to form compound procedures through composition, conditionals, and the use of -parameters, and how to abstract procedures by using @t{define}. We saw that +parameters, and how to abstract procedures by using @code{define}. We saw that a procedure can be regarded as a pattern for the local evolution of a process, and we classified, reasoned about, and performed simple algorithmic analyses of some common patterns for processes as embodied in procedures. We also saw that @@ -5597,11 +5597,11 @@ compound data objects enables us to deal with data at a higher conceptual level than that of the primitive data objects of the language. Consider the task of designing a system to perform arithmetic with rational -numbers. We could imagine an operation @t{add-rat} that takes two rational +numbers. We could imagine an operation @code{add-rat} that takes two rational numbers and produces their sum. In terms of simple data, a rational number can be thought of as two integers: a numerator and a denominator. Thus, we could design a program in which each rational number would be represented by two -integers (a numerator and a denominator) and where @t{add-rat} would be +integers (a numerator and a denominator) and where @code{add-rat} would be implemented by two procedures (one producing the numerator of the sum and one producing the denominator). But this would be awkward, because we would then need to explicitly keep track of which numerators corresponded to which @@ -5649,31 +5649,31 @@ procedure of the form @end lisp @noindent -where @t{add} and @t{mul} are not the primitive procedures @t{+} and -@t{*} but rather more complex things that will perform the appropriate -operations for whatever kinds of data we pass in as the arguments @t{a}, -@t{b}, @t{x}, and @t{y}. The key point is that the only thing -@t{linear-combination} should need to know about @t{a}, @t{b}, -@t{x}, and @t{y} is that the procedures @t{add} and @t{mul} will +where @code{add} and @code{mul} are not the primitive procedures @code{+} and +@code{*} but rather more complex things that will perform the appropriate +operations for whatever kinds of data we pass in as the arguments @code{a}, +@code{b}, @code{x}, and @code{y}. The key point is that the only thing +@code{linear-combination} should need to know about @code{a}, @code{b}, +@code{x}, and @code{y} is that the procedures @code{add} and @code{mul} will perform the appropriate manipulations. From the perspective of the procedure -@t{linear-combination}, it is irrelevant what @t{a}, @t{b}, @t{x}, -and @t{y} are and even more irrelevant how they might happen to be +@code{linear-combination}, it is irrelevant what @code{a}, @code{b}, @code{x}, +and @code{y} are and even more irrelevant how they might happen to be represented in terms of more primitive data. This same example shows why it is important that our programming language provide the ability to manipulate compound objects directly: Without this, there is no way for a procedure such -as @t{linear-combination} to pass its arguments along to @t{add} and -@t{mul} without having to know their detailed structure.@footnote{The +as @code{linear-combination} to pass its arguments along to @code{add} and +@code{mul} without having to know their detailed structure.@footnote{The ability to directly manipulate procedures provides an analogous increase in the expressive power of a programming language. For example, in -@ref{1.3.1} we introduced the @t{sum} procedure, which takes a procedure -@t{term} as an argument and computes the sum of the values of @t{term} -over some specified interval. In order to define @t{sum}, it is crucial -that we be able to speak of a procedure such as @t{term} as an entity in its -own right, without regard for how @t{term} might be expressed with more +@ref{1.3.1} we introduced the @code{sum} procedure, which takes a procedure +@code{term} as an argument and computes the sum of the values of @code{term} +over some specified interval. In order to define @code{sum}, it is crucial +that we be able to speak of a procedure such as @code{term} as an entity in its +own right, without regard for how @code{term} might be expressed with more primitive operations. Indeed, if we did not have the notion of ``a procedure,'' it is doubtful that we would ever even think of the possibility of -defining an operation such as @t{sum}. Moreover, insofar as performing the -summation is concerned, the details of how @t{term} may be constructed from +defining an operation such as @code{sum}. Moreover, insofar as performing the +summation is concerned, the details of how @code{term} may be constructed from more primitive operations are irrelevant.} We begin this chapter by implementing the rational-number arithmetic system @@ -5798,10 +5798,10 @@ available as procedures: @noindent We are using here a powerful strategy of synthesis: @newterm{wishful thinking}. We haven't yet said how a rational number is represented, or how the procedures -@t{numer}, @t{denom}, and @t{make-rat} should be implemented. Even +@code{numer}, @code{denom}, and @code{make-rat} should be implemented. Even so, if we did have these three procedures, we could then add, subtract, multiply, divide, and test equality by using the following relations: -@sp -2 +@sp -0.8 @ifinfo @example @@ -5867,7 +5867,7 @@ We can express these rules as procedures: @noindent Now we have the operations on rational numbers defined in terms of the selector -and constructor procedures @t{numer}, @t{denom}, and @t{make-rat}. +and constructor procedures @code{numer}, @code{denom}, and @code{make-rat}. But we haven't yet defined these. What we need is some way to glue together a numerator and a denominator to form a rational number. @@ -5875,17 +5875,17 @@ numerator and a denominator to form a rational number. To enable us to implement the concrete level of our data abstraction, our language provides a compound structure called a @newterm{pair}, which can be -constructed with the primitive procedure @t{cons}. This procedure takes two +constructed with the primitive procedure @code{cons}. This procedure takes two arguments and returns a compound data object that contains the two arguments as parts. Given a pair, we can extract the parts using the primitive procedures -@t{car} and @t{cdr}.@footnote{The name @t{cons} stands for -``construct.'' The names @t{car} and @t{cdr} derive from the original +@code{car} and @code{cdr}.@footnote{The name @code{cons} stands for +``construct.'' The names @code{car} and @code{cdr} derive from the original implementation of Lisp on the IBM 704. That machine had an addressing scheme that allowed one to reference the ``address'' and ``decrement'' parts of a -memory location. @t{Car} stands for ``Contents of Address part of -Register'' and @t{cdr} (pronounced ``could-er'') stands for ``Contents of -Decrement part of Register.''} Thus, we can use @t{cons}, @t{car}, and -@t{cdr} as follows: +memory location. @code{Car} stands for ``Contents of Address part of +Register'' and @code{cdr} (pronounced ``could-er'') stands for ``Contents of +Decrement part of Register.''} Thus, we can use @code{cons}, @code{car}, and +@code{cdr} as follows: @lisp @@ -5899,7 +5899,7 @@ Decrement part of Register.''} Thus, we can use @t{cons}, @t{car}, and @noindent Notice that a pair is a data object that can be given a name and manipulated, -just like a primitive data object. Moreover, @t{cons} can be used to form +just like a primitive data object. Moreover, @code{cons} can be used to form pairs whose elements are pairs, and so on: @lisp @@ -5917,7 +5917,7 @@ pairs whose elements are pairs, and so on: In @ref{2.2} we will see how this ability to combine pairs means that pairs can be used as general-purpose building blocks to create all sorts of complex data structures. The single compound-data primitive @newterm{pair}, -implemented by the procedures @t{cons}, @t{car}, and @t{cdr}, is the +implemented by the procedures @code{cons}, @code{car}, and @code{cdr}, is the only glue we need. Data objects constructed from pairs are called @newterm{list-structured} data. @@ -5926,7 +5926,7 @@ only glue we need. Data objects constructed from pairs are called Pairs offer a natural way to complete the rational-number system. Simply represent a rational number as a pair of two integers: a numerator and a -denominator. Then @t{make-rat}, @t{numer}, and @t{denom} are readily +denominator. Then @code{make-rat}, @code{numer}, and @code{denom} are readily implemented as follows:@footnote{Another way to define the selectors and constructor is @@ -5936,18 +5936,18 @@ constructor is (define denom cdr) @end lisp -The first definition associates the name @t{make-rat} with the value of the -expression @t{cons}, which is the primitive procedure that constructs pairs. -Thus @t{make-rat} and @t{cons} are names for the same primitive +The first definition associates the name @code{make-rat} with the value of the +expression @code{cons}, which is the primitive procedure that constructs pairs. +Thus @code{make-rat} and @code{cons} are names for the same primitive constructor. Defining selectors and constructors in this way is efficient: Instead of -@t{make-rat} @emph{calling} @t{cons}, @t{make-rat} @emph{is} -@t{cons}, so there is only one procedure called, not two, when -@t{make-rat} is called. On the other hand, doing this defeats debugging +@code{make-rat} @emph{calling} @code{cons}, @code{make-rat} @emph{is} +@code{cons}, so there is only one procedure called, not two, when +@code{make-rat} is called. On the other hand, doing this defeats debugging aids that trace procedure calls or put breakpoints on procedure calls: You may -want to watch @t{make-rat} being called, but you certainly don't want to -watch every call to @t{cons}. +want to watch @code{make-rat} being called, but you certainly don't want to +watch every call to @code{cons}. We have chosen not to use this style of definition in this book.} @@ -5960,11 +5960,11 @@ We have chosen not to use this style of definition in this book.} @noindent Also, in order to display the results of our computations, we can print rational numbers by printing the numerator, a slash, and the -denominator:@footnote{@t{Display} is the Scheme primitive for printing data. -The Scheme primitive @t{newline} starts a new line for printing. Neither of -these procedures returns a useful value, so in the uses of @t{print-rat} -below, we show only what @t{print-rat} prints, not what the interpreter -prints as the value returned by @t{print-rat}.} +denominator:@footnote{@code{Display} is the Scheme primitive for printing data. +The Scheme primitive @code{newline} starts a new line for printing. Neither of +these procedures returns a useful value, so in the uses of @code{print-rat} +below, we show only what @code{print-rat} prints, not what the interpreter +prints as the value returned by @code{print-rat}.} @lisp (define (print-rat x) @@ -5996,9 +5996,9 @@ Now we can try our rational-number procedures: @noindent As the final example shows, our rational-number implementation does not reduce rational numbers to lowest terms. We can remedy this by changing -@t{make-rat}. If we have a @t{gcd} procedure like the one in +@code{make-rat}. If we have a @code{gcd} procedure like the one in @ref{1.2.5} that produces the greatest common divisor of two integers, we can -use @t{gcd} to reduce the numerator and the denominator to lowest terms +use @code{gcd} to reduce the numerator and the denominator to lowest terms before constructing the pair: @lisp @@ -6019,13 +6019,13 @@ Now we have @noindent as desired. This modification was accomplished by changing the constructor -@t{make-rat} without changing any of the procedures (such as @t{add-rat} -and @t{mul-rat}) that implement the actual operations. +@code{make-rat} without changing any of the procedures (such as @code{add-rat} +and @code{mul-rat}) that implement the actual operations. @quotation @strong{@anchor{Exercise 2.1}Exercise 2.1:} Define a better version of -@t{make-rat} that handles both positive and negative arguments. -@t{Make-rat} should normalize the sign so that if the rational number is +@code{make-rat} that handles both positive and negative arguments. +@code{Make-rat} should normalize the sign so that if the rational number is positive, both the numerator and denominator are positive, and if the rational number is negative, only the numerator is negative. @end quotation @@ -6036,7 +6036,7 @@ number is negative, only the numerator is negative. Before continuing with more examples of compound data and data abstraction, let us consider some of the issues raised by the rational-number example. We defined the rational-number operations in terms of a constructor -@t{make-rat} and selectors @t{numer} and @t{denom}. In general, the +@code{make-rat} and selectors @code{numer} and @code{denom}. In general, the underlying idea of data abstraction is to identify for each type of data object a basic set of operations in terms of which all manipulations of data objects of that type will be expressed, and then to use only those operations in @@ -6048,13 +6048,13 @@ barriers} that isolate different ``levels'' of the system. At each level, the barrier separates the programs (above) that use the data abstraction from the programs (below) that implement the data abstraction. Programs that use rational numbers manipulate them solely in terms of the procedures supplied -``for public use'' by the rational-number package: @t{add-rat}, -@t{sub-rat}, @t{mul-rat}, @t{div-rat}, and @t{equal-rat?}. These, +``for public use'' by the rational-number package: @code{add-rat}, +@code{sub-rat}, @code{mul-rat}, @code{div-rat}, and @code{equal-rat?}. These, in turn, are implemented solely in terms of the constructor and selectors -@t{make-rat}, @t{numer}, and @t{denom}, which themselves are +@code{make-rat}, @code{numer}, and @code{denom}, which themselves are implemented in terms of pairs. The details of how pairs are implemented are irrelevant to the rest of the rational-number package so long as pairs can be -manipulated by the use of @t{cons}, @t{car}, and @t{cdr}. In effect, +manipulated by the use of @code{cons}, @code{car}, and @code{cdr}. In effect, procedures at each level are the interfaces that define the abstraction barriers and connect the different levels. @@ -6124,19 +6124,19 @@ different constructor and selector procedures: @noindent The difference between this implementation and the previous one lies in when we -compute the @t{gcd}. If in our typical use of rational numbers we access +compute the @code{gcd}. If in our typical use of rational numbers we access the numerators and denominators of the same rational numbers many times, it -would be preferable to compute the @t{gcd} when the rational numbers are +would be preferable to compute the @code{gcd} when the rational numbers are constructed. If not, we may be better off waiting until access time to compute -the @t{gcd}. In any case, when we change from one representation to the -other, the procedures @t{add-rat}, @t{sub-rat}, and so on do not have to +the @code{gcd}. In any case, when we change from one representation to the +other, the procedures @code{add-rat}, @code{sub-rat}, and so on do not have to be modified at all. Constraining the dependence on the representation to a few interface procedures helps us design programs as well as modify them, because it allows us to maintain the flexibility to consider alternate implementations. To continue with our simple example, suppose we are designing a rational-number package and -we can't decide initially whether to perform the @t{gcd} at construction +we can't decide initially whether to perform the @code{gcd} at construction time or at selection time. The data-abstraction methodology gives us a way to defer that decision without losing the ability to make progress on the rest of the system. @@ -6145,13 +6145,13 @@ the system. @strong{@anchor{Exercise 2.2}Exercise 2.2:} Consider the problem of representing line segments in a plane. Each segment is represented as a pair of points: a starting point and an ending point. Define a constructor -@t{make-segment} and selectors @t{start-segment} and @t{end-segment} +@code{make-segment} and selectors @code{start-segment} and @code{end-segment} that define the representation of segments in terms of points. Furthermore, a point can be represented as a pair of numbers: the @math{x} coordinate and the -@math{y} coordinate. Accordingly, specify a constructor @t{make-point} and -selectors @t{x-point} and @t{y-point} that define this representation. +@math{y} coordinate. Accordingly, specify a constructor @code{make-point} and +selectors @code{x-point} and @code{y-point} that define this representation. Finally, using your selectors and constructors, define a procedure -@t{midpoint-segment} that takes a line segment as argument and returns its +@code{midpoint-segment} that takes a line segment as argument and returns its midpoint (the point whose coordinates are the average of the coordinates of the endpoints). To try your procedures, you'll need a way to print points: @@ -6180,9 +6180,9 @@ using either representation? @subsection What Is Meant by Data? We began the rational-number implementation in @ref{2.1.1} by -implementing the rational-number operations @t{add-rat}, @t{sub-rat}, and -so on in terms of three unspecified procedures: @t{make-rat}, @t{numer}, -and @t{denom}. At that point, we could think of the operations as being +implementing the rational-number operations @code{add-rat}, @code{sub-rat}, and +so on in terms of three unspecified procedures: @code{make-rat}, @code{numer}, +and @code{denom}. At that point, we could think of the operations as being defined in terms of data objects---numerators, denominators, and rational numbers---whose behavior was specified by the latter three procedures. @@ -6190,12 +6190,12 @@ But exactly what is meant by @newterm{data}? It is not enough to say ``whatever is implemented by the given selectors and constructors.'' Clearly, not every arbitrary set of three procedures can serve as an appropriate basis for the rational-number implementation. We need to guarantee that, if we -construct a rational number @t{x} from a pair of integers @t{n} and -@t{d}, then extracting the @t{numer} and the @t{denom} of @t{x} and -dividing them should yield the same result as dividing @t{n} by @t{d}. -In other words, @t{make-rat}, @t{numer}, and @t{denom} must satisfy -the condition that, for any integer @t{n} and any non-zero integer @t{d}, -if @t{x} is @t{(make-rat n d)}, then +construct a rational number @code{x} from a pair of integers @code{n} and +@code{d}, then extracting the @code{numer} and the @code{denom} of @code{x} and +dividing them should yield the same result as dividing @code{n} by @code{d}. +In other words, @code{make-rat}, @code{numer}, and @code{denom} must satisfy +the condition that, for any integer @code{n} and any non-zero integer @code{d}, +if @code{x} is @code{(make-rat n d)}, then @ifinfo @example @@ -6208,8 +6208,8 @@ if @t{x} is @t{(make-rat n d)}, then @tex $$ {\hbox{\tt(numer x)} \over \hbox{\tt(denom x)}} = {{\tt n} \over {\tt d}}\,. $$ @end tex -In fact, this is the only condition @t{make-rat}, @t{numer}, and -@t{denom} must fulfill in order to form a suitable basis for a +In fact, this is the only condition @code{make-rat}, @code{numer}, and +@code{denom} must fulfill in order to form a suitable basis for a rational-number representation. In general, we can think of data as defined by some collection of selectors and constructors, together with specified conditions that these procedures must fulfill in order to be a valid @@ -6236,16 +6236,16 @@ This point of view can serve to define not only ``high-level'' data objects, such as rational numbers, but lower-level objects as well. Consider the notion of a pair, which we used in order to define our rational numbers. We never actually said what a pair was, only that the language supplied procedures -@t{cons}, @t{car}, and @t{cdr} for operating on pairs. But the only +@code{cons}, @code{car}, and @code{cdr} for operating on pairs. But the only thing we need to know about these three operations is that if we glue two -objects together using @t{cons} we can retrieve the objects using @t{car} -and @t{cdr}. That is, the operations satisfy the condition that, for any -objects @t{x} and @t{y}, if @t{z} is @t{(cons x y)} then @t{(car -z)} is @t{x} and @t{(cdr z)} is @t{y}. Indeed, we mentioned that +objects together using @code{cons} we can retrieve the objects using @code{car} +and @code{cdr}. That is, the operations satisfy the condition that, for any +objects @code{x} and @code{y}, if @code{z} is @code{(cons x y)} then @code{(car +z)} is @code{x} and @code{(cdr z)} is @code{y}. Indeed, we mentioned that these three procedures are included as primitives in our language. However, any triple of procedures that satisfies the above condition can be used as the basis for implementing pairs. This point is illustrated strikingly by the fact -that we could implement @t{cons}, @t{car}, and @t{cdr} without using +that we could implement @code{cons}, @code{car}, and @code{cdr} without using any data structures at all but only using procedures. Here are the definitions: @@ -6268,17 +6268,17 @@ data should be. Nevertheless, all we need to do to show that this is a valid way to represent pairs is to verify that these procedures satisfy the condition given above. -The subtle point to notice is that the value returned by @t{(cons x y)} is a -procedure---namely the internally defined procedure @t{dispatch}, which -takes one argument and returns either @t{x} or @t{y} depending on whether -the argument is 0 or 1. Correspondingly, @t{(car z)} is defined to apply -@t{z} to 0. Hence, if @t{z} is the procedure formed by @t{(cons x -y)}, then @t{z} applied to 0 will yield @t{x}. Thus, we have shown that -@t{(car (cons x y))} yields @t{x}, as desired. Similarly, @t{(cdr -(cons x y))} applies the procedure returned by @t{(cons x y)} to 1, which -returns @t{y}. Therefore, this procedural implementation of pairs is a -valid implementation, and if we access pairs using only @t{cons}, -@t{car}, and @t{cdr} we cannot distinguish this implementation from one +The subtle point to notice is that the value returned by @code{(cons x y)} is a +procedure---namely the internally defined procedure @code{dispatch}, which +takes one argument and returns either @code{x} or @code{y} depending on whether +the argument is 0 or 1. Correspondingly, @code{(car z)} is defined to apply +@code{z} to 0. Hence, if @code{z} is the procedure formed by @code{(cons x +y)}, then @code{z} applied to 0 will yield @code{x}. Thus, we have shown that +@code{(car (cons x y))} yields @code{x}, as desired. Similarly, @code{(cdr +(cons x y))} applies the procedure returned by @code{(cons x y)} to 1, which +returns @code{y}. Therefore, this procedural implementation of pairs is a +valid implementation, and if we access pairs using only @code{cons}, +@code{car}, and @code{cdr} we cannot distinguish this implementation from one that uses ``real'' data structures. The point of exhibiting the procedural representation of pairs is not that our @@ -6296,15 +6296,15 @@ simulation. @quotation @strong{@anchor{Exercise 2.4}Exercise 2.4:} Here is an alternative procedural -representation of pairs. For this representation, verify that @t{(car (cons -x y))} yields @t{x} for any objects @t{x} and @t{y}. +representation of pairs. For this representation, verify that @code{(car (cons +x y))} yields @code{x} for any objects @code{x} and @code{y}. @lisp (define (cons x y) (lambda (m) (m x y))) (define (car z) (z (lambda (p q) p))) @end lisp -What is the corresponding definition of @t{cdr}? (Hint: To verify that this +What is the corresponding definition of @code{cdr}? (Hint: To verify that this works, make use of the substitution model of @ref{1.1.5}.) @end quotation @@ -6312,8 +6312,8 @@ works, make use of the substitution model of @ref{1.1.5}.) @strong{@anchor{Exercise 2.5}Exercise 2.5:} Show that we can represent pairs of nonnegative integers using only numbers and arithmetic operations if we represent the pair @math{a} and @math{b} as the integer that is the product @math{2^a 3^b}. -Give the corresponding definitions of the procedures @t{cons}, -@t{car}, and @t{cdr}. +Give the corresponding definitions of the procedures @code{cons}, +@code{car}, and @code{cdr}. @end quotation @quotation @@ -6332,10 +6332,10 @@ adding 1 as This representation is known as @newterm{Church numerals}, after its inventor, Alonzo Church, the logician who invented the @math{\lambda}-calculus. -Define @t{one} and @t{two} directly (not in terms of @t{zero} and -@t{add-1}). (Hint: Use substitution to evaluate @t{(add-1 zero)}). Give -a direct definition of the addition procedure @t{+} (not in terms of -repeated application of @t{add-1}). +Define @code{one} and @code{two} directly (not in terms of @code{zero} and +@code{add-1}). (Hint: Use substitution to evaluate @code{(add-1 zero)}). Give +a direct definition of the addition procedure @code{+} (not in terms of +repeated application of @code{add-1}). @end quotation @node 2.1.4, , 2.1.3, 2.1 @@ -6381,7 +6381,7 @@ range of the result. Alyssa postulates the existence of an abstract object called an ``interval'' that has two endpoints: a lower bound and an upper bound. She also presumes that, given the endpoints of an interval, she can construct the interval using -the data constructor @t{make-interval}. Alyssa first writes a procedure for +the data constructor @code{make-interval}. Alyssa first writes a procedure for adding two intervals. She reasons that the minimum value the sum could be is the sum of the two lower bounds and the maximum value it could be is the sum of the two upper bounds: @@ -6397,7 +6397,7 @@ the two upper bounds: @noindent Alyssa also works out the product of two intervals by finding the minimum and the maximum of the products of the bounds and using them as the bounds of the -resulting interval. (@t{Min} and @t{max} are primitives that find the +resulting interval. (@code{Min} and @code{max} are primitives that find the minimum or maximum of any number of arguments.) @lisp @@ -6436,14 +6436,14 @@ Here is a definition of the interval constructor: (define (make-interval a b) (cons a b)) @end lisp -Define selectors @t{upper-bound} and @t{lower-bound} to complete the +Define selectors @code{upper-bound} and @code{lower-bound} to complete the implementation. @end quotation @quotation @strong{@anchor{Exercise 2.8}Exercise 2.8:} Using reasoning analogous to Alyssa's, describe how the difference of two intervals may be computed. Define -a corresponding subtraction procedure, called @t{sub-interval}. +a corresponding subtraction procedure, called @code{sub-interval}. @end quotation @quotation @@ -6468,7 +6468,7 @@ check for this condition and to signal an error if it occurs. @quotation @strong{@anchor{Exercise 2.11}Exercise 2.11:} In passing, Ben also cryptically comments: ``By testing the signs of the endpoints of the intervals, it is -possible to break @t{mul-interval} into nine cases, only one of which +possible to break @code{mul-interval} into nine cases, only one of which requires more than two multiplications.'' Rewrite this procedure using Ben's suggestion. @@ -6501,9 +6501,9 @@ as in the resistor specifications given earlier. @quotation @strong{@anchor{Exercise 2.12}Exercise 2.12:} Define a constructor -@t{make-@/center-@/percent} that takes a center and a percentage tolerance and -produces the desired interval. You must also define a selector @t{percent} -that produces the percentage tolerance for a given interval. The @t{center} +@code{make-@/center-@/percent} that takes a center and a percentage tolerance and +produces the desired interval. You must also define a selector @code{percent} +that produces the percentage tolerance for a given interval. The @code{center} selector is the same as the one shown above. @end quotation @@ -6582,8 +6582,8 @@ also noticed the different intervals computed by different but algebraically equivalent expressions. She says that a formula to compute with intervals using Alyssa's system will produce tighter error bounds if it can be written in such a form that no variable that represents an uncertain number is repeated. Thus, -she says, @t{par2} is a ``better'' program for parallel resistances than -@t{par1}. Is she right? Why? +she says, @code{par2} is a ``better'' program for parallel resistances than +@code{par1}. Is she right? Why? @end quotation @quotation @@ -6599,15 +6599,15 @@ task impossible? (Warning: This problem is very difficult.) As we have seen, pairs provide a primitive ``glue'' that we can use to construct compound data objects. @ref{Figure 2.2} shows a standard way to -visualize a pair---in this case, the pair formed by @t{(cons 1 2)}. In this +visualize a pair---in this case, the pair formed by @code{(cons 1 2)}. In this representation, which is called @newterm{box-and-pointer notation}, each object is shown as a @newterm{pointer} to a box. The box for a primitive object contains a representation of the object. For example, the box for a number contains a numeral. The box for a pair is actually a double box, the left part -containing (a pointer to) the @t{car} of the pair and the right part -containing the @t{cdr}. +containing (a pointer to) the @code{car} of the pair and the right part +containing the @code{cdr}. -We have already seen that @t{cons} can be used to combine not only numbers +We have already seen that @code{cons} can be used to combine not only numbers but pairs as well. (You made use of this fact, or should have, in doing @ref{Exercise 2.2} and @ref{Exercise 2.3}.) As a consequence, pairs provide a universal building block from which we can construct all sorts of data @@ -6618,7 +6618,7 @@ numbers 1, 2, 3, and 4. @anchor{Figure 2.2} @ifinfo @quotation -@strong{Figure 2.2:} Box-and-pointer representation of @t{(cons 1 2)}. +@strong{Figure 2.2:} Box-and-pointer representation of @code{(cons 1 2)}. @example +---+---+ +---+ @@ -6637,7 +6637,7 @@ numbers 1, 2, 3, and 4. @sp -0.2 @center @image{fig/chap2/Fig2.2e,57mm,,,.pdf} @sp 0.4 -@center @strong{Figure 2.2:} Box-and-pointer representation of @t{(cons 1 2)}. +@center @strong{Figure 2.2:} Box-and-pointer representation of @code{(cons 1 2)}. @sp 1.0 @end iftex @end float @@ -6682,7 +6682,7 @@ numbers 1, 2, 3, and 4. @noindent The ability to create pairs whose elements are pairs is the essence of list structure's importance as a representational tool. We refer to this ability as -the @newterm{closure property} of @t{cons}. In general, an operation for +the @newterm{closure property} of @code{cons}. In general, an operation for combining data objects satisfies the closure property if the results of combining things with that operation can themselves be combined using the same operation.@footnote{The use of the word ``closure'' here comes from abstract @@ -6733,13 +6733,13 @@ One of the useful structures we can build with pairs is a @newterm{sequence}---an ordered collection of data objects. There are, of course, many ways to represent sequences in terms of pairs. One particularly straightforward representation is illustrated in @ref{Figure 2.4}, where the -sequence 1, 2, 3, 4 is represented as a chain of pairs. The @t{car} of each -pair is the corresponding item in the chain, and the @t{cdr} of the pair is -the next pair in the chain. The @t{cdr} of the final pair signals the end +sequence 1, 2, 3, 4 is represented as a chain of pairs. The @code{car} of each +pair is the corresponding item in the chain, and the @code{cdr} of the pair is +the next pair in the chain. The @code{cdr} of the final pair signals the end of the sequence by pointing to a distinguished value that is not a pair, represented in box-and-pointer diagrams as a diagonal line and in programs as -the value of the variable @t{nil}. The entire sequence is constructed by -nested @t{cons} operations: +the value of the variable @code{nil}. The entire sequence is constructed by +nested @code{cons} operations: @lisp (cons 1 @@ -6749,12 +6749,12 @@ nested @t{cons} operations: @end lisp @noindent -Such a sequence of pairs, formed by nested @t{cons}es, is called a -@newterm{list}, and Scheme provides a primitive called @t{list} to help in +Such a sequence of pairs, formed by nested @code{cons}es, is called a +@newterm{list}, and Scheme provides a primitive called @code{list} to help in constructing lists.@footnote{In this book, we use @newterm{list} to mean a chain of pairs terminated by the end-of-list marker. In contrast, the term @newterm{list structure} refers to any data structure made out of pairs, not -just to lists.} The above sequence could be produced by @t{(list 1 2 3 4)}. +just to lists.} The above sequence could be produced by @code{(list 1 2 3 4)}. In general, @lisp @@ -6776,7 +6776,7 @@ is equivalent to @noindent Lisp systems conventionally print lists by printing the sequence of elements, enclosed in parentheses. Thus, the data object in @ref{Figure 2.4} is printed -as @t{(1 2 3 4)}: +as @code{(1 2 3 4)}: @lisp (define one-through-four (list 1 2 3 4)) @@ -6812,28 +6812,28 @@ one-through-four @end float @noindent -Be careful not to confuse the expression @t{(list 1 2 3 4)} with the list -@t{(1 2 3 4)}, which is the result obtained when the expression is -evaluated. Attempting to evaluate the expression @t{(1 2 3 4)} will signal -an error when the interpreter tries to apply the procedure @t{1} to -arguments @t{2}, @t{3}, @t{4}. +Be careful not to confuse the expression @code{(list 1 2 3 4)} with the list +@code{(1 2 3 4)}, which is the result obtained when the expression is +evaluated. Attempting to evaluate the expression @code{(1 2 3 4)} will signal +an error when the interpreter tries to apply the procedure @code{1} to +arguments @code{2}, @code{3}, @code{4}. -We can think of @t{car} as selecting the first item in the list, and of -@t{cdr} as selecting the sublist consisting of all but the first item. -Nested applications of @t{car} and @t{cdr} can be used to extract the +We can think of @code{car} as selecting the first item in the list, and of +@code{cdr} as selecting the sublist consisting of all but the first item. +Nested applications of @code{car} and @code{cdr} can be used to extract the second, third, and subsequent items in the list.@footnote{Since nested -applications of @t{car} and @t{cdr} are cumbersome to write, Lisp +applications of @code{car} and @code{cdr} are cumbersome to write, Lisp dialects provide abbreviations for them---for instance, @lisp (cadr @math{\langle}@math{arg}@math{\rangle}) = (car (cdr @math{\langle}@math{arg}@math{\rangle})) @end lisp -The names of all such procedures start with @t{c} and end with @t{r}. -Each @t{a} between them stands for a @t{car} operation and each @t{d} -for a @t{cdr} operation, to be applied in the same order in which they -appear in the name. The names @t{car} and @t{cdr} persist because simple -combinations like @t{cadr} are pronounceable.} The constructor @t{cons} +The names of all such procedures start with @code{c} and end with @code{r}. +Each @code{a} between them stands for a @code{car} operation and each @code{d} +for a @code{cdr} operation, to be applied in the same order in which they +appear in the name. The names @code{car} and @code{cdr} persist because simple +combinations like @code{cadr} are pronounceable.} The constructor @code{cons} makes a list like the original one, but with an additional item at the beginning. @@ -6853,38 +6853,38 @@ beginning. @end lisp @noindent -The value of @t{nil}, used to terminate the chain of pairs, can be thought +The value of @code{nil}, used to terminate the chain of pairs, can be thought of as a sequence of no elements, the @newterm{empty list}. The word @newterm{nil} is a contraction of the Latin word @emph{nihil}, which means ``nothing.''@footnote{It's remarkable how much energy in the standardization of Lisp dialects has been dissipated in arguments that are literally over nothing: -Should @t{nil} be an ordinary name? Should the value of @t{nil} be a -symbol? Should it be a list? Should it be a pair? In Scheme, @t{nil} is +Should @code{nil} be an ordinary name? Should the value of @code{nil} be a +symbol? Should it be a list? Should it be a pair? In Scheme, @code{nil} is an ordinary name, which we use in this section as a variable whose value is the -end-of-list marker (just as @t{true} is an ordinary variable that has a true -value). Other dialects of Lisp, including Common Lisp, treat @t{nil} as a +end-of-list marker (just as @code{true} is an ordinary variable that has a true +value). Other dialects of Lisp, including Common Lisp, treat @code{nil} as a special symbol. The authors of this book, who have endured too many language standardization brawls, would like to avoid the entire issue. Once we have introduced quotation in @ref{2.3}, we will denote the empty list as -@t{'()} and dispense with the variable @t{nil} entirely.} +@code{'()} and dispense with the variable @code{nil} entirely.} @subsubheading List operations The use of pairs to represent sequences of elements as lists is accompanied by conventional programming techniques for manipulating lists by successively -``@t{cdr}ing down'' the lists. For example, the procedure @t{list-ref} +``@code{cdr}ing down'' the lists. For example, the procedure @code{list-ref} takes as arguments a list and a number @math{n} and returns the @math{n^{\hbox{\ordrm th}}} item of the list. It is customary to number the elements of the list beginning with 0. -The method for computing @t{list-ref} is the following: +The method for computing @code{list-ref} is the following: @itemize @bullet @item -For @math{n = 0}, @t{list-ref} should return the @t{car} of the list. +For @math{n = 0}, @code{list-ref} should return the @code{car} of the list. @item -Otherwise, @t{list-ref} should return the @math{(n - 1)}-st item of the -@t{cdr} of the list. +Otherwise, @code{list-ref} should return the @math{(n - 1)}-st item of the +@code{cdr} of the list. @end itemize @@ -6901,9 +6901,9 @@ Otherwise, @t{list-ref} should return the @math{(n - 1)}-st item of the @end lisp @noindent -Often we @t{cdr} down the whole list. To aid in this, Scheme includes a -primitive predicate @t{null?}, which tests whether its argument is the empty -list. The procedure @t{length}, which returns the number of items in a +Often we @code{cdr} down the whole list. To aid in this, Scheme includes a +primitive predicate @code{null?}, which tests whether its argument is the empty +list. The procedure @code{length}, which returns the number of items in a list, illustrates this typical pattern of use: @lisp @@ -6918,13 +6918,13 @@ list, illustrates this typical pattern of use: @end lisp @noindent -The @t{length} procedure implements a simple recursive plan. The reduction +The @code{length} procedure implements a simple recursive plan. The reduction step is: @itemize @bullet @item -The @t{length} of any list is 1 plus the @t{length} of the @t{cdr} of +The @code{length} of any list is 1 plus the @code{length} of the @code{cdr} of the list. @end itemize @@ -6935,12 +6935,12 @@ This is applied successively until we reach the base case: @itemize @bullet @item -The @t{length} of the empty list is 0. +The @code{length} of the empty list is 0. @end itemize @noindent -We could also compute @t{length} in an iterative style: +We could also compute @code{length} in an iterative style: @lisp (define (length items) @@ -6953,8 +6953,8 @@ We could also compute @t{length} in an iterative style: @end lisp @noindent -Another conventional programming technique is to ``@t{cons} up'' an answer -list while @t{cdr}ing down a list, as in the procedure @t{append}, which +Another conventional programming technique is to ``@code{cons} up'' an answer +list while @code{cdr}ing down a list, as in the procedure @code{append}, which takes two lists as arguments and combines their elements to make a new list: @lisp @@ -6966,17 +6966,17 @@ takes two lists as arguments and combines their elements to make a new list: @end lisp @noindent -@t{Append} is also implemented using a recursive plan. To @t{append} -lists @t{list1} and @t{list2}, do the following: +@code{Append} is also implemented using a recursive plan. To @code{append} +lists @code{list1} and @code{list2}, do the following: @itemize @bullet @item -If @t{list1} is the empty list, then the result is just @t{list2}. +If @code{list1} is the empty list, then the result is just @code{list2}. @item -Otherwise, @t{append} the @t{cdr} of @t{list1} and @t{list2}, and -@t{cons} the @t{car} of @t{list1} onto the result: +Otherwise, @code{append} the @code{cdr} of @code{list1} and @code{list2}, and +@code{cons} the @code{car} of @code{list1} onto the result: @end itemize @@ -6991,7 +6991,7 @@ Otherwise, @t{append} the @t{cdr} of @t{list1} and @t{list2}, and @quotation @strong{@anchor{Exercise 2.17}Exercise 2.17:} Define a procedure -@t{last-pair} that returns the list that contains only the last element of a +@code{last-pair} that returns the list that contains only the last element of a given (nonempty) list: @lisp @@ -7001,7 +7001,7 @@ given (nonempty) list: @end quotation @quotation -@strong{@anchor{Exercise 2.18}Exercise 2.18:} Define a procedure @t{reverse} +@strong{@anchor{Exercise 2.18}Exercise 2.18:} Define a procedure @code{reverse} that takes a list as argument and returns a list of the same elements in reverse order: @@ -7018,11 +7018,11 @@ program of @ref{1.2.2}. It would be nice to be able to easily change the currency used by the program, so that we could compute the number of ways to change a British pound, for example. As the program is written, the knowledge of the currency is distributed partly into the procedure -@t{first-@/denomi-@/nation} and partly into the procedure @t{count-@/change} +@code{first-@/denomi-@/nation} and partly into the procedure @code{count-@/change} (which knows that there are five kinds of U.S. coins). It would be nicer to be able to supply a list of coins to be used for making change. -We want to rewrite the procedure @t{cc} so that its second argument is a +We want to rewrite the procedure @code{cc} so that its second argument is a list of the values of the coins to use rather than an integer specifying which coins to use. We could then have lists that defined each kind of currency: @@ -7034,7 +7034,7 @@ coins to use. We could then have lists that defined each kind of currency: (list 100 50 20 10 5 2 1 0.5)) @end lisp -We could then call @t{cc} as follows: +We could then call @code{cc} as follows: @lisp (cc 100 us-coins) @@ -7042,7 +7042,7 @@ We could then call @t{cc} as follows: @end lisp -To do this will require changing the program @t{cc} somewhat. It will still +To do this will require changing the program @code{cc} somewhat. It will still have the same form, but it will access its second argument differently, as follows: @@ -7073,9 +7073,9 @@ affect the answer produced by @code{cc}? Why or why not? @endpage @quotation -@strong{@anchor{Exercise 2.20}Exercise 2.20:} The procedures @t{+}, -@t{*}, and @t{list} take arbitrary numbers of arguments. One way to -define such procedures is to use @t{define} with @newterm{dotted-tail +@strong{@anchor{Exercise 2.20}Exercise 2.20:} The procedures @code{+}, +@code{*}, and @code{list} take arbitrary numbers of arguments. One way to +define such procedures is to use @code{define} with @newterm{dotted-tail notation}. In a procedure definition, a parameter list that has a dot before the last parameter name indicates that, when the procedure is called, the initial parameters (if any) will have as values the initial arguments, as @@ -7087,7 +7087,7 @@ remaining arguments. For instance, given the definition @end lisp @noindent -the procedure @t{f} can be called with two or more arguments. If we +the procedure @code{f} can be called with two or more arguments. If we evaluate @lisp @@ -7095,15 +7095,15 @@ evaluate @end lisp @noindent -then in the body of @t{f}, @t{x} will be 1, @t{y} will be 2, and -@t{z} will be the list @t{(3 4 5 6)}. Given the definition +then in the body of @code{f}, @code{x} will be 1, @code{y} will be 2, and +@code{z} will be the list @code{(3 4 5 6)}. Given the definition @lisp (define (g . w) @math{\langle}@var{body}@math{\rangle}) @end lisp @noindent -the procedure @t{g} can be called with zero or more arguments. If we +the procedure @code{g} can be called with zero or more arguments. If we evaluate @lisp @@ -7111,8 +7111,8 @@ evaluate @end lisp @noindent -then in the body of @t{g}, @t{w} will be the list @t{(1 2 3 4 5 -6)}.@footnote{To define @t{f} and @t{g} using @t{lambda} we would +then in the body of @code{g}, @code{w} will be the list @code{(1 2 3 4 5 +6)}.@footnote{To define @code{f} and @code{g} using @code{lambda} we would write @lisp @@ -7121,7 +7121,7 @@ write @end lisp } -Use this notation to write a procedure @t{same-@/parity} that takes one or +Use this notation to write a procedure @code{same-@/parity} that takes one or more integers and returns a list of all the arguments that have the same even-odd parity as the first argument. For example, @@ -7154,11 +7154,11 @@ procedure scales each number in a list by a given factor: @noindent We can abstract this general idea and capture it as a common pattern expressed as a higher-order procedure, just as in @ref{1.3}. The higher-order -procedure here is called @t{map}. @t{Map} takes as arguments a procedure +procedure here is called @code{map}. @code{Map} takes as arguments a procedure of one argument and a list, and returns a list of the results produced by applying the procedure to each element in the list:@footnote{@anchor{Footnote 12} -Scheme standardly provides a @t{map} procedure that -is more general than the one described here. This more general @t{map} +Scheme standardly provides a @code{map} procedure that +is more general than the one described here. This more general @code{map} takes a procedure of @math{n} arguments, together with @math{n} lists, and applies the procedure to all the first elements of the lists, all the second elements of the lists, and so on, returning a list of the results. For example: @@ -7192,7 +7192,7 @@ of the lists, and so on, returning a list of the results. For example: @end lisp @noindent -Now we can give a new definition of @t{scale-list} in terms of @t{map}: +Now we can give a new definition of @code{scale-list} in terms of @code{map}: @lisp (define (scale-list items factor) @@ -7201,15 +7201,15 @@ Now we can give a new definition of @t{scale-list} in terms of @t{map}: @end lisp @noindent -@t{Map} is an important construct, not only because it captures a common +@code{Map} is an important construct, not only because it captures a common pattern, but because it establishes a higher level of abstraction in dealing -with lists. In the original definition of @t{scale-list}, the recursive +with lists. In the original definition of @code{scale-list}, the recursive structure of the program draws attention to the element-by-element processing -of the list. Defining @t{scale-list} in terms of @t{map} suppresses that +of the list. Defining @code{scale-list} in terms of @code{map} suppresses that level of detail and emphasizes that scaling transforms a list of elements to a list of results. The difference between the two definitions is not that the computer is performing a different process (it isn't) but that we think about -the process differently. In effect, @t{map} helps establish an abstraction +the process differently. In effect, @code{map} helps establish an abstraction barrier that isolates the implementation of procedures that transform lists from the details of how the elements of the list are extracted and combined. Like the barriers shown in @ref{Figure 2.1}, this abstraction gives us the @@ -7219,7 +7219,7 @@ sequences to sequences. @ref{2.2.3} expands on this use of sequences as a framework for organizing programs. @quotation -@strong{@anchor{Exercise 2.21}Exercise 2.21:} The procedure @t{square-list} +@strong{@anchor{Exercise 2.21}Exercise 2.21:} The procedure @code{square-list} takes a list of numbers as argument and returns a list of the squares of those numbers. @@ -7228,7 +7228,7 @@ numbers. @i{(1 4 9 16)} @end lisp -Here are two different definitions of @t{square-list}. Complete both of +Here are two different definitions of @code{square-list}. Complete both of them by filling in the missing expressions: @lisp @@ -7244,7 +7244,7 @@ them by filling in the missing expressions: @quotation @strong{@anchor{Exercise 2.22}Exercise 2.22:} Louis Reasoner tries to rewrite -the first @t{square-list} procedure of @ref{Exercise 2.21} so that it +the first @code{square-list} procedure of @ref{Exercise 2.21} so that it evolves an iterative process: @lisp @@ -7259,10 +7259,10 @@ evolves an iterative process: @end lisp -Unfortunately, defining @t{square-list} this way produces the answer list in +Unfortunately, defining @code{square-list} this way produces the answer list in the reverse order of the one desired. Why? -Louis then tries to fix his bug by interchanging the arguments to @t{cons}: +Louis then tries to fix his bug by interchanging the arguments to @code{cons}: @lisp (define (square-list items) @@ -7280,12 +7280,12 @@ This doesn't work either. Explain. @end quotation @quotation -@strong{@anchor{Exercise 2.23}Exercise 2.23:} The procedure @t{for-each} is -similar to @t{map}. It takes as arguments a procedure and a list of -elements. However, rather than forming a list of the results, @t{for-each} +@strong{@anchor{Exercise 2.23}Exercise 2.23:} The procedure @code{for-each} is +similar to @code{map}. It takes as arguments a procedure and a list of +elements. However, rather than forming a list of the results, @code{for-each} just applies the procedure to each of the elements in turn, from left to right. The values returned by applying the procedure to the elements are not used at -all---@t{for-each} is used with procedures that perform an action, such as +all---@code{for-each} is used with procedures that perform an action, such as printing. For example, @endpage @@ -7299,9 +7299,9 @@ printing. For example, @i{88} @end lisp -The value returned by the call to @t{for-each} (not illustrated above) can +The value returned by the call to @code{for-each} (not illustrated above) can be something arbitrary, such as true. Give an implementation of -@t{for-each}. +@code{for-each}. @end quotation @node 2.2.2, 2.2.3, 2.2.1, 2.2 @@ -7309,14 +7309,14 @@ be something arbitrary, such as true. Give an implementation of The representation of sequences in terms of lists generalizes naturally to represent sequences whose elements may themselves be sequences. For example, -we can regard the object @t{((1 2) 3 4)} constructed by +we can regard the object @code{((1 2) 3 4)} constructed by @lisp (cons (list 1 2) (list 3 4)) @end lisp @noindent -as a list of three items, the first of which is itself a list, @t{(1 2)}. +as a list of three items, the first of which is itself a list, @code{(1 2)}. Indeed, this is suggested by the form in which the result is printed by the interpreter. @ref{Figure 2.5} shows the representation of this structure in terms of pairs. @@ -7330,7 +7330,7 @@ shows the structure in @ref{Figure 2.5} viewed as a tree. @anchor{Figure 2.5} @ifinfo @quotation -@strong{Figure 2.5:} Structure formed by @t{(cons (list 1 2) (list 3 4))}. +@strong{Figure 2.5:} Structure formed by @code{(cons (list 1 2) (list 3 4))}. @example (3 4) @@ -7357,7 +7357,7 @@ shows the structure in @ref{Figure 2.5} viewed as a tree. @center @image{fig/chap2/Fig2.5e,140mm,,,.pdf} @sp 0.6 @quotation -@strong{Figure 2.5:} Structure formed by @t{(cons (list 1 2) (list 3 4))}. +@strong{Figure 2.5:} Structure formed by @code{(cons (list 1 2) (list 3 4))}. @end quotation @sp 0.7 @end iftex @@ -7392,8 +7392,8 @@ shows the structure in @ref{Figure 2.5} viewed as a tree. Recursion is a natural tool for dealing with tree structures, since we can often reduce operations on trees to operations on their branches, which reduce in turn to operations on the branches of the branches, and so on, until we -reach the leaves of the tree. As an example, compare the @t{length} -procedure of @ref{2.2.1} with the @t{count-leaves} procedure, which +reach the leaves of the tree. As an example, compare the @code{length} +procedure of @ref{2.2.1} with the @code{count-leaves} procedure, which returns the total number of leaves of a tree: @lisp @@ -7420,59 +7420,59 @@ returns the total number of leaves of a tree: @end lisp @noindent -To implement @t{count-leaves}, recall the recursive plan for computing -@t{length}: +To implement @code{count-leaves}, recall the recursive plan for computing +@code{length}: @itemize @bullet @item -@t{Length} of a list @t{x} is 1 plus @t{length} of the -@t{cdr} of @t{x}. +@code{Length} of a list @code{x} is 1 plus @code{length} of the +@code{cdr} of @code{x}. @item -@t{Length} of the empty list is 0. +@code{Length} of the empty list is 0. @end itemize @noindent -@t{Count-leaves} is similar. The value for the empty list is the same: +@code{Count-leaves} is similar. The value for the empty list is the same: @itemize @bullet @item -@t{Count-leaves} of the empty list is 0. +@code{Count-leaves} of the empty list is 0. @end itemize @noindent -But in the reduction step, where we strip off the @t{car} of the list, we -must take into account that the @t{car} may itself be a tree whose leaves we +But in the reduction step, where we strip off the @code{car} of the list, we +must take into account that the @code{car} may itself be a tree whose leaves we need to count. Thus, the appropriate reduction step is @itemize @bullet @item -@t{Count-leaves} of a tree @t{x} is @t{count-leaves} of the @t{car} -of @t{x} plus @t{count-leaves} of the @t{cdr} of @t{x}. +@code{Count-leaves} of a tree @code{x} is @code{count-leaves} of the @code{car} +of @code{x} plus @code{count-leaves} of the @code{cdr} of @code{x}. @end itemize @noindent -Finally, by taking @t{car}s we reach actual leaves, so we need another base +Finally, by taking @code{car}s we reach actual leaves, so we need another base case: @itemize @bullet @item -@t{Count-leaves} of a leaf is 1. +@code{Count-leaves} of a leaf is 1. @end itemize @noindent To aid in writing recursive procedures on trees, Scheme provides the primitive -predicate @t{pair?}, which tests whether its argument is a pair. Here is +predicate @code{pair?}, which tests whether its argument is a pair. Here is the complete procedure:@footnote{The order of the first two clauses in the -@t{cond} matters, since the empty list satisfies @t{null?} and also is +@code{cond} matters, since the empty list satisfies @code{null?} and also is not a pair.} @lisp @@ -7485,14 +7485,14 @@ not a pair.} @quotation @strong{@anchor{Exercise 2.24}Exercise 2.24:} Suppose we evaluate the -expression @t{(list 1 (list 2 (list 3 4)))}. Give the result printed by the +expression @code{(list 1 (list 2 (list 3 4)))}. Give the result printed by the interpreter, the corresponding box-@/and-@/pointer structure, and the interpretation of this as a tree (as in @ref{Figure 2.6}). @end quotation @quotation -@strong{@anchor{Exercise 2.25}Exercise 2.25:} Give combinations of @t{car}s -and @t{cdr}s that will pick 7 from each of the following lists: +@strong{@anchor{Exercise 2.25}Exercise 2.25:} Give combinations of @code{car}s +and @code{cdr}s that will pick 7 from each of the following lists: @lisp (1 3 (5 7) 9) @@ -7502,8 +7502,8 @@ and @t{cdr}s that will pick 7 from each of the following lists: @end quotation @quotation -@strong{@anchor{Exercise 2.26}Exercise 2.26:} Suppose we define @t{x} and -@t{y} to be two lists: +@strong{@anchor{Exercise 2.26}Exercise 2.26:} Suppose we define @code{x} and +@code{y} to be two lists: @lisp (define x (list 1 2 3)) @@ -7521,8 +7521,8 @@ following expressions: @end quotation @quotation -@strong{@anchor{Exercise 2.27}Exercise 2.27:} Modify your @t{reverse} -procedure of @ref{Exercise 2.18} to produce a @t{deep-reverse} procedure +@strong{@anchor{Exercise 2.27}Exercise 2.27:} Modify your @code{reverse} +procedure of @ref{Exercise 2.18} to produce a @code{deep-reverse} procedure that takes a list as argument and returns as its value the list with its elements reversed and with all sublists deep-reversed as well. For example, @@ -7538,7 +7538,7 @@ x @end quotation @quotation -@strong{@anchor{Exercise 2.28}Exercise 2.28:} Write a procedure @t{fringe} +@strong{@anchor{Exercise 2.28}Exercise 2.28:} Write a procedure @code{fringe} that takes as argument a tree (represented as a list) and returns a list whose elements are all the leaves of the tree arranged in left-to-right order. For example, @@ -7559,15 +7559,15 @@ example, branches, a left branch and a right branch. Each branch is a rod of a certain length, from which hangs either a weight or another binary mobile. We can represent a binary mobile using compound data by constructing it from two -branches (for example, using @t{list}): +branches (for example, using @code{list}): @lisp (define (make-mobile left right) (list left right)) @end lisp -A branch is constructed from a @t{length} (which must be a number) together -with a @t{structure}, which may be either a number (representing a simple +A branch is constructed from a @code{length} (which must be a number) together +with a @code{structure}, which may be either a number (representing a simple weight) or another mobile: @lisp @@ -7578,12 +7578,12 @@ weight) or another mobile: @enumerate a @item -Write the corresponding selectors @t{left-branch} and @t{right-@/branch}, -which return the branches of a mobile, and @t{branch-@/length} and -@t{branch-@/structure}, which return the components of a branch. +Write the corresponding selectors @code{left-branch} and @code{right-@/branch}, +which return the branches of a mobile, and @code{branch-@/length} and +@code{branch-@/structure}, which return the components of a branch. @item -Using your selectors, define a procedure @t{total-@/weight} that returns the +Using your selectors, define a procedure @code{total-@/weight} that returns the total weight of a mobile. @item @@ -7613,13 +7613,13 @@ representation? @subsubheading Mapping over trees -Just as @t{map} is a powerful abstraction for dealing with sequences, -@t{map} together with recursion is a powerful abstraction for dealing with -trees. For instance, the @t{scale-tree} procedure, analogous to -@t{scale-list} of @ref{2.2.1}, takes as arguments a numeric factor +Just as @code{map} is a powerful abstraction for dealing with sequences, +@code{map} together with recursion is a powerful abstraction for dealing with +trees. For instance, the @code{scale-tree} procedure, analogous to +@code{scale-list} of @ref{2.2.1}, takes as arguments a numeric factor and a tree whose leaves are numbers. It returns a tree of the same shape, where each number is multiplied by the factor. The recursive plan for -@t{scale-tree} is similar to the one for @t{count-leaves}: +@code{scale-tree} is similar to the one for @code{count-leaves}: @lisp (define (scale-tree tree factor) @@ -7637,8 +7637,8 @@ where each number is multiplied by the factor. The recursive plan for @end lisp @noindent -Another way to implement @t{scale-tree} is to regard the tree as a sequence -of sub-trees and use @t{map}. We map over the sequence, scaling each +Another way to implement @code{scale-tree} is to regard the tree as a sequence +of sub-trees and use @code{map}. We map over the sequence, scaling each sub-tree in turn, and return the list of results. In the base case, where the tree is a leaf, we simply multiply by the factor: @@ -7657,8 +7657,8 @@ operations and recursion. @quotation @strong{@anchor{Exercise 2.30}Exercise 2.30:} Define a procedure -@t{square-tree} analogous to the @t{square-@/list} procedure of -@ref{Exercise 2.21}. That is, @t{square-tree} should behave as follows: +@code{square-tree} analogous to the @code{square-@/list} procedure of +@ref{Exercise 2.21}. That is, @code{square-tree} should behave as follows: @lisp (square-tree @@ -7668,14 +7668,14 @@ operations and recursion. @i{(1 (4 (9 16) 25) (36 49))} @end lisp -Define @t{square-tree} both directly (i.e., without using any higher-order -procedures) and also by using @t{map} and recursion. +Define @code{square-tree} both directly (i.e., without using any higher-order +procedures) and also by using @code{map} and recursion. @end quotation @quotation @strong{@anchor{Exercise 2.31}Exercise 2.31:} Abstract your answer to -@ref{Exercise 2.30} to produce a procedure @t{tree-map} with the property -that @t{square-tree} could be defined as +@ref{Exercise 2.30} to produce a procedure @code{tree-map} with the property +that @code{square-tree} could be defined as @lisp (define (square-tree tree) @@ -7686,8 +7686,8 @@ that @t{square-tree} could be defined as @quotation @strong{@anchor{Exercise 2.32}Exercise 2.32:} We can represent a set as a list of distinct elements, and we can represent the set of all subsets of the set as -a list of lists. For example, if the set is @t{(1 2 3)}, then the set of -all subsets is @t{(() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))}. Complete the +a list of lists. For example, if the set is @code{(1 2 3)}, then the set of +all subsets is @code{(() (3) (2) (2 3) (1) (1 3) (1 2) (1 2 3))}. Complete the following definition of a procedure that generates the set of subsets of a set and give a clear explanation of why it works: @@ -7715,7 +7715,7 @@ higher-order procedures, can capture common patterns in programs that deal with numerical data. Our ability to formulate analogous operations for working with compound data depends crucially on the style in which we manipulate our data structures. Consider, for example, the following procedure, analogous to the -@t{count-leaves} procedure of @ref{2.2.2}, which takes a tree as +@code{count-leaves} procedure of @ref{2.2.2}, which takes a tree as argument and computes the sum of the squares of the leaves that are odd: @lisp @@ -7763,7 +7763,7 @@ filters them, selecting the odd ones; squares each of the selected ones; and @item -accumulates the results using @t{+}, starting with 0. +accumulates the results using @code{+}, starting with 0. @end itemize @@ -7782,7 +7782,7 @@ computes the Fibonacci number for each integer; filters them, selecting the even ones; and @item -accumulates the results using @t{cons}, starting with the +accumulates the results using @code{cons}, starting with the empty list. @end itemize @@ -7791,21 +7791,21 @@ empty list. A signal-processing engineer would find it natural to conceptualize these processes in terms of signals flowing through a cascade of stages, each of which implements part of the program plan, as shown in @ref{Figure 2.7}. In -@t{sum-odd-squares}, we begin with an @newterm{enumerator}, which generates +@code{sum-odd-squares}, we begin with an @newterm{enumerator}, which generates a ``signal'' consisting of the leaves of a given tree. This signal is passed through a @newterm{filter}, which eliminates all but the odd elements. The resulting signal is in turn passed through a @newterm{map}, which is a -``transducer'' that applies the @t{square} procedure to each element. The +``transducer'' that applies the @code{square} procedure to each element. The output of the map is then fed to an @newterm{accumulator}, which combines the -elements using @t{+}, starting from an initial 0. The plan for -@t{even-fibs} is analogous. +elements using @code{+}, starting from an initial 0. The plan for +@code{even-fibs} is analogous. @float @anchor{Figure 2.7} @ifinfo @quotation @strong{Figure 2.7:} The signal-flow plans for the -procedures @t{sum-odd-squares} (top) and @t{even-fibs} (bottom) reveal +procedures @code{sum-odd-squares} (top) and @code{even-fibs} (bottom) reveal the commonality between the two programs. @example @@ -7828,7 +7828,7 @@ the commonality between the two programs. @c @quotation @noindent @strong{Figure 2.7:} The signal-flow plans for the -procedures @t{sum-@/odd-@/squares} (top) and @t{even-fibs} (bottom) reveal +procedures @code{sum-@/odd-@/squares} (top) and @code{even-fibs} (bottom) reveal the commonality between the two programs. @c @end quotation @sp 1.1 @@ -7837,9 +7837,9 @@ the commonality between the two programs. @noindent Unfortunately, the two procedure definitions above fail to exhibit this -signal-flow structure. For instance, if we examine the @t{sum-odd-squares} +signal-flow structure. For instance, if we examine the @code{sum-odd-squares} procedure, we find that the enumeration is implemented partly by the -@t{null?} and @t{pair?} tests and partly by the tree-recursive structure +@code{null?} and @code{pair?} tests and partly by the tree-recursive structure of the procedure. Similarly, the accumulation is found partly in the tests and partly in the addition used in the recursion. In general, there are no distinct parts of either procedure that correspond to the elements in the @@ -7857,7 +7857,7 @@ structure is to concentrate on the ``signals'' that flow from one stage in the process to the next. If we represent these signals as lists, then we can use list operations to implement the processing at each of the stages. For instance, we can implement the mapping stages of the signal-flow diagrams using -the @t{map} procedure from @ref{2.2.1}: +the @code{map} procedure from @ref{2.2.1}: @lisp (map square (list 1 2 3 4 5)) @@ -7909,7 +7909,7 @@ Accumulations can be implemented by @noindent All that remains to implement signal-flow diagrams is to enumerate the sequence -of elements to be processed. For @t{even-fibs}, we need to generate the +of elements to be processed. For @code{even-fibs}, we need to generate the sequence of integers in a given range, which we can do as follows: @lisp @@ -7927,7 +7927,7 @@ sequence of integers in a given range, which we can do as follows: @noindent To enumerate the leaves of a tree, we can use@footnote{This is, in fact, -precisely the @t{fringe} procedure from @ref{Exercise 2.28}. Here we've +precisely the @code{fringe} procedure from @ref{Exercise 2.28}. Here we've renamed it to emphasize that it is part of a family of general sequence-manipulation procedures.} @@ -7944,8 +7944,8 @@ sequence-manipulation procedures.} @end lisp @noindent -Now we can reformulate @t{sum-odd-squares} and @t{even-@/fibs} as in the -signal-flow diagrams. For @t{sum-@/odd-@/squares}, we enumerate the sequence of +Now we can reformulate @code{sum-odd-squares} and @code{even-@/fibs} as in the +signal-flow diagrams. For @code{sum-@/odd-@/squares}, we enumerate the sequence of leaves of the tree, filter this to keep only the odd numbers in the sequence, square each element, and sum the results: @@ -7960,7 +7960,7 @@ square each element, and sum the results: @end lisp @noindent -For @t{even-fibs}, we enumerate the integers from 0 to @math{n}, generate the +For @code{even-fibs}, we enumerate the integers from 0 to @math{n}, generate the Fibonacci number for each of these integers, filter the resulting sequence to keep only the even elements, and accumulate the results into a list: @@ -7986,8 +7986,8 @@ engineering design. In real signal-processing applications, for example, designers regularly build systems by cascading elements selected from standardized families of filters and transducers. Similarly, sequence operations provide a library of standard program elements that we can mix and -match. For instance, we can reuse pieces from the @t{sum-odd-squares} and -@t{even-@/fibs} procedures in a program that constructs a list of the squares +match. For instance, we can reuse pieces from the @code{sum-odd-squares} and +@code{even-@/fibs} procedures in a program that constructs a list of the squares of the first @math{n + 1} Fibonacci numbers: @lisp @@ -8024,8 +8024,8 @@ integers in a sequence: We can also formulate conventional data-processing applications in terms of sequence operations. Suppose we have a sequence of personnel records and we want to find the salary of the highest-paid programmer. Assume that we have a -selector @t{salary} that returns the salary of a record, and a predicate -@t{programmer?} that tests if a record is for a programmer. Then we can +selector @code{salary} that returns the salary of a record, and a predicate +@code{programmer?} that tests if a record is for a programmer. Then we can write @lisp @@ -8144,7 +8144,7 @@ would evaluate @end quotation @quotation -@strong{@anchor{Exercise 2.35}Exercise 2.35:} Redefine @t{count-leaves} from +@strong{@anchor{Exercise 2.35}Exercise 2.35:} Redefine @code{count-leaves} from @ref{2.2.2} as an accumulation: @lisp @@ -8154,16 +8154,16 @@ would evaluate @end quotation @quotation -@strong{@anchor{Exercise 2.36}Exercise 2.36:} The procedure @t{accumulate-n} -is similar to @t{accumulate} except that it takes as its third argument a +@strong{@anchor{Exercise 2.36}Exercise 2.36:} The procedure @code{accumulate-n} +is similar to @code{accumulate} except that it takes as its third argument a sequence of sequences, which are all assumed to have the same number of elements. It applies the designated accumulation procedure to combine all the first elements of the sequences, all the second elements of the sequences, and -so on, and returns a sequence of the results. For instance, if @t{s} is a -sequence containing four sequences, @t{((1 2 3) (4 5 6) (7 8 9) (10 11 -12)),} then the value of @t{(accumulate-n + 0 s)} should be the sequence -@t{(22 26 30)}. Fill in the missing expressions in the following definition -of @t{accumulate-n}: +so on, and returns a sequence of the results. For instance, if @code{s} is a +sequence containing four sequences, @code{((1 2 3) (4 5 6) (7 8 9) (10 11 +12)),} then the value of @code{(accumulate-n + 0 s)} should be the sequence +@code{(22 26 30)}. Fill in the missing expressions in the following definition +of @code{accumulate-n}: @lisp (define (accumulate-n op init seqs) @@ -8197,7 +8197,7 @@ $$ 6 & 7 & 8 & 9 \cr }\right) $$ @end tex @noindent -is represented as the sequence @t{((1 2 3 4) (4 5 6 6) (6 7 8 9))}. With +is represented as the sequence @code{((1 2 3 4) (4 5 6 6) (6 7 8 9))}. With this representation, we can use sequence operations to concisely express the basic matrix and vector operations. These operations (which are described in any book on matrix algebra) are the following: @@ -8234,7 +8234,7 @@ $$ } $$ @end tex We can define the dot product as@footnote{This definition uses the extended -version of @t{map} described in @ref{Footnote 12}.} +version of @code{map} described in @ref{Footnote 12}.} @lisp (define (dot-product v w) @@ -8242,7 +8242,7 @@ version of @t{map} described in @ref{Footnote 12}.} @end lisp Fill in the missing expressions in the following procedures for computing the -other matrix operations. (The procedure @t{accumulate-n} is defined in +other matrix operations. (The procedure @code{accumulate-n} is defined in @ref{Exercise 2.36}.) @lisp @@ -8259,10 +8259,10 @@ other matrix operations. (The procedure @t{accumulate-n} is defined in @end quotation @quotation -@strong{@anchor{Exercise 2.38}Exercise 2.38:} The @t{accumulate} procedure -is also known as @t{fold-right}, because it combines the first element of +@strong{@anchor{Exercise 2.38}Exercise 2.38:} The @code{accumulate} procedure +is also known as @code{fold-right}, because it combines the first element of the sequence with the result of combining all the elements to the right. There -is also a @t{fold-left}, which is similar to @t{fold-right}, except that +is also a @code{fold-left}, which is similar to @code{fold-right}, except that it combines elements working in the opposite direction: @float @@ -8286,15 +8286,15 @@ What are the values of (fold-left list nil (list 1 2 3)) @end lisp -Give a property that @t{op} should satisfy to guarantee that -@t{fold-right} and @t{fold-left} will produce the same values for any +Give a property that @code{op} should satisfy to guarantee that +@code{fold-right} and @code{fold-left} will produce the same values for any sequence. @end quotation @quotation @strong{@anchor{Exercise 2.39}Exercise 2.39:} Complete the following -definitions of @t{reverse} (@ref{Exercise 2.18}) in terms of -@t{fold-right} and @t{fold-left} from @ref{Exercise 2.38}: +definitions of @code{reverse} (@ref{Exercise 2.18}) in terms of +@code{fold-right} and @code{fold-left} from @ref{Exercise 2.38}: @lisp (define (reverse sequence) @@ -8356,14 +8356,14 @@ that passes through the filter, produce the triple @math{(i, j, i + j)}. Here is a way to generate the sequence of pairs: For each integer @math{i \le n}, enumerate the integers @math{j < i}, and for each such @math{i} and @math{j} generate the pair @math{(i, j)}. In terms of sequence operations, we map along -the sequence @t{(enumerate-interval 1 n)}. For each @math{i} in this sequence, -we map along the sequence @t{(enumerate-interval 1 (- i 1))}. For each -@math{j} in this latter sequence, we generate the pair @t{(list i j)}. This +the sequence @code{(enumerate-interval 1 n)}. For each @math{i} in this sequence, +we map along the sequence @code{(enumerate-interval 1 (- i 1))}. For each +@math{j} in this latter sequence, we generate the pair @code{(list i j)}. This gives us a sequence of pairs for each @math{i}. Combining all the sequences for -all the @math{i} (by accumulating with @t{append}) produces the required +all the @math{i} (by accumulating with @code{append}) produces the required sequence of pairs:@footnote{We're representing a pair here as a list of two elements rather than as a Lisp pair. Thus, the ``pair'' @math{(i, j)} is -represented as @t{(list i j)}, not @t{(cons i j)}.} +represented as @code{(list i j)}, not @code{(cons i j)}.} @lisp (accumulate @@ -8377,7 +8377,7 @@ represented as @t{(list i j)}, not @t{(cons i j)}.} @end lisp @noindent -The combination of mapping and accumulating with @t{append} is so common in +The combination of mapping and accumulating with @code{append} is so common in this sort of program that we will isolate it as a separate procedure: @lisp @@ -8458,9 +8458,9 @@ make our programs self-documenting by using descriptive names.} Notice how this strategy reduces the problem of generating permutations of @math{S} to the problem of generating the permutations of sets with fewer elements than @math{S}. In the terminal case, we work our way down to the empty list, -which represents a set of no elements. For this, we generate @t{(list +which represents a set of no elements. For this, we generate @code{(list nil)}, which is a sequence with one item, namely the set with no elements. The -@t{remove} procedure used in @t{permutations} returns all the items in a +@code{remove} procedure used in @code{permutations} returns all the items in a given sequence except for a given item. This can be expressed as a simple filter: @@ -8472,9 +8472,9 @@ filter: @quotation @strong{@anchor{Exercise 2.40}Exercise 2.40:} Define a procedure -@t{unique-pairs} that, given an integer @math{n}, generates the sequence of -pairs @math{(i, j)} with @math{1 \le j < i \le n}. Use @t{unique-pairs} -to simplify the definition of @t{prime-sum-pairs} given above. +@code{unique-pairs} that, given an integer @math{n}, generates the sequence of +pairs @math{(i, j)} with @math{1 \le j < i \le n}. Use @code{unique-pairs} +to simplify the definition of @code{prime-sum-pairs} given above. @end quotation @quotation @@ -8501,10 +8501,10 @@ respect to the other queens. This produces the sequence of all ways to place @math{k} queens in the first @math{k} columns. By continuing this process, we will produce not only one solution, but all solutions to the puzzle. -We implement this solution as a procedure @t{queens}, which returns a +We implement this solution as a procedure @code{queens}, which returns a sequence of all solutions to the problem of placing @math{n} queens on an -@math{n \times n} chessboard. @t{Queens} has an internal procedure -@t{queen-cols} that returns the sequence of all ways to place queens in the +@math{n \times n} chessboard. @code{Queens} has an internal procedure +@code{queen-cols} that returns the sequence of all ways to place queens in the first @math{k} columns of the board. @lisp @@ -8529,13 +8529,13 @@ first @math{k} columns of the board. (queen-cols board-size)) @end lisp -In this procedure @t{rest-of-queens} is a way to place @math{k - 1} queens in -the first @math{k - 1} columns, and @t{new-row} is a proposed row in which to +In this procedure @code{rest-of-queens} is a way to place @math{k - 1} queens in +the first @math{k - 1} columns, and @code{new-row} is a proposed row in which to place the queen for the @math{k^{\hbox{\ordrm th}}} column. Complete the program by implementing the representation for sets of board positions, including the procedure -@t{adjoin-position}, which adjoins a new row-column position to a set of -positions, and @t{empty-board}, which represents an empty set of positions. -You must also write the procedure @t{safe?}, which determines for a set of +@code{adjoin-position}, which adjoins a new row-column position to a set of +positions, and @code{empty-board}, which represents an empty set of positions. +You must also write the procedure @code{safe?}, which determines for a set of positions, whether the queen in the @math{k^{\hbox{\ordrm th}}} column is safe with respect to the others. (Note that we need only check whether the new queen is safe---the other queens are already guaranteed safe with respect to each other.) @@ -8577,11 +8577,11 @@ other queens are already guaranteed safe with respect to each other.) @quotation @strong{@anchor{Exercise 2.43}Exercise 2.43:} Louis Reasoner is having a -terrible time doing @ref{Exercise 2.42}. His @t{queens} procedure seems to +terrible time doing @ref{Exercise 2.42}. His @code{queens} procedure seems to work, but it runs extremely slowly. (Louis never does manage to wait long enough for it to solve even the @math{6\times6} case.) When Louis asks Eva Lu Ator for help, she points out that he has interchanged the order of the nested mappings -in the @t{flatmap}, writing it as +in the @code{flatmap}, writing it as @lisp (flatmap @@ -8609,9 +8609,9 @@ composed of repeated elements that are shifted and scaled.@footnote{The picture language is based on the language Peter Henderson created to construct images like M.C. Escher's ``Square Limit'' woodcut (see @ref{Henderson 1982}). The woodcut incorporates a repeated scaled pattern, similar to the arrangements drawn using -the @t{square-limit} procedure in this section.} In this language, the data +the @code{square-limit} procedure in this section.} In this language, the data objects being combined are represented as procedures rather than as list -structure. Just as @t{cons}, which satisfies the closure property, allowed +structure. Just as @code{cons}, which satisfies the closure property, allowed us to easily build arbitrarily complicated list structure, the operations in this language, which also satisfy the closure property, allow us to easily build arbitrarily complicated patterns. @@ -8644,11 +8644,11 @@ framework here. Part of the elegance of this picture language is that there is only one kind of element, called a @newterm{painter}. A painter draws an image that is shifted and scaled to fit within a designated parallelogram-shaped frame. For example, -there's a primitive painter we'll call @t{wave} that makes a crude line +there's a primitive painter we'll call @code{wave} that makes a crude line drawing, as shown in @ref{Figure 2.10}. The actual shape of the drawing depends on the frame---all four images in figure 2.10 are produced by the -same @t{wave} painter, but with respect to four different frames. Painters -can be more elaborate than this: The primitive painter called @t{rogers} +same @code{wave} painter, but with respect to four different frames. Painters +can be more elaborate than this: The primitive painter called @code{rogers} paints a picture of @acronym{MIT}'s founder, William Barton Rogers, as shown in @ref{Figure 2.11}.@footnote{William Barton Rogers (1804-1882) was the founder and first president of @acronym{MIT}. A geologist and talented teacher, he @@ -8703,13 +8703,13 @@ as so good a knight would surely have wished, in harness, at his post, and in the very part and act of public duty. @end quotation } The four images in figure 2.11 are drawn with respect to the same four -frames as the @t{wave} images in figure 2.10. +frames as the @code{wave} images in figure 2.10. @float @quotation @anchor{Figure 2.10} @ifinfo -@strong{Figure 2.10:} Images produced by the @t{wave} +@strong{Figure 2.10:} Images produced by the @code{wave} painter, with respect to four different frames. The frames, shown with dotted lines, are not part of the images. @@ -8719,7 +8719,7 @@ lines, are not part of the images. @sp 0.0 @center @image{fig/chap2/Fig2.10,58mm,,,.pdf} @sp 0.5 -@strong{Figure 2.10:} Images produced by the @t{wave} +@strong{Figure 2.10:} Images produced by the @code{wave} painter, with respect to four different frames. The frames, shown with dotted lines, are not part of the images. @sp 0.7 @@ -8752,25 +8752,25 @@ four frames as in @ref{Figure 2.10} (original image from Wikimedia Commons). @noindent To combine images, we use various operations that construct new painters from -given painters. For example, the @t{beside} operation takes two painters +given painters. For example, the @code{beside} operation takes two painters and produces a new, compound painter that draws the first painter's image in the left half of the frame and the second painter's image in the right half of -the frame. Similarly, @t{below} takes two painters and produces a compound +the frame. Similarly, @code{below} takes two painters and produces a compound painter that draws the first painter's image below the second painter's image. Some operations transform a single painter to produce a new painter. For -example, @t{flip-vert} takes a painter and produces a painter that draws its -image upside-down, and @t{flip-horiz} produces a painter that draws the +example, @code{flip-vert} takes a painter and produces a painter that draws its +image upside-down, and @code{flip-horiz} produces a painter that draws the original painter's image left-to-right reversed. @ref{Figure 2.12} shows the drawing of a painter called -@t{wave4} that is built up in two stages starting from @t{wave}: +@code{wave4} that is built up in two stages starting from @code{wave}: @float @quotation @anchor{Figure 2.12} @ifinfo @strong{Figure 2.12:} Creating a complex figure, starting -from the @t{wave} painter of @ref{Figure 2.10}. +from the @code{wave} painter of @ref{Figure 2.10}. [two graphic images not included] @@ -8784,7 +8784,7 @@ from the @t{wave} painter of @ref{Figure 2.10}. @center @image{fig/chap2/Fig2.12,118mm,,,.pdf} @sp 0.6 @strong{Figure 2.12:} Creating a complex figure, starting -from the @t{wave} painter of @ref{Figure 2.10}. +from the @code{wave} painter of @ref{Figure 2.10}. @sp 0.3 @end iftex @end quotation @@ -8798,9 +8798,9 @@ from the @t{wave} painter of @ref{Figure 2.10}. @noindent In building up a complex image in this manner we are exploiting the fact that painters are closed under the language's means of combination. The -@t{beside} or @t{below} of two painters is itself a painter; therefore, +@code{beside} or @code{below} of two painters is itself a painter; therefore, we can use it as an element in making more complex painters. As with building -up list structure using @t{cons}, the closure of our data under the means of +up list structure using @code{cons}, the closure of our data under the means of combination is crucial to the ability to create complex structures while using only a few operations. @@ -8810,7 +8810,7 @@ Scheme procedures. This means that we don't need a special abstraction mechanism in the picture language: Since the means of combination are ordinary Scheme procedures, we automatically have the capability to do anything with painter operations that we can do with procedures. For example, we can -abstract the pattern in @t{wave4} as +abstract the pattern in @code{wave4} as @lisp (define (flipped-pairs painter) (let ((painter2 @@ -8820,7 +8820,7 @@ abstract the pattern in @t{wave4} as @end lisp @noindent -and define @t{wave4} as an instance of this pattern: +and define @code{wave4} as an instance of this pattern: @lisp (define wave4 (flipped-pairs wave)) @@ -8830,7 +8830,7 @@ and define @t{wave4} as an instance of this pattern: @anchor{Figure 2.13} @quotation @ifinfo -@strong{Figure 2.13:} Recursive plans for @t{right-split} and @t{corner-split}. +@strong{Figure 2.13:} Recursive plans for @code{right-split} and @code{corner-split}. @example +-------------+-------------+ +------+------+-------------+ @@ -8855,7 +8855,7 @@ and define @t{wave4} as an instance of this pattern: @sp 0.3 @center @image{fig/chap2/Fig2.13a,132mm,,,.pdf} @sp 0.5 -@strong{Figure 2.13:} Recursive plans for @t{right-split} and @t{corner-split}. +@strong{Figure 2.13:} Recursive plans for @code{right-split} and @code{corner-split}. @sp 0.0 @end iftex @end quotation @@ -8902,9 +8902,9 @@ right (see @ref{Exercise 2.44}, @ref{Figure 2.13} and @ref{Figure 2.14}): @ifinfo @quotation @strong{Figure 2.14:} The recursive operations -@t{right-split} and @t{corner-split} applied to the painters @t{wave} -and @t{rogers}. Combining four @t{corner-split} figures produces -symmetric @t{square-limit} designs as shown in @ref{Figure 2.9}. +@code{right-split} and @code{corner-split} applied to the painters @code{wave} +and @code{rogers}. Combining four @code{corner-split} figures produces +symmetric @code{square-limit} designs as shown in @ref{Figure 2.9}. [two graphic images not included] @@ -8925,16 +8925,16 @@ symmetric @t{square-limit} designs as shown in @ref{Figure 2.9}. @sp 0.6 @noindent @strong{Figure 2.14:} The recursive operations -@t{right-@/split} and @t{corner-@/split} applied to the painters @t{wave} -and @t{rogers}. Combining four @t{corner-@/split} figures produces -symmetric @t{square-@/limit} designs as shown in @ref{Figure 2.9}. +@code{right-@/split} and @code{corner-@/split} applied to the painters @code{wave} +and @code{rogers}. Combining four @code{corner-@/split} figures produces +symmetric @code{square-@/limit} designs as shown in @ref{Figure 2.9}. @sp 0.0 @end iftex @end float -By placing four copies of a @t{corner-split} appropriately, we obtain a -pattern called @t{square-limit}, whose application to @t{wave} and -@t{rogers} is shown in @ref{Figure 2.9}: +By placing four copies of a @code{corner-split} appropriately, we obtain a +pattern called @code{square-limit}, whose application to @code{wave} and +@code{rogers} is shown in @ref{Figure 2.9}: @lisp (define (square-limit painter n) @@ -8946,9 +8946,9 @@ pattern called @t{square-limit}, whose application to @t{wave} and @quotation @strong{@anchor{Exercise 2.44}Exercise 2.44:} Define the procedure -@t{up-split} used by @t{corner-@/split}. It is similar to -@t{right-@/split}, except that it switches the roles of @t{below} and -@t{beside}. +@code{up-split} used by @code{corner-@/split}. It is similar to +@code{right-@/split}, except that it switches the roles of @code{below} and +@code{beside}. @end quotation @subsubheading Higher-order operations @@ -8959,13 +8959,13 @@ we can view the painter operations as elements to manipulate and can write means of combination for these elements---procedures that take painter operations as arguments and create new painter operations. -For example, @t{flipped-pairs} and @t{square-limit} each arrange four +For example, @code{flipped-pairs} and @code{square-limit} each arrange four copies of a painter's image in a square pattern; they differ only in how they orient the copies. One way to abstract this pattern of painter combination is with the following procedure, which takes four one-argument painter operations and produces a painter operation that transforms a given painter with those -four operations and arranges the results in a square. @t{Tl}, @t{tr}, -@t{bl}, and @t{br} are the transformations to apply to the top left copy, +four operations and arranges the results in a square. @code{Tl}, @code{tr}, +@code{bl}, and @code{br} are the transformations to apply to the top left copy, the top right copy, the bottom left copy, and the bottom right copy, respectively. @@ -8980,7 +8980,7 @@ respectively. @end lisp @noindent -Then @t{flipped-pairs} can be defined in terms of @t{square-@/of-@/four} as +Then @code{flipped-pairs} can be defined in terms of @code{square-@/of-@/four} as follows:@footnote{Equivalently, we could write @lisp @@ -9001,9 +9001,9 @@ follows:@footnote{Equivalently, we could write @end lisp @noindent -and @t{square-limit} can be expressed as@footnote{@t{Rotate180} rotates a -painter by 180 degrees (see @ref{Exercise 2.50}). Instead of @t{rotate180} -we could say @t{(compose flip-vert flip-horiz)}, using the @t{compose} +and @code{square-limit} can be expressed as@footnote{@code{Rotate180} rotates a +painter by 180 degrees (see @ref{Exercise 2.50}). Instead of @code{rotate180} +we could say @code{(compose flip-vert flip-horiz)}, using the @code{compose} procedure from @ref{Exercise 1.42}.} @lisp @@ -9017,9 +9017,9 @@ procedure from @ref{Exercise 1.42}.} @end lisp @quotation -@strong{@anchor{Exercise 2.45}Exercise 2.45:} @t{Right-split} and -@t{up-split} can be expressed as instances of a general splitting operation. -Define a procedure @t{split} with the property that evaluating +@strong{@anchor{Exercise 2.45}Exercise 2.45:} @code{Right-split} and +@code{up-split} can be expressed as instances of a general splitting operation. +Define a procedure @code{split} with the property that evaluating @lisp (define right-split (split beside below)) @@ -9027,7 +9027,7 @@ Define a procedure @t{split} with the property that evaluating @end lisp @noindent -produces procedures @t{right-split} and @t{up-split} with the same +produces procedures @code{right-split} and @code{up-split} with the same behaviors as the ones already defined. @end quotation @@ -9044,9 +9044,9 @@ more general parallelogram. @ref{Figure 2.15} shows a frame and its associated vectors. In accordance with data abstraction, we need not be specific yet about how frames are represented, other than to say that there is a constructor -@t{make-frame}, which takes three vectors and produces a frame, and three -corresponding selectors @t{origin-frame}, @t{edge1-frame}, and -@t{edge2-frame} (see @ref{Exercise 2.47}). +@code{make-frame}, which takes three vectors and produces a frame, and three +corresponding selectors @code{origin-frame}, @code{edge1-frame}, and +@code{edge2-frame} (see @ref{Exercise 2.47}). @float @quotation @@ -9102,7 +9102,7 @@ $$ {\rm Origin(Frame)} + x \cdot {\rm Edge_1(Frame)} + y \cdot {\rm Edge_2(Frame For example, (0, 0) is mapped to the origin of the frame, (1, 1) to the vertex diagonally opposite the origin, and (0.5, 0.5) to the center of the frame. We can create a frame's coordinate map with the following -procedure:@footnote{@t{Frame-coord-map} uses the vector operations described +procedure:@footnote{@code{Frame-coord-map} uses the vector operations described in @ref{Exercise 2.46} below, which we assume have been implemented using some representation for vectors. Because of data abstraction, it doesn't matter what this vector representation is, so long as the vector operations behave @@ -9121,7 +9121,7 @@ correctly.} @end lisp @noindent -Observe that applying @t{frame-coord-map} to a frame returns a procedure +Observe that applying @code{frame-coord-map} to a frame returns a procedure that, given a vector, returns a vector. If the argument vector is in the unit square, the result vector will be in the frame. For example, @@ -9140,10 +9140,10 @@ returns the same vector as @strong{@anchor{Exercise 2.46}Exercise 2.46:} A two-dimensional vector @math{\bf v} running from the origin to a point can be represented as a pair consisting of an @math{x}-coordinate and a @math{y}-coordinate. Implement a data abstraction for -vectors by giving a constructor @t{make-vect} and corresponding selectors -@t{xcor-vect} and @t{ycor-vect}. In terms of your selectors and -constructor, implement procedures @t{add-vect}, @t{sub-vect}, and -@t{scale-vect} that perform the operations vector addition, vector +vectors by giving a constructor @code{make-vect} and corresponding selectors +@code{xcor-vect} and @code{ycor-vect}. In terms of your selectors and +constructor, implement procedures @code{add-vect}, @code{sub-vect}, and +@code{scale-vect} that perform the operations vector addition, vector subtraction, and multiplying a vector by a scalar: @ifinfo @@ -9183,17 +9183,17 @@ implementation for frames. A painter is represented as a procedure that, given a frame as argument, draws a particular image shifted and scaled to fit the frame. That is to say, if -@t{p} is a painter and @t{f} is a frame, then we produce @t{p}'s image -in @t{f} by calling @t{p} with @t{f} as argument. +@code{p} is a painter and @code{f} is a frame, then we produce @code{p}'s image +in @code{f} by calling @code{p} with @code{f} as argument. The details of how primitive painters are implemented depend on the particular characteristics of the graphics system and the type of image to be drawn. For -instance, suppose we have a procedure @t{draw-line} that draws a line on the +instance, suppose we have a procedure @code{draw-line} that draws a line on the screen between two specified points. Then we can create painters for line -drawings, such as the @t{wave} painter in @ref{Figure 2.10}, from lists of -line segments as follows:@footnote{@t{Segments->painter} uses the +drawings, such as the @code{wave} painter in @ref{Figure 2.10}, from lists of +line segments as follows:@footnote{@code{Segments->painter} uses the representation for line segments described in @ref{Exercise 2.48} below. It -also uses the @t{for-each} procedure described in @ref{Exercise 2.23}.} +also uses the @code{for-each} procedure described in @ref{Exercise 2.23}.} @lisp (define (segments->painter segment-list) @@ -9218,9 +9218,9 @@ the picture language. We can create and intermix all sorts of primitive painters, based on a variety of graphics capabilities. The details of their implementation do not matter. Any procedure can serve as a painter, provided that it takes a frame as argument and draws something scaled to fit the -frame.@footnote{For example, the @t{rogers} painter of @ref{Figure 2.11} was +frame.@footnote{For example, the @code{rogers} painter of @ref{Figure 2.11} was constructed from a gray-level image. For each point in a given frame, the -@t{rogers} painter determines the point in the image that is mapped to it +@code{rogers} painter determines the point in the image that is mapped to it under the frame coordinate map, and shades it accordingly. By allowing different types of painters, we are capitalizing on the abstract data idea discussed in @ref{2.1.3}, where we argued that a rational-number @@ -9236,11 +9236,11 @@ plane can be represented as a pair of vectors---the vector running from the origin to the start-point of the segment, and the vector running from the origin to the end-point of the segment. Use your vector representation from @ref{Exercise 2.46} to define a representation for segments with a constructor -@t{make-segment} and selectors @t{start-segment} and @t{end-segment}. +@code{make-segment} and selectors @code{start-segment} and @code{end-segment}. @end quotation @quotation -@strong{@anchor{Exercise 2.49}Exercise 2.49:} Use @t{segments->painter} +@strong{@anchor{Exercise 2.49}Exercise 2.49:} Use @code{segments->painter} to define the following primitive painters: @enumerate a @@ -9256,25 +9256,25 @@ The painter that draws a diamond shape by connecting the midpoints of the sides of the frame. @item -The @t{wave} painter. +The @code{wave} painter. @end enumerate @end quotation @subsubheading Transforming and combining painters -An operation on painters (such as @t{flip-vert} or @t{beside}) works by +An operation on painters (such as @code{flip-vert} or @code{beside}) works by creating a painter that invokes the original painters with respect to frames -derived from the argument frame. Thus, for example, @t{flip-vert} doesn't +derived from the argument frame. Thus, for example, @code{flip-vert} doesn't have to know how a painter works in order to flip it---it just has to know how to turn a frame upside down: The flipped painter just uses the original painter, but in the inverted frame. -Painter operations are based on the procedure @t{trans-@/form-@/painter}, which +Painter operations are based on the procedure @code{trans-@/form-@/painter}, which takes as arguments a painter and information on how to transform a frame and produces a new painter. The transformed painter, when called on a frame, transforms the frame and calls the original painter on the transformed frame. -The arguments to @t{transform-@/painter} are points (represented as vectors) +The arguments to @code{transform-@/painter} are points (represented as vectors) that specify the corners of the new frame: When mapped into the frame, the first point specifies the new frame's origin and the other two specify the ends of its edge vectors. Thus, arguments within the unit square specify a frame @@ -9300,13 +9300,13 @@ Here's how to flip painter images vertically: (define (flip-vert painter) (transform-painter painter - (make-vect 0.0 1.0) @r{; new @t{origin}} - (make-vect 1.0 1.0) @r{; new end of @t{edge1}} - (make-vect 0.0 0.0))) @r{; new end of @t{edge2}} + (make-vect 0.0 1.0) @r{; new @code{origin}} + (make-vect 1.0 1.0) @r{; new end of @code{edge1}} + (make-vect 0.0 0.0))) @r{; new end of @code{edge2}} @end lisp @noindent -Using @t{transform-painter}, we can easily define new transformations. +Using @code{transform-painter}, we can easily define new transformations. For example, we can define a painter that shrinks its image to the upper-right quarter of the frame it is given: @@ -9320,7 +9320,7 @@ upper-right quarter of the frame it is given: @noindent Other transformations rotate images counterclockwise by 90 -degrees@footnote{@t{Rotate90} is a pure rotation only for square frames, +degrees@footnote{@code{Rotate90} is a pure rotation only for square frames, because it also stretches and shrinks the image to fit into the rotated frame.} @lisp @@ -9334,7 +9334,7 @@ because it also stretches and shrinks the image to fit into the rotated frame.} @noindent or squash images towards the center of the frame:@footnote{The diamond-shaped images in @ref{Figure 2.10} and @ref{Figure 2.11} were created with -@t{squash-inwards} applied to @t{wave} and @t{rogers}.} +@code{squash-inwards} applied to @code{wave} and @code{rogers}.} @lisp (define (squash-inwards painter) @@ -9346,7 +9346,7 @@ images in @ref{Figure 2.10} and @ref{Figure 2.11} were created with @noindent Frame transformation is also the key to defining means of combining two or more -painters. The @t{beside} procedure, for example, takes two painters, +painters. The @code{beside} procedure, for example, takes two painters, transforms them to paint in the left and right halves of an argument frame respectively, and produces a new, compound painter. When the compound painter is given a frame, it calls the first transformed painter to paint in the left @@ -9373,24 +9373,24 @@ right half of the frame: @noindent Observe how the painter data abstraction, and in particular the representation -of painters as procedures, makes @t{beside} easy to implement. The -@t{beside} procedure need not know anything about the details of the +of painters as procedures, makes @code{beside} easy to implement. The +@code{beside} procedure need not know anything about the details of the component painters other than that each painter will draw something in its designated frame. @quotation @strong{@anchor{Exercise 2.50}Exercise 2.50:} Define the transformation -@t{flip-@/horiz}, which flips painters horizontally, and transformations that +@code{flip-@/horiz}, which flips painters horizontally, and transformations that rotate painters counterclockwise by 180 degrees and 270 degrees. @end quotation @quotation -@strong{@anchor{Exercise 2.51}Exercise 2.51:} Define the @t{below} operation -for painters. @t{Below} takes two painters as arguments. The resulting +@strong{@anchor{Exercise 2.51}Exercise 2.51:} Define the @code{below} operation +for painters. @code{Below} takes two painters as arguments. The resulting painter, given a frame, draws with the first painter in the bottom of the frame -and with the second painter in the top. Define @t{below} in two different -ways---first by writing a procedure that is analogous to the @t{beside} -procedure given above, and again in terms of @t{beside} and suitable +and with the second painter in the top. Define @code{below} in two different +ways---first by writing a procedure that is analogous to the @code{beside} +procedure given above, and again in terms of @code{beside} and suitable rotation operations (from @ref{Exercise 2.50}). @end quotation @@ -9426,44 +9426,44 @@ languages appropriate for describing network interconnections, and so on. As a tiny example of stratification, our picture language uses primitive elements (primitive painters) that are created using a language that specifies points and lines to provide the lists of line segments for -@t{segments->painter}, or the shading details for a painter like -@t{rogers}. The bulk of our description of the picture language focused on -combining these primitives, using geometric combiners such as @t{beside} and -@t{below}. We also worked at a higher level, regarding @t{beside} and -@t{below} as primitives to be manipulated in a language whose operations, -such as @t{square-of-four}, capture common patterns of combining geometric +@code{segments->painter}, or the shading details for a painter like +@code{rogers}. The bulk of our description of the picture language focused on +combining these primitives, using geometric combiners such as @code{beside} and +@code{below}. We also worked at a higher level, regarding @code{beside} and +@code{below} as primitives to be manipulated in a language whose operations, +such as @code{square-of-four}, capture common patterns of combining geometric combiners. Stratified design helps make programs @newterm{robust}, that is, it makes it likely that small changes in a specification will require correspondingly small changes in the program. For instance, suppose we wanted to change the image -based on @t{wave} shown in @ref{Figure 2.9}. We could work at the lowest -level to change the detailed appearance of the @t{wave} element; we could -work at the middle level to change the way @t{corner-split} replicates the -@t{wave}; we could work at the highest level to change how -@t{square-limit} arranges the four copies of the corner. In general, each +based on @code{wave} shown in @ref{Figure 2.9}. We could work at the lowest +level to change the detailed appearance of the @code{wave} element; we could +work at the middle level to change the way @code{corner-split} replicates the +@code{wave}; we could work at the highest level to change how +@code{square-limit} arranges the four copies of the corner. In general, each level of a stratified design provides a different vocabulary for expressing the characteristics of the system, and a different kind of ability to change it. @endpage @quotation @strong{@anchor{Exercise 2.52}Exercise 2.52:} Make changes to the square limit -of @t{wave} shown in @ref{Figure 2.9} by working at each of the levels +of @code{wave} shown in @ref{Figure 2.9} by working at each of the levels described above. In particular: @enumerate a @item -Add some segments to the primitive @t{wave} painter of @ref{Exercise 2.49} +Add some segments to the primitive @code{wave} painter of @ref{Exercise 2.49} (to add a smile, for example). @item -Change the pattern constructed by @t{corner-split} (for example, by using -only one copy of the @t{up-@/split} and @t{right-split} images instead of +Change the pattern constructed by @code{corner-split} (for example, by using +only one copy of the @code{up-@/split} and @code{right-split} images instead of two). @item -Modify the version of @t{square-limit} that uses @t{square-of-four} so as +Modify the version of @code{square-limit} that uses @code{square-of-four} so as to assemble the corners in a different pattern. (For example, you might make the big Mr. Rogers look outward from each corner of the square.) @@ -9515,9 +9515,9 @@ language: @noindent In order to manipulate symbols we need a new element in our language: the ability to @newterm{quote} a data object. Suppose we want to construct the -list @t{(a b)}. We can't accomplish this with @t{(list a b)}, because -this expression constructs a list of the @newterm{values} of @t{a} and -@t{b} rather than the symbols themselves. This issue is well known in the +list @code{(a b)}. We can't accomplish this with @code{(list a b)}, because +this expression constructs a list of the @newterm{values} of @code{a} and +@code{b} rather than the symbols themselves. This issue is well known in the context of natural languages, where words and sentences may be regarded either as semantic entities or as character strings (syntactic entities). The common practice in natural languages is to use quotation marks to indicate that a word @@ -9543,7 +9543,7 @@ Venus'' we cannot infer that ``John knows that the morning star is Venus.''} We can follow this same practice to identify lists and symbols that are to be treated as data objects rather than as expressions to be evaluated. However, our format for quoting differs from that of natural languages in that we place -a quotation mark (traditionally, the single quote symbol @t{'}) only at the +a quotation mark (traditionally, the single quote symbol @code{'}) only at the beginning of the object to be quoted. We can get away with this in Scheme syntax because we rely on blanks and parentheses to delimit objects. Thus, the meaning of the single quote character is to quote the next object.@footnote{The @@ -9570,16 +9570,16 @@ Quotation also allows us to type in compound objects, using the conventional printed representation for lists:@footnote{Strictly, our use of the quotation mark violates the general rule that all compound expressions in our language should be delimited by parentheses and look like lists. We can recover this -consistency by introducing a special form @t{quote}, which serves the same -purpose as the quotation mark. Thus, we would type @t{(quote a)} instead of -@t{'a}, and we would type @t{(quote (a b c))} instead of @t{'(a b c)}. +consistency by introducing a special form @code{quote}, which serves the same +purpose as the quotation mark. Thus, we would type @code{(quote a)} instead of +@code{'a}, and we would type @code{(quote (a b c))} instead of @code{'(a b c)}. This is precisely how the interpreter works. The quotation mark is just a single-character abbreviation for wrapping the next complete expression with -@t{quote} to form @math{\hbox{\tt(quote}\;\langle\kern0.06em\hbox{\ttsl expression}\kern0.08em\rangle\hbox{\tt)}}. This is +@code{quote} to form @math{\hbox{\tt(quote}\;\langle\kern0.06em\hbox{\ttsl expression}\kern0.08em\rangle\hbox{\tt)}}. This is important because it maintains the principle that any expression seen by the interpreter can be manipulated as a data object. For instance, we could -construct the expression @t{(car '(a b c))}, which is the same as @t{(car -(quote (a b c)))}, by evaluating @t{(list 'car (list 'quote '(a b c)))}.} +construct the expression @code{(car '(a b c))}, which is the same as @code{(car +(quote (a b c)))}, by evaluating @code{(list 'car (list 'quote '(a b c)))}.} @lisp (car '(a b c)) @@ -9589,18 +9589,18 @@ construct the expression @t{(car '(a b c))}, which is the same as @t{(car @end lisp @noindent -In keeping with this, we can obtain the empty list by evaluating @t{'()}, -and thus dispense with the variable @t{nil}. +In keeping with this, we can obtain the empty list by evaluating @code{'()}, +and thus dispense with the variable @code{nil}. -One additional primitive used in manipulating symbols is @t{eq?}, which +One additional primitive used in manipulating symbols is @code{eq?}, which takes two symbols as arguments and tests whether they are the same.@footnote{We can consider two symbols to be ``the same'' if they consist of the same characters in the same order. Such a definition skirts a deep issue that we are not yet ready to address: the meaning of ``sameness'' in a programming language. We will return to this in @ref{Chapter 3} (@ref{3.1.3}).} -Using @t{eq?}, we can implement a useful procedure called @t{memq}. This +Using @code{eq?}, we can implement a useful procedure called @code{memq}. This takes two arguments, a symbol and a list. If the symbol is not contained in -the list (i.e., is not @t{eq?} to any item in the list), then @t{memq} +the list (i.e., is not @code{eq?} to any item in the list), then @code{memq} returns false. Otherwise, it returns the sublist of the list beginning with the first occurrence of the symbol: @@ -9626,7 +9626,7 @@ is false, whereas the value of @end lisp @noindent -is @t{(apple pear)}. +is @code{(apple pear)}. @quotation @strong{@anchor{Exercise 2.53}Exercise 2.53:} What would the interpreter print @@ -9645,7 +9645,7 @@ in response to evaluating each of the following expressions? @quotation @strong{@anchor{Exercise 2.54}Exercise 2.54:} Two lists are said to be -@t{equal?} if they contain equal elements arranged in the same order. For +@code{equal?} if they contain equal elements arranged in the same order. For example, @lisp @@ -9662,19 +9662,19 @@ is true, but @end lisp @noindent -is false. To be more precise, we can define @t{equal?} recursively in -terms of the basic @t{eq?} equality of symbols by saying that @t{a} and -@t{b} are @t{equal?} if they are both symbols and the symbols are -@t{eq?}, or if they are both lists such that @t{(car a)} is @t{equal?} -to @t{(car b)} and @t{(cdr a)} is @t{equal?} to @t{(cdr b)}. Using -this idea, implement @t{equal?} as a procedure.@footnote{In practice, -programmers use @t{equal?} to compare lists that contain numbers as well as +is false. To be more precise, we can define @code{equal?} recursively in +terms of the basic @code{eq?} equality of symbols by saying that @code{a} and +@code{b} are @code{equal?} if they are both symbols and the symbols are +@code{eq?}, or if they are both lists such that @code{(car a)} is @code{equal?} +to @code{(car b)} and @code{(cdr a)} is @code{equal?} to @code{(cdr b)}. Using +this idea, implement @code{equal?} as a procedure.@footnote{In practice, +programmers use @code{equal?} to compare lists that contain numbers as well as symbols. Numbers are not considered to be symbols. The question of whether -two numerically equal numbers (as tested by @t{=}) are also @t{eq?} is -highly implementation-dependent. A better definition of @t{equal?} (such as +two numerically equal numbers (as tested by @code{=}) are also @code{eq?} is +highly implementation-dependent. A better definition of @code{equal?} (such as the one that comes as a primitive in Scheme) would also stipulate that if -@t{a} and @t{b} are both numbers, then @t{a} and @t{b} are -@t{equal?} if they are numerically equal.} +@code{a} and @code{b} are both numbers, then @code{a} and @code{b} are +@code{equal?} if they are numerically equal.} @end quotation @quotation @@ -9685,7 +9685,7 @@ interpreter the expression (car ''abracadabra) @end lisp -To her surprise, the interpreter prints back @t{quote}. Explain. +To her surprise, the interpreter prints back @code{quote}. Explain. @end quotation @node 2.3.2, 2.3.3, 2.3.1, 2.3 @@ -9782,20 +9782,20 @@ already have procedures to implement the following selectors, constructors, and predicates: @smallexample -(variable? e) @r{Is @t{e} a variable?} -(same-variable? v1 v2) @r{Are @t{v1} and @t{v2} the same variable?} -(sum? e) @r{Is @t{e} a sum?} -(addend e) @r{Addend of the sum @t{e}.} -(augend e) @r{Augend of the sum @t{e}.} -(make-sum a1 a2) @r{Construct the sum of @t{a1} and @t{a2}.} -(product? e) @r{Is @t{e} a product?} -(multiplier e) @r{Multiplier of the product @t{e}.} -(multiplicand e) @r{Multiplicand of the product @t{e}.} -(make-product m1 m2) @r{Construct the product of @t{m1} and @t{m2}.} +(variable? e) @r{Is @code{e} a variable?} +(same-variable? v1 v2) @r{Are @code{v1} and @code{v2} the same variable?} +(sum? e) @r{Is @code{e} a sum?} +(addend e) @r{Addend of the sum @code{e}.} +(augend e) @r{Augend of the sum @code{e}.} +(make-sum a1 a2) @r{Construct the sum of @code{a1} and @code{a2}.} +(product? e) @r{Is @code{e} a product?} +(multiplier e) @r{Multiplier of the product @code{e}.} +(multiplicand e) @r{Multiplicand of the product @code{e}.} +(make-product m1 m2) @r{Construct the product of @code{m1} and @code{m2}.} @end smallexample @noindent -Using these, and the primitive predicate @t{number?}, which identifies +Using these, and the primitive predicate @code{number?}, which identifies numbers, we can express the differentiation rules as the following procedure: @lisp @@ -9819,7 +9819,7 @@ numbers, we can express the differentiation rules as the following procedure: @end lisp @noindent -This @t{deriv} procedure incorporates the complete differentiation +This @code{deriv} procedure incorporates the complete differentiation algorithm. Since it is expressed in terms of abstract data, it will work no matter how we choose to represent algebraic expressions, as long as we design a proper set of selectors and constructors. This is the issue we must address @@ -9829,24 +9829,24 @@ next. We can imagine many ways to use list structure to represent algebraic expressions. For example, we could use lists of symbols that mirror the usual -algebraic notation, representing @math{ax + b} as the list @t{(a * x + +algebraic notation, representing @math{ax + b} as the list @code{(a * x + b)} . However, one especially straightforward choice is to use the same parenthesized prefix notation that Lisp uses for combinations; that is, to -represent @math{ax + b} as @t{(+ (* a x) b)}. Then our data +represent @math{ax + b} as @code{(+ (* a x) b)}. Then our data representation for the differentiation problem is as follows: @itemize @bullet @item The variables are symbols. They are identified by the primitive predicate -@t{symbol?}: +@code{symbol?}: @lisp (define (variable? x) (symbol? x)) @end lisp @item -Two variables are the same if the symbols representing them are @t{eq?}: +Two variables are the same if the symbols representing them are @code{eq?}: @lisp (define (same-variable? v1 v2) @@ -9864,7 +9864,7 @@ Sums and products are constructed as lists: @end lisp @item -A sum is a list whose first element is the symbol @t{+}: +A sum is a list whose first element is the symbol @code{+}: @lisp (define (sum? x) @@ -9886,7 +9886,7 @@ The augend is the third item of the sum list: @end lisp @item -A product is a list whose first element is the symbol @t{*}: +A product is a list whose first element is the symbol @code{*}: @lisp (define (product? x) (and (pair? x) (eq? (car x) '*))) @@ -9909,7 +9909,7 @@ The multiplicand is the third item of the product list: @end itemize @noindent -Thus, we need only combine these with the algorithm as embodied by @t{deriv} +Thus, we need only combine these with the algorithm as embodied by @code{deriv} in order to have a working symbolic-differentiation program. Let us look at some examples of its behavior: @@ -9944,16 +9944,16 @@ $$ {{\it d\,(xy)} \over {\it dx}} = x \cdot 0 + 1 \cdot y, $$ @noindent but we would like the program to know that @math{x \cdot 0 = 0}, @math{1 \cdot y = y}, and @math{0 + y = y}. The answer for the second example should have been -simply @t{y}. As the third example shows, this becomes a serious issue when +simply @code{y}. As the third example shows, this becomes a serious issue when the expressions are complex. Our difficulty is much like the one we encountered with the rational-number implementation: we haven't reduced answers to simplest form. To accomplish the rational-number reduction, we needed to change only the constructors and the selectors of the implementation. We can adopt a similar strategy here. We -won't change @t{deriv} at all. Instead, we will change @t{make-sum} so -that if both summands are numbers, @t{make-sum} will add them and return -their sum. Also, if one of the summands is 0, then @t{make-sum} will return +won't change @code{deriv} at all. Instead, we will change @code{make-sum} so +that if both summands are numbers, @code{make-sum} will add them and return +their sum. Also, if one of the summands is 0, then @code{make-sum} will return the other summand: @lisp (define (make-sum a1 a2) @@ -9965,7 +9965,7 @@ the other summand: @end lisp @noindent -This uses the procedure @t{=number?}, which checks whether an expression is +This uses the procedure @code{=number?}, which checks whether an expression is equal to a given number: @lisp @@ -9974,7 +9974,7 @@ equal to a given number: @end lisp @noindent -Similarly, we will change @t{make-product} to build in the rules that 0 +Similarly, we will change @code{make-product} to build in the rules that 0 times anything is 0 and 1 times anything is the thing itself: @lisp @@ -10025,9 +10025,9 @@ d(u^n) du $$ {{\it d\,(\!u^n)} \over {\it dx}} = nu^{n-1} {{\it du} \over {\it dx}} $$ @end tex @noindent -by adding a new clause to the @t{deriv} program and defining appropriate -procedures @t{exponentiation?}, @t{base}, @t{exponent}, and -@t{make-@/exponentiation}. (You may use the symbol @t{**} to denote +by adding a new clause to the @code{deriv} program and defining appropriate +procedures @code{exponentiation?}, @code{base}, @code{exponent}, and +@code{make-@/exponentiation}. (You may use the symbol @code{**} to denote exponentiation.) Build in the rules that anything raised to the power 0 is 1 and anything raised to the power 1 is the thing itself. @end quotation @@ -10042,15 +10042,15 @@ terms. Then the last example above could be expressed as @end lisp Try to do this by changing only the representation for sums and products, -without changing the @t{deriv} procedure at all. For example, the -@t{addend} of a sum would be the first term, and the @t{augend} would be +without changing the @code{deriv} procedure at all. For example, the +@code{addend} of a sum would be the first term, and the @code{augend} would be the sum of the rest of the terms. @end quotation @quotation @strong{@anchor{Exercise 2.58}Exercise 2.58:} Suppose we want to modify the differentiation program so that it works with ordinary mathematical notation, -in which @t{+} and @t{*} are infix rather than prefix operators. Since +in which @code{+} and @code{*} are infix rather than prefix operators. Since the differentiation program is defined in terms of abstract data, we can modify it to work with different representations of expressions solely by changing the predicates, selectors, and constructors that define the representation of the @@ -10060,13 +10060,13 @@ algebraic expressions on which the differentiator is to operate. @item Show how to do this in order to differentiate algebraic expressions presented -in infix form, such as @t{(x + (3 * (x + (y + 2))))}. To simplify the task, -assume that @t{+} and @t{*} always take two arguments and that +in infix form, such as @code{(x + (3 * (x + (y + 2))))}. To simplify the task, +assume that @code{+} and @code{*} always take two arguments and that expressions are fully parenthesized. @item The problem becomes substantially harder if we allow standard algebraic -notation, such as @t{(x + 3 * (x + y + 2))}, which drops unnecessary +notation, such as @code{(x + 3 * (x + y + 2))}, which drops unnecessary parentheses and assumes that multiplication is done before addition. Can you design appropriate predicates, selectors, and constructors for this notation such that our derivative program still works? @@ -10089,13 +10089,13 @@ differ significantly from one another in several ways. Informally, a set is simply a collection of distinct objects. To give a more precise definition we can employ the method of data abstraction. That is, we define ``set'' by specifying the operations that are to be used on sets. These -are @t{union-set}, @t{intersection-set}, @t{element-of-set?}, and -@t{adjoin-set}. @t{Element-of-set?} is a predicate that determines -whether a given element is a member of a set. @t{Adjoin-@/set} takes an +are @code{union-set}, @code{intersection-set}, @code{element-of-set?}, and +@code{adjoin-set}. @code{Element-of-set?} is a predicate that determines +whether a given element is a member of a set. @code{Adjoin-@/set} takes an object and a set as arguments and returns a set that contains the elements of -the original set and also the adjoined element. @t{Union-set} computes the +the original set and also the adjoined element. @code{Union-set} computes the union of two sets, which is the set containing each element that appears in -either argument. @t{Intersection-set} computes the intersection of two +either argument. @code{Intersection-set} computes the intersection of two sets, which is the set containing only elements that appear in both arguments. From the viewpoint of data abstraction, we are free to design any representation that implements these operations in a way consistent with the @@ -10104,22 +10104,22 @@ specify ``consistent with the interpretations given above'' to mean that the operations satisfy a collection of rules such as these: @noindent -@math{\bullet} For any set @t{S} and any object @t{x}, -@t{(element-of-set? x (adjoin-set x S))} +@math{\bullet} For any set @code{S} and any object @code{x}, +@code{(element-of-set? x (adjoin-set x S))} is true (informally: ``Adjoining an object to a set produces a set that contains the object''). @noindent -@math{\bullet} For any sets @t{S} and @t{T} and any object @t{x}, -@t{(element-of-set? x (union-set S T))} +@math{\bullet} For any sets @code{S} and @code{T} and any object @code{x}, +@code{(element-of-set? x (union-set S T))} is equal to -@t{(or (element-of-set? x S) (element-of-set? x T))} -(informally: ``The elements of @t{(union S T)} are the elements that -are in @t{S} or in @t{T}''). +@code{(or (element-of-set? x S) (element-of-set? x T))} +(informally: ``The elements of @code{(union S T)} are the elements that +are in @code{S} or in @code{T}''). @noindent -@math{\bullet} For any object @t{x}, -@t{(element-of-set? x '())} +@math{\bullet} For any object @code{x}, +@code{(element-of-set? x '())} is false (informally: ``No object is an element of the empty set''). } @@ -10127,9 +10127,9 @@ is false (informally: ``No object is an element of the empty set''). One way to represent a set is as a list of its elements in which no element appears more than once. The empty set is represented by the empty list. In -this representation, @t{element-of-set?} is similar to the procedure -@t{memq} of @ref{2.3.1}. It uses @t{equal?} instead of -@t{eq?} so that the set elements need not be symbols: +this representation, @code{element-of-set?} is similar to the procedure +@code{memq} of @ref{2.3.1}. It uses @code{equal?} instead of +@code{eq?} so that the set elements need not be symbols: @lisp (define (element-of-set? x set) @@ -10139,8 +10139,8 @@ this representation, @t{element-of-set?} is similar to the procedure @end lisp @noindent -Using this, we can write @t{adjoin-set}. If the object to be adjoined is -already in the set, we just return the set. Otherwise, we use @t{cons} to +Using this, we can write @code{adjoin-set}. If the object to be adjoined is +already in the set, we just return the set. Otherwise, we use @code{cons} to add the object to the list that represents the set: @lisp @@ -10151,10 +10151,10 @@ add the object to the list that represents the set: @end lisp @noindent -For @t{intersection-set} we can use a recursive strategy. If we know how to -form the intersection of @t{set2} and the @t{cdr} of @t{set1}, we only -need to decide whether to include the @t{car} of @t{set1} in this. But -this depends on whether @t{(car set1)} is also in @t{set2}. Here is the +For @code{intersection-set} we can use a recursive strategy. If we know how to +form the intersection of @code{set2} and the @code{cdr} of @code{set1}, we only +need to decide whether to include the @code{car} of @code{set1} in this. But +this depends on whether @code{(car set1)} is also in @code{set2}. Here is the resulting procedure: @lisp @@ -10172,30 +10172,30 @@ resulting procedure: @noindent In designing a representation, one of the issues we should be concerned with is efficiency. Consider the number of steps required by our set operations. -Since they all use @t{element-of-set?}, the speed of this operation has a +Since they all use @code{element-of-set?}, the speed of this operation has a major impact on the efficiency of the set implementation as a whole. Now, in -order to check whether an object is a member of a set, @t{element-of-set?} +order to check whether an object is a member of a set, @code{element-of-set?} may have to scan the entire set. (In the worst case, the object turns out not to be in the set.) Hence, if the set has @math{n} elements, -@t{element-of-set?} might take up to @math{n} steps. Thus, the number of +@code{element-of-set?} might take up to @math{n} steps. Thus, the number of steps required grows as @math{\Theta(n)}. The number of steps required by -@t{adjoin-set}, which uses this operation, also grows as @math{\Theta(n)}. -For @t{intersection-set}, which does an @t{element-of-set?} check for -each element of @t{set1}, the number of steps required grows as the product +@code{adjoin-set}, which uses this operation, also grows as @math{\Theta(n)}. +For @code{intersection-set}, which does an @code{element-of-set?} check for +each element of @code{set1}, the number of steps required grows as the product of the sizes of the sets involved, or @math{\Theta(n^2)} for two sets of size -@math{n}. The same will be true of @t{union-set}. +@math{n}. The same will be true of @code{union-set}. @quotation -@strong{@anchor{Exercise 2.59}Exercise 2.59:} Implement the @t{union-set} +@strong{@anchor{Exercise 2.59}Exercise 2.59:} Implement the @code{union-set} operation for the unordered-list representation of sets. @end quotation @quotation @strong{@anchor{Exercise 2.60}Exercise 2.60:} We specified that a set would be represented as a list with no duplicates. Now suppose we allow duplicates. -For instance, the set @math{\{1, 2, 3\}} could be represented as the list @t{(2 3 2 1 -3 2 2)}. Design procedures @t{element-of-set?}, @t{adjoin-set}, -@t{union-set}, and @t{intersection-set} that operate on this +For instance, the set @math{\{1, 2, 3\}} could be represented as the list @code{(2 3 2 1 +3 2 2)}. Design procedures @code{element-of-set?}, @code{adjoin-set}, +@code{union-set}, and @code{intersection-set} that operate on this representation. How does the efficiency of each compare with the corresponding procedure for the non-duplicate representation? Are there applications for which you would use this representation in preference to the non-duplicate one? @@ -10210,13 +10210,13 @@ could compare symbols lexicographically, or we could agree on some method for assigning a unique number to an object and then compare the elements by comparing the corresponding numbers. To keep our discussion simple, we will consider only the case where the set elements are numbers, so that we can -compare elements using @t{>} and @t{<}. We will represent a set of +compare elements using @code{>} and @code{<}. We will represent a set of numbers by listing its elements in increasing order. Whereas our first representation above allowed us to represent the set @math{\{1, 3, 6, 10\}} by listing -the elements in any order, our new representation allows only the list @t{(1 +the elements in any order, our new representation allows only the list @code{(1 3 6 10)}. -One advantage of ordering shows up in @t{element-@/of-@/set?}: In checking for +One advantage of ordering shows up in @code{element-@/of-@/set?}: In checking for the presence of an item, we no longer have to scan the entire set. If we reach a set element that is larger than the item we are looking for, then we know that the item is not in the set: @@ -10240,20 +10240,20 @@ number of steps required will be about @math{n \big/ 2}. This is still @math{\Theta(n)} growth, but it does save us, on the average, a factor of 2 in number of steps over the previous implementation. -We obtain a more impressive speedup with @t{inter-@/section-set}. In the +We obtain a more impressive speedup with @code{inter-@/section-set}. In the unordered representation this operation required @math{\Theta(n^2)} steps, -because we performed a complete scan of @t{set2} for each element of -@t{set1}. But with the ordered representation, we can use a more clever -method. Begin by comparing the initial elements, @t{x1} and @t{x2}, of -the two sets. If @t{x1} equals @t{x2}, then that gives an element of the +because we performed a complete scan of @code{set2} for each element of +@code{set1}. But with the ordered representation, we can use a more clever +method. Begin by comparing the initial elements, @code{x1} and @code{x2}, of +the two sets. If @code{x1} equals @code{x2}, then that gives an element of the intersection, and the rest of the intersection is the intersection of the -@t{cdr}-s of the two sets. Suppose, however, that @t{x1} is less than -@t{x2}. Since @t{x2} is the smallest element in @t{set2}, we can -immediately conclude that @t{x1} cannot appear anywhere in @t{set2} and +@code{cdr}-s of the two sets. Suppose, however, that @code{x1} is less than +@code{x2}. Since @code{x2} is the smallest element in @code{set2}, we can +immediately conclude that @code{x1} cannot appear anywhere in @code{set2} and hence is not in the intersection. Hence, the intersection is equal to the -intersection of @t{set2} with the @t{cdr} of @t{set1}. Similarly, if -@t{x2} is less than @t{x1}, then the intersection is given by the -intersection of @t{set1} with the @t{cdr} of @t{set2}. Here is the +intersection of @code{set2} with the @code{cdr} of @code{set1}. Similarly, if +@code{x2} is less than @code{x1}, then the intersection is given by the +intersection of @code{set1} with the @code{cdr} of @code{set2}. Here is the procedure: @lisp @@ -10276,23 +10276,23 @@ procedure: @noindent To estimate the number of steps required by this process, observe that at each step we reduce the intersection problem to computing intersections of smaller -sets---removing the first element from @t{set1} or @t{set2} or both. +sets---removing the first element from @code{set1} or @code{set2} or both. Thus, the number of steps required is at most the sum of the sizes of -@t{set1} and @t{set2}, rather than the product of the sizes as with the +@code{set1} and @code{set2}, rather than the product of the sizes as with the unordered representation. This is @math{\Theta(n)} growth rather than @math{\Theta(n^2)}---a considerable speedup, even for sets of moderate size. @quotation @strong{@anchor{Exercise 2.61}Exercise 2.61:} Give an implementation of -@t{adjoin-@/set} using the ordered representation. By analogy with -@t{element-of-set?} show how to take advantage of the ordering to produce a +@code{adjoin-@/set} using the ordered representation. By analogy with +@code{element-of-set?} show how to take advantage of the ordering to produce a procedure that requires on the average about half as many steps as with the unordered representation. @end quotation @quotation @strong{@anchor{Exercise 2.62}Exercise 2.62:} Give a @math{\Theta(n)} -implementation of @t{union-@/set} for sets represented as ordered lists. +implementation of @code{union-@/set} for sets represented as ordered lists. @end quotation @float @@ -10355,8 +10355,8 @@ or a right subtree of the empty list will indicate that there is no subtree connected there. We can describe this representation by the following procedures:@footnote{We are representing sets in terms of trees, and trees in terms of lists---in effect, a data abstraction built upon a data abstraction. -We can regard the procedures @t{entry}, @t{left-branch}, -@t{right-branch}, and @t{make-tree} as a way of isolating the abstraction +We can regard the procedures @code{entry}, @code{left-branch}, +@code{right-branch}, and @code{make-tree} as a way of isolating the abstraction of a ``binary tree'' from the particular way we might wish to represent such a tree in terms of list structure.} @@ -10369,7 +10369,7 @@ tree in terms of list structure.} @end lisp @noindent -Now we can write the @t{element-of-set?} procedure using the strategy +Now we can write the @code{element-of-set?} procedure using the strategy described above: @lisp @@ -10388,13 +10388,13 @@ described above: @noindent Adjoining an item to a set is implemented similarly and also requires -@math{\Theta(\log n)} steps. To adjoin an item @t{x}, we compare -@t{x} with the node entry to determine whether @t{x} should be added to -the right or to the left branch, and having adjoined @t{x} to the +@math{\Theta(\log n)} steps. To adjoin an item @code{x}, we compare +@code{x} with the node entry to determine whether @code{x} should be added to +the right or to the left branch, and having adjoined @code{x} to the appropriate branch we piece this newly constructed branch together with the -original entry and the other branch. If @t{x} is equal to the entry, we -just return the node. If we are asked to adjoin @t{x} to an empty tree, we -generate a tree that has @t{x} as the entry and empty right and left +original entry and the other branch. If @code{x} is equal to the entry, we +just return the node. If we are asked to adjoin @code{x} to an empty tree, we +generate a tree that has @code{x} as the entry and empty right and left branches. Here is the procedure: @lisp @@ -10420,7 +10420,7 @@ that the left and the right subtree of every tree have approximately the same number of elements, so that each subtree contains about half the elements of its parent. But how can we be certain that the trees we construct will be balanced? Even if we start with a balanced tree, adding elements with -@t{adjoin-set} may produce an unbalanced result. Since the position of a +@code{adjoin-set} may produce an unbalanced result. Since the position of a newly adjoined element depends on how the element compares with the items already in the set, we can expect that if we add elements ``randomly'' the tree will tend to be balanced on the average. But this is not a guarantee. For @@ -10429,7 +10429,7 @@ sequence we end up with the highly unbalanced tree shown in @ref{Figure 2.17}. In this tree all the left subtrees are empty, so it has no advantage over a simple ordered list. One way to solve this problem is to define an operation that transforms an arbitrary tree into a balanced tree with the same elements. -Then we can perform this transformation after every few @t{adjoin-set} +Then we can perform this transformation after every few @code{adjoin-set} operations to keep our set in balance. There are also other ways to solve this problem, most of which involve designing new data structures for which searching and insertion both can be done in @math{\Theta(\log n)} @@ -10512,12 +10512,12 @@ which one grows more slowly? @quotation @strong{@anchor{Exercise 2.64}Exercise 2.64:} The following procedure -@t{list->@/tree} converts an ordered list to a balanced binary tree. The -helper procedure @t{partial-tree} takes as arguments an integer @math{n} and +@code{list->@/tree} converts an ordered list to a balanced binary tree. The +helper procedure @code{partial-tree} takes as arguments an integer @math{n} and list of at least @math{n} elements and constructs a balanced tree containing the -first @math{n} elements of the list. The result returned by @t{partial-@/tree} -is a pair (formed with @t{cons}) whose @t{car} is the constructed tree -and whose @t{cdr} is the list of elements not included in the tree. +first @math{n} elements of the list. The result returned by @code{partial-@/tree} +is a pair (formed with @code{cons}) whose @code{car} is the constructed tree +and whose @code{cdr} is the list of elements not included in the tree. @lisp (define (list->tree elements) @@ -10557,12 +10557,12 @@ and whose @t{cdr} is the list of elements not included in the tree. @item Write a short paragraph explaining as clearly as you can how -@t{partial-tree} works. Draw the tree produced by @t{list->tree} for -the list @t{(1 3 5 7 9 11)}. +@code{partial-tree} works. Draw the tree produced by @code{list->tree} for +the list @code{(1 3 5 7 9 11)}. @item What is the order of growth in the number of steps required by -@t{list->tree} to convert a list of @math{n} elements? +@code{list->tree} to convert a list of @math{n} elements? @end enumerate @end quotation @@ -10570,7 +10570,7 @@ What is the order of growth in the number of steps required by @quotation @strong{@anchor{Exercise 2.65}Exercise 2.65:} Use the results of @ref{Exercise 2.63} and @ref{Exercise 2.64} to give @math{\Theta(n)} implementations of -@t{union-@/set} and @t{intersection-set} for sets implemented as (balanced) +@code{union-@/set} and @code{intersection-set} for sets implemented as (balanced) binary trees.@footnote{@ref{Exercise 2.63} through @ref{Exercise 2.65} are due to Paul Hilfinger.} @end quotation @@ -10592,14 +10592,14 @@ serve as an identifying @newterm{key}. A key can be anything that uniquely identifies the record. For a personnel file, it might be an employee's ID number. For an accounting system, it might be a transaction number. Whatever the key is, when we define the record as a data structure we should include a -@t{key} selector procedure that retrieves the key associated with a given +@code{key} selector procedure that retrieves the key associated with a given record. Now we represent the data base as a set of records. To locate the record with a -given key we use a procedure @t{lookup}, which takes as arguments a key and +given key we use a procedure @code{lookup}, which takes as arguments a key and a data base and which returns the record that has that key, or false if there -is no such record. @t{Lookup} is implemented in almost the same way as -@t{element-of-set?}. For example, if the set of records is implemented as +is no such record. @code{Lookup} is implemented in almost the same way as +@code{element-of-set?}. For example, if the set of records is implemented as an unordered list, we could use @lisp @@ -10628,7 +10628,7 @@ selectors and constructors, this change in representation will not require any changes to the rest of the system. @quotation -@strong{@anchor{Exercise 2.66}Exercise 2.66:} Implement the @t{lookup} +@strong{@anchor{Exercise 2.66}Exercise 2.66:} Implement the @code{lookup} procedure for the case where the set of records is structured as a binary tree, ordered by the numerical values of the keys. @end quotation @@ -10837,7 +10837,7 @@ algorithm outlined above. We will begin by discussing how trees are represented. Leaves of the tree are represented by a list consisting of the symbol -@t{leaf}, the symbol at the leaf, and the weight: +@code{leaf}, the symbol at the leaf, and the weight: @lisp (define (make-leaf symbol weight) @@ -10855,7 +10855,7 @@ symbols, rather than some more sophisticated set representation. When we make a tree by merging two nodes, we obtain the weight of the tree as the sum of the weights of the nodes, and the set of symbols as the union of the sets of symbols for the nodes. Since our symbol sets are represented as lists, we can -form the union by using the @t{append} procedure we defined in +form the union by using the @code{append} procedure we defined in @ref{2.2.1}: @lisp @@ -10885,7 +10885,7 @@ If we make a tree in this way, we have the following selectors: @end lisp @noindent -The procedures @t{symbols} and @t{weight} must do something slightly +The procedures @code{symbols} and @code{weight} must do something slightly different depending on whether they are called with a leaf or a general tree. These are simple examples of @newterm{generic procedures} (procedures that can handle more than one kind of data), which we will have much more to say about @@ -10922,14 +10922,14 @@ arguments a list of zeros and ones, together with a Huffman tree. @endpage @noindent -The procedure @t{decode-1} takes two arguments: the list of remaining bits +The procedure @code{decode-1} takes two arguments: the list of remaining bits and the current position in the tree. It keeps moving ``down'' the tree, choosing a left or a right branch according to whether the next bit in the list -is a zero or a one. (This is done with the procedure @t{choose-branch}.) +is a zero or a one. (This is done with the procedure @code{choose-branch}.) When it reaches a leaf, it returns the symbol at that leaf as the next symbol -in the message by @t{cons}ing it onto the result of decoding the rest of the +in the message by @code{cons}ing it onto the result of decoding the rest of the message, starting at the root of the tree. Note the error check in the final -clause of @t{choose-branch}, which complains if the procedure finds +clause of @code{choose-branch}, which complains if the procedure finds something other than a zero or a one in the input data. @subsubheading Sets of weighted elements @@ -10942,7 +10942,7 @@ to repeatedly find the smallest item in a set, it is convenient to use an ordered representation for this kind of set. We will represent a set of leaves and trees as a list of elements, arranged in -increasing order of weight. The following @t{adjoin-set} procedure for +increasing order of weight. The following @code{adjoin-set} procedure for constructing sets is similar to the one described in @ref{Exercise 2.61}; however, items are compared by their weights, and the element being added to the set is never already in it. @@ -10960,7 +10960,7 @@ the set is never already in it. @noindent The following procedure takes a list of symbol-frequency pairs such as -@t{((A 4) (B 2) (C 1) (D 1))} and constructs an initial ordered set of +@code{((A 4) (B 2) (C 1) (D 1))} and constructs an initial ordered set of leaves, ready to be merged according to the Huffman algorithm: @lisp @@ -10992,11 +10992,11 @@ sample message: '(0 1 1 0 0 1 0 1 0 1 1 1 0)) @end lisp -Use the @t{decode} procedure to decode the message, and give the result. +Use the @code{decode} procedure to decode the message, and give the result. @end quotation @quotation -@strong{@anchor{Exercise 2.68}Exercise 2.68:} The @t{encode} procedure takes +@strong{@anchor{Exercise 2.68}Exercise 2.68:} The @code{encode} procedure takes as arguments a message and a tree and produces the list of bits that gives the encoded message. @@ -11010,9 +11010,9 @@ encoded message. (encode (cdr message) tree)))) @end lisp -@t{Encode-symbol} is a procedure, which you must write, that returns the +@code{Encode-symbol} is a procedure, which you must write, that returns the list of bits that encodes a given symbol according to a given tree. You should -design @t{encode-symbol} so that it signals an error if the symbol is not in +design @code{encode-symbol} so that it signals an error if the symbol is not in the tree at all. Test your procedure by encoding the result you obtained in @ref{Exercise 2.67} with the sample tree and seeing whether it is the same as the original sample message. @@ -11030,9 +11030,9 @@ algorithm. (make-leaf-set pairs))) @end lisp -@t{Make-leaf-set} is the procedure given above that transforms the list of -pairs into an ordered set of leaves. @t{Successive-merge} is the procedure -you must write, using @t{make-code-tree} to successively merge the +@code{Make-leaf-set} is the procedure given above that transforms the list of +pairs into an ordered set of leaves. @code{Successive-merge} is the procedure +you must write, using @code{make-code-tree} to successively merge the smallest-weight elements of the set until there is only one element left, which is the desired Huffman tree. (This procedure is slightly tricky, but not really complicated. If you find yourself designing a complex procedure, then @@ -11054,8 +11054,8 @@ GET 2 YIP 9 JOB 2 WAH 1 @end example -Use @t{generate-huffman-tree} (@ref{Exercise 2.69}) to generate a -corresponding Huffman tree, and use @t{encode} (@ref{Exercise 2.68}) to +Use @code{generate-huffman-tree} (@ref{Exercise 2.69}) to generate a +corresponding Huffman tree, and use @code{encode} (@ref{Exercise 2.68}) to encode the following message: @example @@ -11105,11 +11105,11 @@ program that uses rational numbers from the task of implementing rational numbers in terms of the computer language's primitive mechanisms for constructing compound data. The key idea was to erect an abstraction barrier -- in this case, the selectors and constructors for rational numbers -(@t{make-rat}, @t{numer}, @t{denom})---that isolates the way rational +(@code{make-rat}, @code{numer}, @code{denom})---that isolates the way rational numbers are used from their underlying representation in terms of list structure. A similar abstraction barrier isolates the details of the -procedures that perform rational arithmetic (@t{add-rat}, @t{sub-rat}, -@t{mul-rat}, and @t{div-rat}) from the ``higher-level'' procedures that +procedures that perform rational arithmetic (@code{add-rat}, @code{sub-rat}, +@code{mul-rat}, and @code{div-rat}) from the ``higher-level'' procedures that use rational numbers. The resulting program has the structure shown in @ref{Figure 2.1}. @@ -11156,8 +11156,8 @@ We begin with the simple complex-number example. We will see how type tags and data-directed style enable us to design separate rectangular and polar representations for complex numbers while maintaining the notion of an abstract ``complex-number'' data object. We will accomplish this by defining arithmetic -procedures for complex numbers (@t{add-@/complex}, @t{sub-complex}, -@t{mul-complex}, and @t{div-complex}) in terms of generic selectors that +procedures for complex numbers (@code{add-@/complex}, @code{sub-complex}, +@code{mul-complex}, and @code{div-complex}) in terms of generic selectors that access parts of a complex number independent of how the number is represented. The resulting complex-number system, as shown in @ref{Figure 2.19}, contains two different kinds of abstraction barriers. The ``horizontal'' abstraction @@ -11198,8 +11198,8 @@ and install alternative representations. @noindent In @ref{2.5} we will show how to use type tags and data-directed style -to develop a generic arithmetic package. This provides procedures (@t{add}, -@t{mul}, and so on) that can be used to manipulate all sorts of ``numbers'' +to develop a generic arithmetic package. This provides procedures (@code{add}, +@code{mul}, and so on) that can be used to manipulate all sorts of ``numbers'' and can be easily extended when a new kind of number is needed. In @ref{2.5.3}, we'll show how to use generic arithmetic in a system that performs symbolic algebra. @@ -11321,12 +11321,12 @@ specified by polar coordinates. To design such a system, we can follow the same data-abstraction strategy we followed in designing the rational-number package in @ref{2.1.1}. Assume that the operations on complex numbers are implemented in terms of four -selectors: @t{real-part}, @t{imag-part}, @t{magnitude}, and -@t{angle}. Also assume that we have two procedures for constructing complex -numbers: @t{make-from-real-imag} returns a complex number with specified -real and imaginary parts, and @t{make-from-mag-ang} returns a complex number +selectors: @code{real-part}, @code{imag-part}, @code{magnitude}, and +@code{angle}. Also assume that we have two procedures for constructing complex +numbers: @code{make-from-real-imag} returns a complex number with specified +real and imaginary parts, and @code{make-from-mag-ang} returns a complex number with specified magnitude and angle. These procedures have the property that, -for any complex number @t{z}, both +for any complex number @code{z}, both @lisp (make-from-real-imag (real-part z) @@ -11341,7 +11341,7 @@ and @end lisp @noindent -produce complex numbers that are equal to @t{z}. +produce complex numbers that are equal to @code{z}. Using these constructors and selectors, we can implement arithmetic on complex numbers using the ``abstract data'' specified by the constructors and @@ -11398,7 +11398,7 @@ y = r sin A A = arctan(y,x) @end ifinfo @tex $$ \eqalign{ - x = r \cos A, \qquad & r = \sqrt{x^2 + y^2}, \cr + x = r \cos A, \qquad & r = \sqrt{x^2 + y^2,} \cr y = r \sin A, \qquad & A = \arctan(y, x), \cr } $$ @end tex @@ -11406,7 +11406,7 @@ $$ \eqalign{ @noindent which relate the real and imaginary parts @math{(x, y)} to the magnitude and the angle @math{(r, A)}.@footnote{The arctangent function referred to here, -computed by Scheme's @t{atan} procedure, is defined so as to take two +computed by Scheme's @code{atan} procedure, is defined so as to take two arguments @math{y} and @math{x} and to return the angle whose tangent is @math{y \big/\! x}. The signs of the arguments determine the quadrant of the angle.} Ben's representation is therefore given by the following selectors and constructors: @@ -11448,8 +11448,8 @@ representation is: @noindent The discipline of data abstraction ensures that the same implementation of -@t{add-complex}, @t{sub-complex}, @t{mul-@/complex}, and -@t{div-complex} will work with either Ben's representation or Alyssa's +@code{add-complex}, @code{sub-complex}, @code{mul-@/complex}, and +@code{div-complex} will work with either Ben's representation or Alyssa's representation. @node 2.4.2, 2.4.3, 2.4.1, 2.4 @@ -11469,18 +11469,18 @@ have designed the selectors and constructors, and elect to use both Ben's representation @emph{and} Alyssa's representation. If both representations are included in a single system, however, we will need some way to distinguish data in polar form from data in rectangular form. Otherwise, if we were asked, for -instance, to find the @t{magnitude} of the pair (3, 4), we wouldn't know +instance, to find the @code{magnitude} of the pair (3, 4), we wouldn't know whether to answer 5 (interpreting the number in rectangular form) or 3 (interpreting the number in polar form). A straightforward way to accomplish this distinction is to include a @newterm{type tag}---the symbol -@t{rectangular} or @t{polar}---as part of each complex number. Then +@code{rectangular} or @code{polar}---as part of each complex number. Then when we need to manipulate a complex number we can use the tag to decide which selector to apply. In order to manipulate tagged data, we will assume that we have procedures -@t{type-tag} and @t{contents} that extract from a data object the tag and +@code{type-tag} and @code{contents} that extract from a data object the tag and the actual contents (the polar or rectangular coordinates, in the case of a -complex number). We will also postulate a procedure @t{attach-tag} that +complex number). We will also postulate a procedure @code{attach-tag} that takes a tag and contents and produces a tagged data object. A straightforward way to implement this is to use ordinary list structure: @@ -11500,8 +11500,8 @@ way to implement this is to use ordinary list structure: @end lisp @noindent -Using these procedures, we can define predicates @t{rectangular?} and -@t{polar?}, which recognize rectangular and polar numbers, respectively: +Using these procedures, we can define predicates @code{rectangular?} and +@code{polar?}, which recognize rectangular and polar numbers, respectively: @lisp (define (rectangular? z) @@ -11516,8 +11516,8 @@ different representations can coexist in the same system. Whenever Ben constructs a complex number, he tags it as rectangular. Whenever Alyssa constructs a complex number, she tags it as polar. In addition, Ben and Alyssa must make sure that the names of their procedures do not conflict. One way to -do this is for Ben to append the suffix @t{rectangular} to the name of each -of his representation procedures and for Alyssa to append @t{polar} to the +do this is for Ben to append the suffix @code{rectangular} to the name of each +of his representation procedures and for Alyssa to append @code{polar} to the names of hers. Here is Ben's revised rectangular representation from @ref{2.4.1}: @@ -11562,9 +11562,9 @@ and here is Alyssa's revised polar representation: @noindent Each generic selector is implemented as a procedure that checks the tag of its argument and calls the appropriate procedure for handling data of that type. -For example, to obtain the real part of a complex number, @t{real-part} -examines the tag to determine whether to use Ben's @t{real-part-rectangular} -or Alyssa's @t{real-part-polar}. In either case, we use @t{contents} to +For example, to obtain the real part of a complex number, @code{real-part} +examines the tag to determine whether to use Ben's @code{real-part-rectangular} +or Alyssa's @code{real-part-polar}. In either case, we use @code{contents} to extract the bare, untagged datum and send this to the rectangular or polar procedure as required: @@ -11602,10 +11602,10 @@ procedure as required: @noindent To implement the complex-number arithmetic operations, we can use the same -procedures @t{add-@/complex}, @t{sub-@/complex}, @t{mul-@/complex}, and -@t{div-@/complex} from @ref{2.4.1}, because the selectors they call +procedures @code{add-@/complex}, @code{sub-@/complex}, @code{mul-@/complex}, and +@code{div-@/complex} from @ref{2.4.1}, because the selectors they call are generic, and so will work with either representation. For example, the -procedure @t{add-@/complex} is still +procedure @code{add-@/complex} is still @lisp (define (add-complex z1 z2) @@ -11676,7 +11676,7 @@ that depends upon the particular type of data it is applied to. Notice the general mechanism for interfacing the separate representations: Within a given representation implementation (say, Alyssa's polar package) a complex number is an untyped pair (magnitude, angle). When a generic selector operates on a -number of @t{polar} type, it strips off the tag and passes the contents on +number of @code{polar} type, it strips off the tag and passes the contents on to Alyssa's code. Conversely, when Alyssa constructs a number for general use, she tags it with a type so that it can be appropriately recognized by the higher-level procedures. This discipline of stripping off and attaching tags @@ -11690,8 +11690,8 @@ The general strategy of checking the type of a datum and calling an appropriate procedure is called @newterm{dispatching on type}. This is a powerful strategy for obtaining modularity in system design. On the other hand, implementing the dispatch as in @ref{2.4.2} has two significant weaknesses. One -weakness is that the generic interface procedures (@t{real-part}, -@t{imag-part}, @t{magnitude}, and @t{angle}) must know about all the +weakness is that the generic interface procedures (@code{real-part}, +@code{imag-part}, @code{magnitude}, and @code{angle}) must know about all the different representations. For instance, suppose we wanted to incorporate a new representation for complex numbers into our complex-number system. We would need to identify this new representation with a type, and then add a @@ -11772,8 +11772,8 @@ argument. If we do this, then to add a new representation package to the system we need not change any existing procedures; we need only add new entries to the table. -To implement this plan, assume that we have two procedures, @t{put} and -@t{get}, for manipulating the operation-and-type table: +To implement this plan, assume that we have two procedures, @code{put} and +@code{get}, for manipulating the operation-and-type table: @endpage @itemize @bullet @@ -11785,12 +11785,12 @@ To implement this plan, assume that we have two procedures, @t{put} and @item @math{\hbox{\tt(get}\;\langle}@var{op}@math{\kern0.1em\rangle\;\langle}@var{type}@math{\kern0.08em\rangle\hbox{\tt)}} looks up the @math{\langle}@var{op}@math{\kern0.08em\rangle}, @math{\langle}@var{type}@math{\kern0.08em\rangle} entry in the table and -returns the item found there. If no item is found, @t{get} returns false. +returns the item found there. If no item is found, @code{get} returns false. @end itemize @noindent -For now, we can assume that @t{put} and @t{get} are included in our +For now, we can assume that @code{put} and @code{get} are included in our language. In @ref{Chapter 3} (@ref{3.3.3}) we will see how to implement these and other operations for manipulating tables. @@ -11838,10 +11838,10 @@ necessary in order to interface them to the rest of the system. Moreover, since these procedure definitions are internal to the installation procedure, Ben needn't worry about name conflicts with other procedures outside the rectangular package. To interface these to the rest of the system, Ben -installs his @t{real-part} procedure under the operation name -@t{real-part} and the type @t{(rectangular)}, and similarly for the other -selectors.@footnote{We use the list @t{(rectangular)} rather than the symbol -@t{rect-@/angular} to allow for the possibility of operations with multiple +installs his @code{real-part} procedure under the operation name +@code{real-part} and the type @code{(rectangular)}, and similarly for the other +selectors.@footnote{We use the list @code{(rectangular)} rather than the symbol +@code{rect-@/angular} to allow for the possibility of operations with multiple arguments, not all of the same type.} The interface also defines the constructors to be used by the external system.@footnote{The type the constructors are installed under needn't be a list because a constructor is @@ -11880,22 +11880,22 @@ Alyssa's polar package is analogous: @noindent Even though Ben and Alyssa both still use their original procedures defined -with the same names as each other's (e.g., @t{real-part}), these definitions +with the same names as each other's (e.g., @code{real-part}), these definitions are now internal to different procedures (see @ref{1.1.8}), so there is no name conflict. The complex-arithmetic selectors access the table by means of a general -``operation'' procedure called @t{apply-@/generic}, which applies a generic -operation to some arguments. @t{Apply-generic} looks in the table under the +``operation'' procedure called @code{apply-@/generic}, which applies a generic +operation to some arguments. @code{Apply-generic} looks in the table under the name of the operation and the types of the arguments and applies the resulting -procedure if one is present:@footnote{@t{Apply-generic} uses the dotted-tail +procedure if one is present:@footnote{@code{Apply-generic} uses the dotted-tail notation described in @ref{Exercise 2.20}, because different generic operations -may take different numbers of arguments. In @t{apply-generic}, @t{op} -has as its value the first argument to @t{apply-generic} and @t{args} has +may take different numbers of arguments. In @code{apply-generic}, @code{op} +has as its value the first argument to @code{apply-generic} and @code{args} has as its value a list of the remaining arguments. -@t{Apply-generic} also uses the primitive procedure @t{apply}, which -takes two arguments, a procedure and a list. @t{Apply} applies the +@code{Apply-generic} also uses the primitive procedure @code{apply}, which +takes two arguments, a procedure and a list. @code{Apply} applies the procedure, using the elements in the list as arguments. For example, @lisp @@ -11918,7 +11918,7 @@ returns 10.} @end lisp @noindent -Using @t{apply-generic}, we can define our generic selectors as follows: +Using @code{apply-generic}, we can define our generic selectors as follows: @lisp (define (real-part z) @@ -11982,8 +11982,8 @@ program that performs symbolic differentiation: @quotation We can regard this program as performing a dispatch on the type of the expression to be differentiated. In this situation the ``type tag'' of the -datum is the algebraic operator symbol (such as @t{+}) and the operation -being performed is @t{deriv}. We can transform this program into +datum is the algebraic operator symbol (such as @code{+}) and the operation +being performed is @code{deriv}. We can transform this program into data-directed style by rewriting the basic derivative procedure as @end quotation @@ -12006,7 +12006,7 @@ data-directed style by rewriting the basic derivative procedure as @item Explain what was done above. Why can't we assimilate the predicates -@t{number?} and @t{variable?} into the data-directed dispatch? +@code{number?} and @code{variable?} into the data-directed dispatch? @item Write the procedures for derivatives of sums and products, and the auxiliary @@ -12020,7 +12020,7 @@ system. @item In this simple algebraic manipulator the type of an expression is the algebraic operator that binds it together. Suppose, however, we indexed the procedures -in the opposite way, so that the dispatch line in @t{deriv} looked like +in the opposite way, so that the dispatch line in @code{deriv} looked like @lisp ((get (operator exp) 'deriv) @@ -12052,13 +12052,13 @@ an example, suppose that each division's personnel records consist of a single file, which contains a set of records keyed on employees' names. The structure of the set varies from division to division. Furthermore, each employee's record is itself a set (structured differently from division to division) that -contains information keyed under identifiers such as @t{address} and -@t{salary}. In particular: +contains information keyed under identifiers such as @code{address} and +@code{salary}. In particular: @enumerate a @item -Implement for headquarters a @t{get-record} procedure that retrieves a +Implement for headquarters a @code{get-record} procedure that retrieves a specified employee's record from a specified personnel file. The procedure should be applicable to any division's file. Explain how the individual divisions' files should be structured. In particular, what type information @@ -12066,13 +12066,13 @@ must be supplied? @sp 1 @item -Implement for headquarters a @t{get-salary} procedure that returns the +Implement for headquarters a @code{get-salary} procedure that returns the salary information from a given employee's record from any division's personnel file. How should the record be structured in order to make this operation work? @item -Implement for headquarters a @t{find-@/employee-@/record} procedure. This +Implement for headquarters a @code{find-@/employee-@/record} procedure. This should search all the divisions' files for the record of a given employee and return the record. Assume that this procedure takes as arguments an employee's name and a list of all the divisions' files. @@ -12100,7 +12100,7 @@ to work with ``intelligent data objects'' that dispatch on operation names. We can do this by arranging things so that a data object, such as a rectangular number, is represented as a procedure that takes as input the required operation name and performs the operation indicated. In such a discipline, -@t{make-from-real-imag} could be written as +@code{make-from-real-imag} could be written as @lisp (define (make-from-real-imag x y) @@ -12117,7 +12117,7 @@ operation name and performs the operation indicated. In such a discipline, @end lisp @noindent -The corresponding @t{apply-generic} procedure, which applies a generic +The corresponding @code{apply-generic} procedure, which applies a generic operation to an argument, now simply feeds the operation's name to the data object and lets the object do the work:@footnote{One limitation of this organization is it permits only generic procedures of one argument.} @@ -12127,15 +12127,15 @@ organization is it permits only generic procedures of one argument.} @end lisp @noindent -Note that the value returned by @t{make-from-real-imag} is a procedure---the -internal @t{dispatch} procedure. This is the procedure that is invoked when -@t{apply-generic} requests an operation to be performed. +Note that the value returned by @code{make-from-real-imag} is a procedure---the +internal @code{dispatch} procedure. This is the procedure that is invoked when +@code{apply-generic} requests an operation to be performed. This style of programming is called @newterm{message passing}. The name comes from the image that a data object is an entity that receives the requested operation name as a ``message.'' We have already seen an example of message -passing in @ref{2.1.3}, where we saw how @t{cons}, @t{car}, and -@t{cdr} could be defined with no data objects but only procedures. Here we +passing in @ref{2.1.3}, where we saw how @code{cons}, @code{car}, and +@code{cdr} could be defined with no data objects but only procedures. Here we see that message passing is not a mathematical trick but a useful technique for organizing systems with generic operations. In the remainder of this chapter we will continue to use data-directed programming, rather than message passing, @@ -12145,8 +12145,8 @@ simulation programs. @quotation @strong{@anchor{Exercise 2.75}Exercise 2.75:} Implement the constructor -@t{make-@/from-@/mag-@/ang} in mes@-sage-pass@-ing style. This procedure should be -analogous to the @t{make-@/from-@/real-@/imag} procedure given above. +@code{make-@/from-@/mag-@/ang} in mes@-sage-pass@-ing style. This procedure should be +analogous to the @code{make-@/from-@/real-@/imag} procedure given above. @end quotation @quotation @@ -12170,21 +12170,21 @@ generic interface procedures. Now we will see how to use this same idea not only to define operations that are generic over different representations but also to define operations that are generic over different kinds of arguments. We have already seen several different packages of arithmetic operations: the -primitive arithmetic (@t{+}, @t{-}, @t{*}, @t{/}) built into our -language, the rational-number arithmetic (@t{add-rat}, @t{sub-rat}, -@t{mul-rat}, @t{div-rat}) of @ref{2.1.1}, and the complex-number +primitive arithmetic (@code{+}, @code{-}, @code{*}, @code{/}) built into our +language, the rational-number arithmetic (@code{add-rat}, @code{sub-rat}, +@code{mul-rat}, @code{div-rat}) of @ref{2.1.1}, and the complex-number arithmetic that we implemented in @ref{2.4.3}. We will now use data-directed techniques to construct a package of arithmetic operations that incorporates all the arithmetic packages we have already constructed. @ref{Figure 2.23} shows the structure of the system we shall build. Notice the abstraction barriers. From the perspective of someone using ``numb@-ers,'' there -is a single procedure @t{add} that operates on whatever numb@-ers are -supplied. @t{Add} is part of a generic interface that allows the separate +is a single procedure @code{add} that operates on whatever numb@-ers are +supplied. @code{Add} is part of a generic interface that allows the separate or@-di@-na@-ry-arithmetic, rational-arithmetic, and complex-arithmetic pack@-ag@-es to be accessed uniformly by programs that use numbers. Any individual arithmetic package (such as the complex package) may itself be accessed through generic -procedures (such as @t{add-complex}) that combine packages designed for +procedures (such as @code{add-complex}) that combine packages designed for different representations (such as rectangular and polar). Moreover, the structure of the system is additive, so that one can design the individual arithmetic packages separately and combine them to produce a generic arithmetic @@ -12239,10 +12239,10 @@ system. The task of designing generic arithmetic operations is analogous to that of designing the generic complex-number operations. We would like, for instance, -to have a generic addition procedure @t{add} that acts like ordinary -primitive addition @t{+} on ordinary numbers, like @t{add-rat} on -rational numbers, and like @t{add-complex} on complex numbers. We can -implement @t{add}, and the other generic arithmetic operations, by following +to have a generic addition procedure @code{add} that acts like ordinary +primitive addition @code{+} on ordinary numbers, like @code{add-rat} on +rational numbers, and like @code{add-complex} on complex numbers. We can +implement @code{add}, and the other generic arithmetic operations, by following the same strategy we used in @ref{2.4.3} to implement the generic selectors for complex numbers. We will attach a type tag to each kind of number and cause the generic procedure to dispatch to an appropriate package @@ -12260,11 +12260,11 @@ The generic arithmetic procedures are defined as follows: @noindent We begin by installing a package for handling @newterm{ordinary} numbers, that is, the primitive numbers of our language. We will tag these with the symbol -@t{scheme-number}. The arithmetic operations in this package are the +@code{scheme-number}. The arithmetic operations in this package are the primitive arithmetic procedures (so there is no need to define extra procedures to handle the untagged numbers). Since these operations each take two arguments, they are installed in the table keyed by the list -@t{(scheme-number scheme-number)}: +@code{(scheme-number scheme-number)}: @lisp (define (install-scheme-number-package) @@ -12340,11 +12340,11 @@ procedures in the package: @noindent We can install a similar package to handle complex numbers, using the tag -@t{complex}. In creating the package, we extract from the table the -operations @t{make-@/from-@/real-@/imag} and @t{make-@/from-@/mag-@/ang} that were +@code{complex}. In creating the package, we extract from the table the +operations @code{make-@/from-@/real-@/imag} and @code{make-@/from-@/mag-@/ang} that were defined by the rectangular and polar packages. Additivity permits us to use, -as the internal operations, the same @t{add-complex}, @t{sub-complex}, -@t{mul-@/complex}, and @t{div-@/complex} procedures from @ref{2.4.1}. +as the internal operations, the same @code{add-complex}, @code{sub-complex}, +@code{mul-@/complex}, and @code{div-@/complex} procedures from @ref{2.4.1}. @lisp (define (install-complex-package) @@ -12417,13 +12417,13 @@ outside world. @noindent What we have here is a two-level tag system. A typical complex number, such as @math{3 + 4i} in rectangular form, would be represented as shown in @ref{Figure 2.24}. -The outer tag (@t{complex}) is used to direct the number to the +The outer tag (@code{complex}) is used to direct the number to the complex package. Once within the complex package, the next tag -(@t{rectangular}) is used to direct the number to the rectangular package. +(@code{rectangular}) is used to direct the number to the rectangular package. In a large and complicated system there might be many levels, each interfaced with the next by means of generic operations. As a data object is passed ``downward,'' the outer tag that is used to direct it to the appropriate -package is stripped off (by applying @t{contents}) and the next level of tag +package is stripped off (by applying @code{contents}) and the next level of tag (if any) becomes visible to be used for further dispatching. @float @@ -12455,22 +12455,22 @@ package is stripped off (by applying @t{contents}) and the next level of tag @end float @noindent -In the above packages, we used @t{add-rat}, @t{add-@/complex}, and the +In the above packages, we used @code{add-rat}, @code{add-@/complex}, and the other arithmetic procedures exactly as originally written. Once these definitions are internal to different installation procedures, however, they no longer need names that are distinct from each other: we could simply name them -@t{add}, @t{sub}, @t{mul}, and @t{div} in both packages. +@code{add}, @code{sub}, @code{mul}, and @code{div} in both packages. @quotation @strong{@anchor{Exercise 2.77}Exercise 2.77:} Louis Reasoner tries to evaluate -the expression @t{(magnitude z)} where @t{z} is the object shown in +the expression @code{(magnitude z)} where @code{z} is the object shown in @ref{Figure 2.24}. To his surprise, instead of the answer 5 he gets an error -message from @t{apply-@/generic}, saying there is no method for the operation -@t{magnitude} on the types @t{(complex)}. He shows this interaction to +message from @code{apply-@/generic}, saying there is no method for the operation +@code{magnitude} on the types @code{(complex)}. He shows this interaction to Alyssa P. Hacker, who says ``The problem is that the complex-number selectors -were never defined for @t{complex} numbers, just for @t{polar} and -@t{rectangular} numbers. All you have to do to make this work is add the -following to the @t{complex} package:'' +were never defined for @code{complex} numbers, just for @code{polar} and +@code{rectangular} numbers. All you have to do to make this work is add the +following to the @code{complex} package:'' @lisp (put 'real-part '(complex) real-part) @@ -12480,38 +12480,38 @@ following to the @t{complex} package:'' @end lisp Describe in detail why this works. As an example, trace through all the -procedures called in evaluating the expression @t{(magnitude z)} where -@t{z} is the object shown in @ref{Figure 2.24}. In particular, how many -times is @t{apply-generic} invoked? What procedure is dispatched to in each +procedures called in evaluating the expression @code{(magnitude z)} where +@code{z} is the object shown in @ref{Figure 2.24}. In particular, how many +times is @code{apply-generic} invoked? What procedure is dispatched to in each case? @end quotation @quotation @strong{@anchor{Exercise 2.78}Exercise 2.78:} The internal procedures in the -@t{scheme-@/number} package are essentially nothing more than calls to the -primitive procedures @t{+}, @t{-}, etc. It was not possible to use the +@code{scheme-@/number} package are essentially nothing more than calls to the +primitive procedures @code{+}, @code{-}, etc. It was not possible to use the primitives of the language directly because our type-tag system requires that each data object have a type attached to it. In fact, however, all Lisp implementations do have a type system, which they use internally. Primitive -predicates such as @t{symbol?} and @t{number?} determine whether data -objects have particular types. Modify the definitions of @t{type-@/tag}, -@t{contents}, and @t{attach-@/tag} from @ref{2.4.2} so that our +predicates such as @code{symbol?} and @code{number?} determine whether data +objects have particular types. Modify the definitions of @code{type-@/tag}, +@code{contents}, and @code{attach-@/tag} from @ref{2.4.2} so that our generic system takes advantage of Scheme's internal type system. That is to say, the system should work as before except that ordinary numbers should be -represented simply as Scheme numbers rather than as pairs whose @t{car} is -the symbol @t{scheme-@/number}. +represented simply as Scheme numbers rather than as pairs whose @code{car} is +the symbol @code{scheme-@/number}. @end quotation @quotation @strong{@anchor{Exercise 2.79}Exercise 2.79:} Define a generic equality -predicate @t{equ?} that tests the equality of two numbers, and install it in +predicate @code{equ?} that tests the equality of two numbers, and install it in the generic arithmetic package. This operation should work for ordinary numbers, rational numbers, and complex numbers. @end quotation @quotation @strong{@anchor{Exercise 2.80}Exercise 2.80:} Define a generic predicate -@t{=zero?} that tests if its argument is zero, and install it in the generic +@code{=zero?} that tests if its argument is zero, and install it in the generic arithmetic package. This operation should work for ordinary numbers, rational numbers, and complex numbers. @end quotation @@ -12536,9 +12536,9 @@ One way to handle cross-type operations is to design a different procedure for each possible combination of types for which the operation is valid. For example, we could extend the complex-number package so that it provides a procedure for adding complex numbers to ordinary numbers and installs this in -the table using the tag @t{(complex scheme-number)}:@footnote{We also have +the table using the tag @code{(complex scheme-number)}:@footnote{We also have to supply an almost identical procedure to handle the types -@t{(scheme-number complex)}.} +@code{(scheme-number complex)}.} @lisp (define (add-complex-to-schemenum z x) @@ -12606,16 +12606,16 @@ the names of the two types: @end lisp @noindent -(We assume that there are @t{put-coercion} and @t{get-@/coercion} +(We assume that there are @code{put-coercion} and @code{get-@/coercion} procedures available for manipulating this table.) Generally some of the slots in the table will be empty, because it is not generally possible to coerce an arbitrary data object of each type into all other types. For example, there is no way to coerce an arbitrary complex number to an ordinary number, so there -will be no general @t{complex->@/scheme-@/number} procedure included in the +will be no general @code{complex->@/scheme-@/number} procedure included in the table. Once the coercion table has been set up, we can handle coercion in a uniform -manner by modifying the @t{apply-generic} procedure of @ref{2.4.3}. +manner by modifying the @code{apply-generic} procedure of @ref{2.4.3}. When asked to apply an operation, we first check whether the operation is defined for the arguments' types, just as before. If so, we dispatch to the procedure found in the operation-and-type table. Otherwise, we try coercion. @@ -12743,14 +12743,14 @@ adding a new type to the hierarchy, for we need only specify how the new type is embedded in the next supertype above it and how it is the supertype of the type below it. For example, if we want to add an integer to a complex number, we need not explicitly define a special coercion procedure -@t{integer->complex}. Instead, we define how an integer can be transformed +@code{integer->complex}. Instead, we define how an integer can be transformed into a rational number, how a rational number is transformed into a real number, and how a real number is transformed into a complex number. We then allow the system to transform the integer into a complex number through these steps and then add the two complex numbers. -We can redesign our @t{apply-generic} procedure in the following way: For -each type, we need to supply a @t{raise} procedure, which ``raises'' objects +We can redesign our @code{apply-generic} procedure in the following way: For +each type, we need to supply a @code{raise} procedure, which ``raises'' objects of that type one level in the tower. Then when the system is required to operate on objects of different types it can successively raise the lower types until all the objects are at the same level in the tower. (@ref{Exercise 2.83} @@ -12759,10 +12759,10 @@ and @ref{Exercise 2.84} concern the details of implementing such a strategy.) Another advantage of a tower is that we can easily implement the notion that every type ``inherits'' all operations defined on a supertype. For instance, if we do not supply a special procedure for finding the real part of an -integer, we should nevertheless expect that @t{real-part} will be defined +integer, we should nevertheless expect that @code{real-part} will be defined for integers by virtue of the fact that integers are a subtype of complex numbers. In a tower, we can arrange for this to happen in a uniform way by -modifying @t{apply-generic}. If the required operation is not directly +modifying @code{apply-generic}. If the required operation is not directly defined for the type of the object given, we raise the object to its supertype and try again. We thus crawl up the tower, transforming our argument as we go, until we either find a level at which the desired operation can be performed or @@ -12828,7 +12828,7 @@ triangle. This multiple-supertypes issue is particularly thorny, since it means that there is no unique way to ``raise'' a type in the hierarchy. Finding the ``correct'' supertype in which to apply an operation to an object may involve considerable searching through the entire type network on the part -of a procedure such as @t{apply-generic}. Since there generally are +of a procedure such as @code{apply-generic}. Since there generally are multiple subtypes for a type, there is a similar problem in coercing a value ``down'' the type hierarchy. Dealing with large numbers of interrelated types while still preserving modularity in the design of large systems is very @@ -12853,11 +12853,11 @@ work in knowledge representation and automated reasoning.} @quotation @strong{@anchor{Exercise 2.81}Exercise 2.81:} Louis Reasoner has noticed that -@t{apply-generic} may try to coerce the arguments to each other's type even +@code{apply-generic} may try to coerce the arguments to each other's type even if they already have the same type. Therefore, he reasons, we need to put procedures in the coercion table to @newterm{coerce} arguments of each type to their own type. For example, in addition to the -@t{scheme-number->complex} coercion shown above, he would do: +@code{scheme-number->complex} coercion shown above, he would do: @end quotation @lisp @@ -12875,8 +12875,8 @@ their own type. For example, in addition to the @item With Louis's coercion procedures installed, what happens if -@t{apply-@/generic} is called with two arguments of type @t{scheme-number} -or two arguments of type @t{complex} for an operation that is not found in +@code{apply-@/generic} is called with two arguments of type @code{scheme-number} +or two arguments of type @code{complex} for an operation that is not found in the table for those types? For example, assume that we've defined a generic exponentiation operation: @@ -12895,18 +12895,18 @@ package but not in any other package: '(scheme-number scheme-number) (lambda (x y) (tag (expt x y)))) - @r{; using primitive @t{expt}} + @r{; using primitive @code{expt}} @end lisp @noindent -What happens if we call @t{exp} with two complex numbers as arguments? +What happens if we call @code{exp} with two complex numbers as arguments? @item Is Louis correct that something had to be done about coercion with arguments of -the same type, or does @t{apply-generic} work correctly as is? +the same type, or does @code{apply-generic} work correctly as is? @item -Modify @t{apply-generic} so that it doesn't try coercion if the two +Modify @code{apply-generic} so that it doesn't try coercion if the two arguments have the same type. @end enumerate @@ -12914,7 +12914,7 @@ arguments have the same type. @quotation @strong{@anchor{Exercise 2.82}Exercise 2.82:} Show how to generalize -@t{apply-@/generic} to handle coercion in the general case of multiple +@code{apply-@/generic} to handle coercion in the general case of multiple arguments. One strategy is to attempt to coerce all the arguments to the type of the first argument, then to the type of the second argument, and so on. Give an example of a situation where this strategy (and likewise the @@ -12928,13 +12928,13 @@ table that will not be tried.) generic arithmetic system for dealing with the tower of types shown in @ref{Figure 2.25}: integer, rational, real, complex. For each type (except complex), design a procedure that raises objects of that type one level in the -tower. Show how to install a generic @t{raise} operation that will work for +tower. Show how to install a generic @code{raise} operation that will work for each type (except complex). @end quotation @quotation -@strong{@anchor{Exercise 2.84}Exercise 2.84:} Using the @t{raise} operation -of @ref{Exercise 2.83}, modify the @t{apply-generic} procedure so that it +@strong{@anchor{Exercise 2.84}Exercise 2.84:} Using the @code{raise} operation +of @ref{Exercise 2.83}, modify the @code{apply-generic} procedure so that it coerces its arguments to have the same type by the method of successive raising, as discussed in this section. You will need to devise a way to test which of two types is higher in the tower. Do this in a manner that is @@ -12945,24 +12945,24 @@ adding new levels to the tower. @quotation @strong{@anchor{Exercise 2.85}Exercise 2.85:} This section mentioned a method for ``simplifying'' a data object by lowering it in the tower of types as far -as possible. Design a procedure @t{drop} that accomplishes this for the +as possible. Design a procedure @code{drop} that accomplishes this for the tower described in @ref{Exercise 2.83}. The key is to decide, in some general way, whether an object can be lowered. For example, the complex number -@math{1.5 + 0i} can be lowered as far as @t{real}, the complex number @math{1 + 0i} can -be lowered as far as @t{integer}, and the complex number @math{2 + 3i} cannot +@math{1.5 + 0i} can be lowered as far as @code{real}, the complex number @math{1 + 0i} can +be lowered as far as @code{integer}, and the complex number @math{2 + 3i} cannot be lowered at all. Here is a plan for determining whether an object can be -lowered: Begin by defining a generic operation @t{project} that ``pushes'' +lowered: Begin by defining a generic operation @code{project} that ``pushes'' an object down in the tower. For example, projecting a complex number would involve throwing away the imaginary part. Then a number can be dropped if, -when we @t{project} it and @t{raise} the result back to the type we +when we @code{project} it and @code{raise} the result back to the type we started with, we end up with something equal to what we started with. Show how -to implement this idea in detail, by writing a @t{drop} procedure that drops +to implement this idea in detail, by writing a @code{drop} procedure that drops an object as far as possible. You will need to design the various projection operations@footnote{A real number can be projected to an integer using the -@t{round} primitive, which returns the closest integer to its argument.} and -install @t{project} as a generic operation in the system. You will also +@code{round} primitive, which returns the closest integer to its argument.} and +install @code{project} as a generic operation in the system. You will also need to make use of a generic equality predicate, such as described in -@ref{Exercise 2.79}. Finally, use @t{drop} to rewrite @t{apply-generic} +@ref{Exercise 2.79}. Finally, use @code{drop} to rewrite @code{apply-generic} from @ref{Exercise 2.84} so that it ``simplifies'' its answers. @end quotation @@ -12971,8 +12971,8 @@ from @ref{Exercise 2.84} so that it ``simplifies'' its answers. numbers whose real parts, imaginary parts, magnitudes, and angles can be either ordinary numbers, rational numbers, or other numbers we might wish to add to the system. Describe and implement the changes to the system needed to -accommodate this. You will have to define operations such as @t{sine} and -@t{cosine} that are generic over ordinary numbers and rational numbers. +accommodate this. You will have to define operations such as @code{sine} and +@code{cosine} that are generic over ordinary numbers and rational numbers. @end quotation @node 2.5.3, , 2.5.2, 2.5 @@ -13080,10 +13080,10 @@ indeterminate. We will approach the design of our system by following the familiar discipline of data abstraction. We will represent polynomials using a data structure called a @newterm{poly}, which consists of a variable and a collection of -terms. We assume that we have selectors @t{variable} and @t{term-list} -that extract those parts from a poly and a constructor @t{make-poly} that +terms. We assume that we have selectors @code{variable} and @code{term-list} +that extract those parts from a poly and a constructor @code{make-poly} that assembles a poly from a given variable and a term list. A variable will be -just a symbol, so we can use the @t{same-variable?} procedure of +just a symbol, so we can use the @code{same-variable?} procedure of @ref{2.3.2} to compare variables. The following procedures define addition and multiplication of polys: @@ -13112,7 +13112,7 @@ multiplication of polys: @noindent To incorporate polynomials into our generic arithmetic system, we need to -supply them with type tags. We'll use the tag @t{polynomial}, and install +supply them with type tags. We'll use the tag @code{polynomial}, and install appropriate operations on tagged polynomials in the operation table. We'll embed all our code in an installation procedure for the polynomial package, similar to the ones in @ref{2.5.1}: @@ -13125,19 +13125,19 @@ similar to the ones in @ref{2.5.1}: (cons variable term-list)) (define (variable p) (car p)) (define (term-list p) (cdr p)) - @math{\langle}@emph{procedures @t{same-variable?} - and @t{variable?} from section 2.3.2}@math{\rangle} + @math{\langle}@emph{procedures @code{same-variable?} + and @code{variable?} from section 2.3.2}@math{\rangle} @r{;; representation of terms and term lists} - @math{\langle}@emph{procedures @t{adjoin-term} @dots{} @t{coeff} + @math{\langle}@emph{procedures @code{adjoin-term} @dots{} @code{coeff} from text below}@math{\rangle} @c @r{;; continued on next page} @c (define (add-poly p1 p2) @dots{}) - @math{\langle}@emph{procedures used by @t{add-poly}}@math{\rangle} + @math{\langle}@emph{procedures used by @code{add-poly}}@math{\rangle} (define (mul-poly p1 p2) @dots{}) - @math{\langle}@emph{procedures used by @t{mul-poly}}@math{\rangle} + @math{\langle}@emph{procedures used by @code{mul-poly}}@math{\rangle} @r{;; interface to rest of the system} (define (tag p) (attach-tag 'polynomial p)) @@ -13162,24 +13162,24 @@ order in the other addend are simply accumulated into the sum polynomial being constructed. In order to manipulate term lists, we will assume that we have a constructor -@t{the-empty-termlist} that returns an empty term list and a constructor -@t{adjoin-term} that adjoins a new term to a term list. We will also assume -that we have a predicate @t{empty-termlist?} that tells if a given term list -is empty, a selector @t{first-term} that extracts the highest-order term -from a term list, and a selector @t{rest-terms} that returns all but the +@code{the-empty-termlist} that returns an empty term list and a constructor +@code{adjoin-term} that adjoins a new term to a term list. We will also assume +that we have a predicate @code{empty-termlist?} that tells if a given term list +is empty, a selector @code{first-term} that extracts the highest-order term +from a term list, and a selector @code{rest-terms} that returns all but the highest-order term. To manipulate terms, we will suppose that we have a -constructor @t{make-term} that constructs a term with given order and -coefficient, and selectors @t{order} and @t{coeff} that return, +constructor @code{make-term} that constructs a term with given order and +coefficient, and selectors @code{order} and @code{coeff} that return, respectively, the order and the coefficient of the term. These operations allow us to consider both terms and term lists as data abstractions, whose concrete representations we can worry about separately. Here is the procedure that constructs the term list for the sum of two polynomials:@footnote{This operation is very much like the ordered -@t{union-set} operation we developed in @ref{Exercise 2.62}. In +@code{union-set} operation we developed in @ref{Exercise 2.62}. In fact, if we think of the terms of the polynomial as a set ordered according to the power of the indeterminate, then the program that produces the term list -for a sum is almost identical to @t{union-set}.} +for a sum is almost identical to @code{union-set}.} @lisp (define (add-terms L1 L2) @@ -13212,11 +13212,11 @@ for a sum is almost identical to @t{union-set}.} @noindent The most important point to note here is that we used the generic addition -procedure @t{add} to add together the coefficients of the terms being +procedure @code{add} to add together the coefficients of the terms being combined. This has powerful consequences, as we will see below. In order to multiply two term lists, we multiply each term of the first list by -all the terms of the other list, repeatedly using @t{mul-term-by-all-terms}, +all the terms of the other list, repeatedly using @code{mul-term-by-all-terms}, which multiplies a given term by all terms in a given term list. The resulting term lists (one for each term of the first list) are accumulated into a sum. Multiplying two terms forms a term whose order is the sum of the orders of the @@ -13246,8 +13246,8 @@ factors: @noindent This is really all there is to polynomial addition and multiplication. Notice -that, since we operate on terms using the generic procedures @t{add} and -@t{mul}, our polynomial package is automatically able to handle any type of +that, since we operate on terms using the generic procedures @code{add} and +@code{mul}, our polynomial package is automatically able to handle any type of coefficient that is known about by the generic arithmetic package. If we include a coercion mechanism such as one of those discussed in @ref{2.5.2}, then we also are automatically able to handle operations on @@ -13265,8 +13265,8 @@ polynomials of different coefficient types, such as $$ [3x^2 + (2 + 3i)x + 7] \cdot \! \left[ x^4 + {2\over3} x^2 + (5 + 3i) \right]\!\!. $$ @end tex Because we installed the polynomial addition and multiplication procedures -@t{add-poly} and @t{mul-poly} in the generic arithmetic system as the -@t{add} and @t{mul} operations for type @t{polynomial}, our system is +@code{add-poly} and @code{mul-poly} in the generic arithmetic system as the +@code{add} and @code{mul} operations for type @code{polynomial}, our system is also automatically able to handle polynomial operations such as @ifinfo @@ -13279,11 +13279,11 @@ also automatically able to handle polynomial operations such as $$ \Big[(y + 1)x^2 + (y^2 + 1)x + (y - 1)\Big] \cdot \Big[(y - 2)x + (y^3 + 7)\Big]. $$ @end tex The reason is that when the system tries to combine coefficients, it will -dispatch through @t{add} and @t{mul}. Since the coefficients are -themselves polynomials (in @math{y}), these will be combined using @t{add-poly} -and @t{mul-poly}. The result is a kind of ``data-directed recursion'' in -which, for example, a call to @t{mul-poly} will result in recursive calls to -@t{mul-poly} in order to multiply the coefficients. If the coefficients of +dispatch through @code{add} and @code{mul}. Since the coefficients are +themselves polynomials (in @math{y}), these will be combined using @code{add-poly} +and @code{mul-poly}. The result is a kind of ``data-directed recursion'' in +which, for example, a call to @code{mul-poly} will result in recursive calls to +@code{mul-poly} in order to multiply the coefficients. If the coefficients of the coefficients were themselves polynomials (as might be used to represent polynomials in three variables), the data direction would ensure that the system would follow through another level of recursive calls, and so on through @@ -13311,7 +13311,7 @@ Finally, we must confront the job of implementing a good representation for term lists. A term list is, in effect, a set of coefficients keyed by the order of the term. Hence, any of the methods for representing sets, as discussed in @ref{2.3.3}, can be applied to this task. On the other -hand, our procedures @t{add-terms} and @t{mul-terms} always access term +hand, our procedures @code{add-terms} and @code{mul-terms} always access term lists sequentially from highest to lowest order. Thus, we will use some kind of ordered list representation. @@ -13347,30 +13347,30 @@ is sparse. The term lists of dense polynomials are most efficiently represented as lists of the coefficients. For example, @math{A} above would be nicely represented as -@t{(1 2 0 3 -2 -5)}. The order of a term in this representation is the +@code{(1 2 0 3 -2 -5)}. The order of a term in this representation is the length of the sublist beginning with that term's coefficient, decremented by 1.@footnote{In these polynomial examples, we assume that we have implemented the generic arithmetic system using the type mechanism suggested in @ref{Exercise 2.78}. Thus, coefficients that are ordinary numbers will be -represented as the numbers themselves rather than as pairs whose @t{car} is -the symbol @t{scheme-number}.} This would be a terrible representation for +represented as the numbers themselves rather than as pairs whose @code{car} is +the symbol @code{scheme-number}.} This would be a terrible representation for a sparse polynomial such as @math{B}: There would be a giant list of zeros punctuated by a few lonely nonzero terms. A more reasonable representation of the term list of a sparse polynomial is as a list of the nonzero terms, where each term is a list containing the order of the term and the coefficient for that order. In such a scheme, polynomial @math{B} is efficiently represented as -@t{((100 1) (2 2) (0 1))}. As most polynomial manipulations are performed +@code{((100 1) (2 2) (0 1))}. As most polynomial manipulations are performed on sparse polynomials, we will use this method. We will assume that term lists are represented as lists of terms, arranged from highest-order to lowest-order term. Once we have made this decision, implementing the selectors and constructors for terms and term lists is straightforward:@footnote{Although we are assuming that term lists are ordered, we have implemented -@t{adjoin-term} to simply @t{cons} the new term onto the existing term +@code{adjoin-term} to simply @code{cons} the new term onto the existing term list. We can get away with this so long as we guarantee that the procedures -(such as @t{add-terms}) that use @t{adjoin-term} always call it with a +(such as @code{add-terms}) that use @code{adjoin-term} always call it with a higher-order term than appears in the list. If we did not want to make such a -guarantee, we could have implemented @t{adjoin-term} to be similar to the -@t{adjoin-set} constructor for the ordered-list representation of sets +guarantee, we could have implemented @code{adjoin-term} to be similar to the +@code{adjoin-set} constructor for the ordered-list representation of sets (@ref{Exercise 2.61}).} @lisp @@ -13390,7 +13390,7 @@ guarantee, we could have implemented @t{adjoin-term} to be similar to the @end lisp @noindent -where @t{=zero?} is as defined in @ref{Exercise 2.80}. (See also +where @code{=zero?} is as defined in @ref{Exercise 2.80}. (See also @ref{Exercise 2.87} below.) Users of the polynomial package will create (tagged) polynomials by means of @@ -13402,9 +13402,9 @@ the procedure: @end lisp @quotation -@strong{@anchor{Exercise 2.87}Exercise 2.87:} Install @t{=zero?} for +@strong{@anchor{Exercise 2.87}Exercise 2.87:} Install @code{=zero?} for polynomials in the generic arithmetic package. This will allow -@t{adjoin-@/term} to work for polynomials with coefficients that are +@code{adjoin-@/term} to work for polynomials with coefficients that are themselves polynomials. @end quotation @@ -13456,18 +13456,18 @@ divisor exceeds the order of the dividend and declare the dividend to be the remainder. Also, if the dividend ever becomes zero, return zero as both quotient and remainder. -We can design a @t{div-poly} procedure on the model of @t{add-poly} and -@t{mul-poly}. The procedure checks to see if the two polys have the same -variable. If so, @t{div-poly} strips off the variable and passes the -problem to @t{div-terms}, which performs the division operation on term -lists. @t{Div-poly} finally reattaches the variable to the result supplied -by @t{div-terms}. It is convenient to design @t{div-terms} to compute -both the quotient and the remainder of a division. @t{Div-terms} can take +We can design a @code{div-poly} procedure on the model of @code{add-poly} and +@code{mul-poly}. The procedure checks to see if the two polys have the same +variable. If so, @code{div-poly} strips off the variable and passes the +problem to @code{div-terms}, which performs the division operation on term +lists. @code{Div-poly} finally reattaches the variable to the result supplied +by @code{div-terms}. It is convenient to design @code{div-terms} to compute +both the quotient and the remainder of a division. @code{Div-terms} can take two term lists as arguments and return a list of the quotient term list and the remainder term list. -Complete the following definition of @t{div-terms} by filling in the missing -expressions. Use this to implement @t{div-poly}, which takes two polys as +Complete the following definition of @code{div-terms} by filling in the missing +expressions. Use this to implement @code{div-poly}, which takes two polys as arguments and returns a list of the quotient and remainder polys. @end quotation @@ -13577,9 +13577,9 @@ fractions to lowest terms. @quotation @strong{@anchor{Exercise 2.93}Exercise 2.93:} Modify the rational-arithmetic -package to use generic operations, but change @t{make-rat} so that it does +package to use generic operations, but change @code{make-rat} so that it does not attempt to reduce fractions to lowest terms. Test your system by calling -@t{make-rational} on two polynomials to produce a rational function +@code{make-rational} on two polynomials to produce a rational function @end quotation @lisp @@ -13589,13 +13589,13 @@ not attempt to reduce fractions to lowest terms. Test your system by calling @end lisp @quotation -Now add @t{rf} to itself, using @t{add}. You will observe that this +Now add @code{rf} to itself, using @code{add}. You will observe that this addition procedure does not reduce fractions to lowest terms. @end quotation @noindent We can reduce polynomial fractions to lowest terms using the same idea we used -with integers: modifying @t{make-rat} to divide both the numerator and the +with integers: modifying @code{make-rat} to divide both the numerator and the denominator by their greatest common divisor. The notion of ``greatest common divisor'' makes sense for polynomials. In fact, we can compute the @acronym{GCD} of two polynomials using essentially the same Euclid's Algorithm @@ -13632,18 +13632,18 @@ operation that works on term lists: @end lisp @noindent -where @t{remainder-terms} picks out the remainder component of the list -returned by the term-list division operation @t{div-terms} that was +where @code{remainder-terms} picks out the remainder component of the list +returned by the term-list division operation @code{div-terms} that was implemented in @ref{Exercise 2.91}. @quotation -@strong{@anchor{Exercise 2.94}Exercise 2.94:} Using @t{div-terms}, implement -the procedure @t{remainder-@/terms} and use this to define @t{gcd-@/terms} as -above. Now write a procedure @t{gcd-@/poly} that computes the polynomial +@strong{@anchor{Exercise 2.94}Exercise 2.94:} Using @code{div-terms}, implement +the procedure @code{remainder-@/terms} and use this to define @code{gcd-@/terms} as +above. Now write a procedure @code{gcd-@/poly} that computes the polynomial @acronym{GCD} of two polys. (The procedure should signal an error if the two polys are not in the same variable.) Install in the system a generic operation -@t{greatest-common-divisor} that reduces to @t{gcd-poly} for polynomials -and to ordinary @t{gcd} for ordinary numbers. As a test, try +@code{greatest-common-divisor} that reduces to @code{gcd-poly} for polynomials +and to ordinary @code{gcd} for ordinary numbers. As a test, try @lisp (define p1 @@ -13681,7 +13681,7 @@ $$ \eqalign{ } $$ @end tex Now define @math{Q_1} to be the product of @math{P_1} and @math{P_2}, and @math{Q_2} to be -the product of @math{P_1} and @math{P_3}, and use @t{greatest-@/common-@/divisor} +the product of @math{P_1} and @math{P_3}, and use @code{greatest-@/common-@/divisor} (@ref{Exercise 2.94}) to compute the @acronym{GCD} of @math{Q_1} and @math{Q_2}. Note that the answer is not the same as @math{P_1}. This example introduces noninteger operations into the computation, causing difficulties with the @@ -13690,7 +13690,7 @@ Scheme, this produces a polynomial that is indeed a divisor of @math{Q_1} and @math{Q_2}, but with rational coefficients. In many other Scheme systems, in which division of integers can produce limited-precision decimal numbers, we may fail to get a valid divisor.} To understand what is happening, try tracing -@t{gcd-@/terms} while computing the @acronym{GCD} or try performing the +@code{gcd-@/terms} while computing the @acronym{GCD} or try performing the division by hand. @end quotation @@ -13711,7 +13711,7 @@ More precisely, if @math{P} and @math{Q} are polynomials, let @math{O_1} be the order of @math{Q}. Let @math{c} be the leading coefficient of @math{Q}. Then it can be shown that, if we multiply @math{P} by the @newterm{@w{integerizing} @w{factor}} @math{c^{1 + O_1 - O_2}}, the resulting polynomial can be divided by @math{Q} by -using the @t{div-terms} algorithm without introducing any fractions. The +using the @code{div-terms} algorithm without introducing any fractions. The operation of multiplying the dividend by this constant and then dividing is sometimes called the @newterm{pseudodivision} of @math{P} by @math{Q}. The remainder of the division is called the @newterm{pseudoremainder}. @@ -13721,16 +13721,16 @@ of the division is called the @newterm{pseudoremainder}. @enumerate a @item -Implement the procedure @t{pseudoremainder-@/terms}, which is just like -@t{remainder-@/terms} except that it multiplies the dividend by the -integerizing factor described above before calling @t{div-@/terms}. Modify -@t{gcd-@/terms} to use @t{pseudoremainder-@/terms}, and verify that -@t{greatest-@/common-@/divisor} now produces an answer with integer coefficients +Implement the procedure @code{pseudoremainder-@/terms}, which is just like +@code{remainder-@/terms} except that it multiplies the dividend by the +integerizing factor described above before calling @code{div-@/terms}. Modify +@code{gcd-@/terms} to use @code{pseudoremainder-@/terms}, and verify that +@code{greatest-@/common-@/divisor} now produces an answer with integer coefficients on the example in @ref{Exercise 2.95}. @item The @acronym{GCD} now has integer coefficients, but they are larger than those -of @math{P_1}. Modify @t{gcd-terms} so that it removes common factors from the +of @math{P_1}. Modify @code{gcd-terms} so that it removes common factors from the coefficients of the answer by dividing all the coefficients by their (integer) greatest common divisor. @@ -13744,7 +13744,7 @@ Thus, here is how to reduce a rational function to lowest terms: @item Compute the @acronym{GCD} of the numerator and denominator, using the version -of @t{gcd-terms} from @ref{Exercise 2.96}. +of @code{gcd-terms} from @ref{Exercise 2.96}. @item When you obtain the @acronym{GCD}, multiply both numerator and denominator by @@ -13770,18 +13770,18 @@ the numerator and the denominator and dividing through by this factor. @enumerate a @item -Implement this algorithm as a procedure @t{reduce-@/terms} that takes two term -lists @t{n} and @t{d} as arguments and returns a list @t{nn}, -@t{dd}, which are @t{n} and @t{d} reduced to lowest terms via the -algorithm given above. Also write a procedure @t{reduce-@/poly}, analogous to -@t{add-@/poly}, that checks to see if the two polys have the same variable. -If so, @t{reduce-@/poly} strips off the variable and passes the problem to -@t{reduce-@/terms}, then reattaches the variable to the two term lists -supplied by @t{reduce-@/terms}. +Implement this algorithm as a procedure @code{reduce-@/terms} that takes two term +lists @code{n} and @code{d} as arguments and returns a list @code{nn}, +@code{dd}, which are @code{n} and @code{d} reduced to lowest terms via the +algorithm given above. Also write a procedure @code{reduce-@/poly}, analogous to +@code{add-@/poly}, that checks to see if the two polys have the same variable. +If so, @code{reduce-@/poly} strips off the variable and passes the problem to +@code{reduce-@/terms}, then reattaches the variable to the two term lists +supplied by @code{reduce-@/terms}. @item -Define a procedure analogous to @t{reduce-@/terms} that does what the original -@t{make-@/rat} did for integers: +Define a procedure analogous to @code{reduce-@/terms} that does what the original +@code{make-@/rat} did for integers: @lisp (define (reduce-integers n d) @@ -13789,11 +13789,11 @@ Define a procedure analogous to @t{reduce-@/terms} that does what the original (list (/ n g) (/ d g)))) @end lisp -and define @t{reduce} as a generic operation that calls @t{apply-@/generic} -to dispatch to either @t{reduce-@/poly} (for @t{polynomial} arguments) or -@t{reduce-@/integers} (for @t{scheme-@/number} arguments). You can now +and define @code{reduce} as a generic operation that calls @code{apply-@/generic} +to dispatch to either @code{reduce-@/poly} (for @code{polynomial} arguments) or +@code{reduce-@/integers} (for @code{scheme-@/number} arguments). You can now easily make the rational-arithmetic package reduce fractions to lowest terms by -having @t{make-@/rat} call @t{reduce} before combining the given numerator +having @code{make-@/rat} call @code{reduce} before combining the given numerator and denominator to form a rational number. The system now handles rational expressions in either integers or polynomials. To test your program, try the example at the beginning of this extended exercise: @@ -13957,13 +13957,13 @@ operator} to enable us to change the value associated with a name. To illustrate what we mean by having a computational object with time-varying state, let us model the situation of withdrawing money from a bank account. We -will do this using a procedure @t{withdraw}, which takes as argument an -@t{amount} to be withdrawn. If there is enough money in the account to -accommodate the withdrawal, then @t{withdraw} should return the balance -remaining after the withdrawal. Otherwise, @t{withdraw} should return the +will do this using a procedure @code{withdraw}, which takes as argument an +@code{amount} to be withdrawn. If there is enough money in the account to +accommodate the withdrawal, then @code{withdraw} should return the balance +remaining after the withdrawal. Otherwise, @code{withdraw} should return the message @emph{Insufficient funds}. For example, if we begin with $100 in the account, we should obtain the following sequence of responses using -@t{withdraw}: +@code{withdraw}: @lisp (withdraw 25) @@ -13977,7 +13977,7 @@ account, we should obtain the following sequence of responses using @end lisp @noindent -Observe that the expression @t{(withdraw 25)}, evaluated twice, yields +Observe that the expression @code{(withdraw 25)}, evaluated twice, yields different values. This is a new kind of behavior for a procedure. Until now, all our procedures could be viewed as specifications for computing mathematical functions. A call to a procedure computed the value of the function applied to @@ -13985,19 +13985,19 @@ the given arguments, and two calls to the same procedure with the same arguments always produced the same result.@footnote{Actually, this is not quite true. One exception was the random-number generator in @ref{1.2.6}. Another exception involved the operation/type tables we introduced in -@ref{2.4.3}, where the values of two calls to @t{get} with the same -arguments depended on intervening calls to @t{put}. On the other hand, +@ref{2.4.3}, where the values of two calls to @code{get} with the same +arguments depended on intervening calls to @code{put}. On the other hand, until we introduce assignment, we have no way to create such procedures ourselves.} -To implement @t{withdraw}, we can use a variable @t{balance} to indicate -the balance of money in the account and define @t{withdraw} as a procedure -that accesses @t{balance}. The @t{withdraw} procedure checks to see if -@t{balance} is at least as large as the requested @t{amount}. If so, -@t{withdraw} decrements @t{balance} by @t{amount} and returns the new -value of @t{balance}. Otherwise, @t{withdraw} returns the -@emph{Insufficient funds} message. Here are the definitions of @t{balance} -and @t{withdraw}: +To implement @code{withdraw}, we can use a variable @code{balance} to indicate +the balance of money in the account and define @code{withdraw} as a procedure +that accesses @code{balance}. The @code{withdraw} procedure checks to see if +@code{balance} is at least as large as the requested @code{amount}. If so, +@code{withdraw} decrements @code{balance} by @code{amount} and returns the new +value of @code{balance}. Otherwise, @code{withdraw} returns the +@emph{Insufficient funds} message. Here are the definitions of @code{balance} +and @code{withdraw}: @lisp (define balance 100) @@ -14010,14 +14010,14 @@ and @t{withdraw}: @end lisp @noindent -Decrementing @t{balance} is accomplished by the expression +Decrementing @code{balance} is accomplished by the expression @lisp (set! balance (- balance amount)) @end lisp @noindent -This uses the @t{set!} special form, whose syntax is +This uses the @code{set!} special form, whose syntax is @lisp (set! @math{\langle}@var{name}@math{\rangle} @math{\langle}@var{new-value}@math{\rangle}) @@ -14025,22 +14025,22 @@ This uses the @t{set!} special form, whose syntax is @noindent Here @math{\langle}@var{name}@math{\kern0.08em\rangle} is a symbol and @math{\langle}@var{new-value}@math{\kern0.08em\rangle} is any expression. -@t{Set!} changes @math{\langle}@var{name}@math{\kern0.08em\rangle} so that its value is the result obtained by +@code{Set!} changes @math{\langle}@var{name}@math{\kern0.08em\rangle} so that its value is the result obtained by evaluating @math{\langle}@var{new-value}@math{\kern0.08em\rangle}. In the case at hand, we are changing -@t{balance} so that its new value will be the result of subtracting -@t{amount} from the previous value of @t{balance}.@footnote{The value of -a @t{set!} expression is implementation-dependent. @t{Set!} should be +@code{balance} so that its new value will be the result of subtracting +@code{amount} from the previous value of @code{balance}.@footnote{The value of +a @code{set!} expression is implementation-dependent. @code{Set!} should be used only for its effect, not for its value. -The name @t{set!} reflects a naming convention used in Scheme: Operations +The name @code{set!} reflects a naming convention used in Scheme: Operations that change the values of variables (or that change data structures, as we will see in @ref{3.3}) are given names that end with an exclamation point. This is similar to the convention of designating predicates by names that end with a question mark.} -@t{Withdraw} also uses the @t{begin} special form to cause two -expressions to be evaluated in the case where the @t{if} test is true: first -decrementing @t{balance} and then returning the value of @t{balance}. In +@code{Withdraw} also uses the @code{begin} special form to cause two +expressions to be evaluated in the case where the @code{if} test is true: first +decrementing @code{balance} and then returning the value of @code{balance}. In general, evaluating the expression @lisp @@ -14050,24 +14050,24 @@ general, evaluating the expression @noindent causes the expressions @math{\langle}@math{exp_1}@math{\kern0.08em\rangle} through @math{\langle}@math{exp_k}@math{\kern0.08em\rangle} to be evaluated in sequence and the value of the final expression @math{\langle}@math{exp_k}@math{\kern0.08em\rangle} to be -returned as the value of the entire @t{begin} form.@footnote{We have already -used @t{begin} implicitly in our programs, because in Scheme the body of a +returned as the value of the entire @code{begin} form.@footnote{We have already +used @code{begin} implicitly in our programs, because in Scheme the body of a procedure can be a sequence of expressions. Also, the @math{\langle}@var{consequent}@math{\kern0.08em\rangle} part -of each clause in a @t{cond} expression can be a sequence of expressions +of each clause in a @code{cond} expression can be a sequence of expressions rather than a single expression.} -Although @t{withdraw} works as desired, the variable @t{balance} presents -a problem. As specified above, @t{balance} is a name defined in the global +Although @code{withdraw} works as desired, the variable @code{balance} presents +a problem. As specified above, @code{balance} is a name defined in the global environment and is freely accessible to be examined or modified by any -procedure. It would be much better if we could somehow make @t{balance} -internal to @t{withdraw}, so that @t{withdraw} would be the only -procedure that could access @t{balance} directly and any other procedure -could access @t{balance} only indirectly (through calls to @t{withdraw}). -This would more accurately model the notion that @t{balance} is a local -state variable used by @t{withdraw} to keep track of the state of the +procedure. It would be much better if we could somehow make @code{balance} +internal to @code{withdraw}, so that @code{withdraw} would be the only +procedure that could access @code{balance} directly and any other procedure +could access @code{balance} only indirectly (through calls to @code{withdraw}). +This would more accurately model the notion that @code{balance} is a local +state variable used by @code{withdraw} to keep track of the state of the account. -We can make @t{balance} internal to @t{withdraw} by rewriting the +We can make @code{balance} internal to @code{withdraw} by rewriting the definition as follows: @lisp @@ -14082,22 +14082,22 @@ definition as follows: @end lisp @noindent -What we have done here is use @t{let} to establish an environment with a -local variable @t{balance}, bound to the initial value 100. Within this -local environment, we use @t{lambda} to create a procedure that takes -@t{amount} as an argument and behaves like our previous @t{withdraw} +What we have done here is use @code{let} to establish an environment with a +local variable @code{balance}, bound to the initial value 100. Within this +local environment, we use @code{lambda} to create a procedure that takes +@code{amount} as an argument and behaves like our previous @code{withdraw} procedure. This procedure---returned as the result of evaluating the -@t{let} expression---is @t{new-withdraw}, which behaves in precisely the -same way as @t{withdraw} but whose variable @t{balance} is not accessible +@code{let} expression---is @code{new-withdraw}, which behaves in precisely the +same way as @code{withdraw} but whose variable @code{balance} is not accessible by any other procedure.@footnote{In programming-language jargon, the variable -@t{balance} is said to be @newterm{encapsulated} within the -@t{new-withdraw} procedure. Encapsulation reflects the general +@code{balance} is said to be @newterm{encapsulated} within the +@code{new-withdraw} procedure. Encapsulation reflects the general system-design principle known as the @newterm{hiding principle}: One can make a system more modular and robust by protecting parts of the system from each other; that is, by providing information access only to those parts of the system that have a ``need to know.''} -Combining @t{set!} with local variables is the general programming technique +Combining @code{set!} with local variables is the general programming technique we will use for constructing computational objects with local state. Unfortunately, using this technique raises a serious problem: When we first introduced procedures, we also introduced the substitution model of evaluation @@ -14107,18 +14107,18 @@ evaluating the body of the procedure with the formal parameters replaced by their values. The trouble is that, as soon as we introduce assignment into our language, substitution is no longer an adequate model of procedure application. (We will see why this is so in @ref{3.1.3}.) As a consequence, we -technically have at this point no way to understand why the @t{new-withdraw} +technically have at this point no way to understand why the @code{new-withdraw} procedure behaves as claimed above. In order to really understand a procedure -such as @t{new-withdraw}, we will need to develop a new model of procedure +such as @code{new-withdraw}, we will need to develop a new model of procedure application. In @ref{3.2} we will introduce such a model, together -with an explanation of @t{set!} and local variables. First, however, we -examine some variations on the theme established by @t{new-withdraw}. +with an explanation of @code{set!} and local variables. First, however, we +examine some variations on the theme established by @code{new-withdraw}. -The following procedure, @t{make-withdraw}, creates ``withdrawal -processors.'' The formal parameter @t{balance} in @t{make-@/withdraw} +The following procedure, @code{make-withdraw}, creates ``withdrawal +processors.'' The formal parameter @code{balance} in @code{make-@/withdraw} specifies the initial amount of money in the account.@footnote{In contrast with -@t{new-withdraw} above, we do not have to use @t{let} to make -@t{balance} a local variable, since formal parameters are already local. +@code{new-withdraw} above, we do not have to use @code{let} to make +@code{balance} a local variable, since formal parameters are already local. This will be clearer after the discussion of the environment model of evaluation in @ref{3.2}. (See also @ref{Exercise 3.10}.)} @@ -14133,8 +14133,8 @@ evaluation in @ref{3.2}. (See also @ref{Exercise 3.10}.)} @end lisp @noindent -@t{Make-withdraw} can be used as follows to create two objects @t{W1} and -@t{W2}: +@code{Make-withdraw} can be used as follows to create two objects @code{W1} and +@code{W2}: @lisp (define W1 (make-withdraw 100)) @@ -14150,8 +14150,8 @@ evaluation in @ref{3.2}. (See also @ref{Exercise 3.10}.)} @end lisp @noindent -Observe that @t{W1} and @t{W2} are completely independent objects, each -with its own local state variable @t{balance}. Withdrawals from one do not +Observe that @code{W1} and @code{W2} are completely independent objects, each +with its own local state variable @code{balance}. Withdrawals from one do not affect the other. We can also create objects that handle deposits as well as withdrawals, and @@ -14178,17 +14178,17 @@ thus we can represent simple bank accounts. Here is a procedure that returns a @end lisp @noindent -Each call to @t{make-account} sets up an environment with a local state -variable @t{balance}. Within this environment, @t{make-account} defines -procedures @t{deposit} and @t{withdraw} that access @t{balance} and an -additional procedure @t{dispatch} that takes a ``message'' as input and -returns one of the two local procedures. The @t{dispatch} procedure itself +Each call to @code{make-account} sets up an environment with a local state +variable @code{balance}. Within this environment, @code{make-account} defines +procedures @code{deposit} and @code{withdraw} that access @code{balance} and an +additional procedure @code{dispatch} that takes a ``message'' as input and +returns one of the two local procedures. The @code{dispatch} procedure itself is returned as the value that represents the bank-account object. This is precisely the @newterm{message-passing} style of programming that we saw in @ref{2.4.3}, although here we are using it in conjunction with the ability to modify local variables. -@t{Make-account} can be used as follows: +@code{Make-account} can be used as follows: @lisp (define acc (make-account 100)) @@ -14203,10 +14203,10 @@ ability to modify local variables. @end lisp @noindent -Each call to @t{acc} returns the locally defined @t{deposit} or -@t{withdraw} procedure, which is then applied to the specified -@t{amount}. As was the case with @t{make-withdraw}, another call to -@t{make-account} +Each call to @code{acc} returns the locally defined @code{deposit} or +@code{withdraw} procedure, which is then applied to the specified +@code{amount}. As was the case with @code{make-withdraw}, another call to +@code{make-account} @lisp (define acc2 (make-account 100)) @@ -14214,15 +14214,15 @@ Each call to @t{acc} returns the locally defined @t{deposit} or @noindent will produce a completely separate account object, which maintains its own -local @t{balance}. +local @code{balance}. @quotation @strong{@anchor{Exercise 3.1}Exercise 3.1:} An @newterm{accumulator} is a procedure that is called repeatedly with a single numeric argument and accumulates its arguments into a sum. Each time it is called, it returns the -currently accumulated sum. Write a procedure @t{make-accumulator} that +currently accumulated sum. Write a procedure @code{make-accumulator} that generates accumulators, each maintaining an independent sum. The input to -@t{make-accumulator} should specify the initial value of the sum; for +@code{make-accumulator} should specify the initial value of the sum; for example @lisp @@ -14238,15 +14238,15 @@ example @strong{@anchor{Exercise 3.2}Exercise 3.2:} In software-testing applications, it is useful to be able to count the number of times a given procedure is called during the course of a computation. Write a procedure -@t{make-monitored} that takes as input a procedure, @t{f}, that itself -takes one input. The result returned by @t{make-monitored} is a third -procedure, say @t{mf}, that keeps track of the number of times it has been -called by maintaining an internal counter. If the input to @t{mf} is the -special symbol @t{how-many-calls?}, then @t{mf} returns the value of the -counter. If the input is the special symbol @t{reset-count}, then @t{mf} -resets the counter to zero. For any other input, @t{mf} returns the result -of calling @t{f} on that input and increments the counter. For instance, we -could make a monitored version of the @t{sqrt} procedure: +@code{make-monitored} that takes as input a procedure, @code{f}, that itself +takes one input. The result returned by @code{make-monitored} is a third +procedure, say @code{mf}, that keeps track of the number of times it has been +called by maintaining an internal counter. If the input to @code{mf} is the +special symbol @code{how-many-calls?}, then @code{mf} returns the value of the +counter. If the input is the special symbol @code{reset-count}, then @code{mf} +resets the counter to zero. For any other input, @code{mf} returns the result +of calling @code{f} on that input and increments the counter. For instance, we +could make a monitored version of the @code{sqrt} procedure: @lisp (define s (make-monitored sqrt)) @@ -14258,9 +14258,9 @@ could make a monitored version of the @t{sqrt} procedure: @end quotation @quotation -@strong{@anchor{Exercise 3.3}Exercise 3.3:} Modify the @t{make-account} +@strong{@anchor{Exercise 3.3}Exercise 3.3:} Modify the @code{make-account} procedure so that it creates password-protected accounts. That is, -@t{make-account} should take a symbol as an additional argument, as in +@code{make-account} should take a symbol as an additional argument, as in @lisp (define acc @@ -14280,10 +14280,10 @@ a complaint: @end quotation @quotation -@strong{@anchor{Exercise 3.4}Exercise 3.4:} Modify the @t{make-account} +@strong{@anchor{Exercise 3.4}Exercise 3.4:} Modify the @code{make-account} procedure of @ref{Exercise 3.3} by adding another local state variable so that, if an account is accessed more than seven consecutive times with an incorrect -password, it invokes the procedure @t{call-the-cops}. +password, it invokes the procedure @code{call-the-cops}. @end quotation @node 3.1.2, 3.1.3, 3.1.1, 3.1 @@ -14293,14 +14293,14 @@ As we shall see, introducing assignment into our programming language leads us into a thicket of difficult conceptual issues. Nevertheless, viewing systems as collections of objects with local state is a powerful technique for maintaining a modular design. As a simple example, consider the design of a -procedure @t{rand} that, whenever it is called, returns an integer chosen at +procedure @code{rand} that, whenever it is called, returns an integer chosen at random. It is not at all clear what is meant by ``chosen at random.'' What we -presumably want is for successive calls to @t{rand} to produce a sequence of +presumably want is for successive calls to @code{rand} to produce a sequence of numbers that has statistical properties of uniform distribution. We will not discuss methods for generating suitable sequences here. Rather, let us assume -that we have a procedure @t{rand-update} that has the property that if we +that we have a procedure @code{rand-update} that has the property that if we start with a given number @math{x_1} and form @lisp @@ -14311,13 +14311,13 @@ start with a given number @math{x_1} and form @noindent then the sequence of values @math{x_1}, @math{x_2}, @math{x_3}, @dots{} will have the desired statistical properties.@footnote{One common way to implement -@t{rand-update} is to use the rule that @math{x} is updated to @math{ax + b} +@code{rand-update} is to use the rule that @math{x} is updated to @math{ax + b} modulo @math{m}, where @math{a}, @math{b}, and @math{m} are appropriately chosen integers. Chapter 3 of @ref{Knuth 1981} includes an extensive discussion of techniques for generating sequences of random numbers and establishing their -statistical properties. Notice that the @t{rand-update} procedure computes +statistical properties. Notice that the @code{rand-update} procedure computes a mathematical function: Given the same input twice, it produces the same -output. Therefore, the number sequence produced by @t{rand-update} +output. Therefore, the number sequence produced by @code{rand-update} certainly is not ``random,'' if by ``random'' we insist that each number in the sequence is unrelated to the preceding number. The relation between ``real randomness'' and so-called @newterm{pseudo-random} sequences, which are @@ -14326,11 +14326,11 @@ properties, is a complex question involving difficult issues in mathematics and philosophy. Kolmogorov, Solomonoff, and Chaitin have made great progress in clarifying these issues; a discussion can be found in @ref{Chaitin 1975}.} -We can implement @t{rand} as a procedure with a local state variable -@t{x} that is initialized to some fixed value @t{random-init}. Each call -to @t{rand} computes @t{rand-update} of the current value of @t{x}, +We can implement @code{rand} as a procedure with a local state variable +@code{x} that is initialized to some fixed value @code{random-init}. Each call +to @code{rand} computes @code{rand-update} of the current value of @code{x}, returns this as the random number, and also stores this as the new value of -@t{x}. +@code{x}. @lisp (define rand @@ -14340,10 +14340,10 @@ returns this as the random number, and also stores this as the new value of @noindent Of course, we could generate the same sequence of random numbers without using -assignment by simply calling @t{rand-update} directly. How@-ever, this would +assignment by simply calling @code{rand-update} directly. How@-ever, this would mean that any part of our program that used random numbers would have to -explicitly remember the current value of @t{x} to be passed as an argument -to @t{rand-update}. To realize what an annoyance this would be, consider +explicitly remember the current value of @code{x} to be passed as an argument +to @code{rand-update}. To realize what an annoyance this would be, consider using random numbers to implement a technique called @newterm{Monte Carlo simulation}. @@ -14360,10 +14360,10 @@ if their @acronym{GCD} is 1. The fraction of times that the test is passed gives us our estimate of @math{6\big/\pi^2}, and from this we obtain our approximation to @math{\pi}. -The heart of our program is a procedure @t{monte-carlo}, which takes as +The heart of our program is a procedure @code{monte-carlo}, which takes as arguments the number of times to try an experiment, together with the experiment, represented as a no-argument procedure that will return either true -or false each time it is run. @t{Monte-carlo} runs the experiment for the +or false each time it is run. @code{Monte-carlo} runs the experiment for the designated number of trials and returns a number telling the fraction of the trials in which the experiment was found to be true. @@ -14388,8 +14388,8 @@ trials in which the experiment was found to be true. @end lisp @noindent -Now let us try the same computation using @t{rand-update} directly rather -than @t{rand}, the way we would be forced to proceed if we did not use +Now let us try the same computation using @code{rand-update} directly rather +than @code{rand}, the way we would be forced to proceed if we did not use assignment to model local state: @lisp @@ -14418,22 +14418,22 @@ assignment to model local state: @noindent While the program is still simple, it betrays some painful breaches of -modularity. In our first version of the program, using @t{rand}, we can -express the Monte Carlo method directly as a general @t{monte-carlo} -procedure that takes as an argument an arbitrary @t{experiment} procedure. +modularity. In our first version of the program, using @code{rand}, we can +express the Monte Carlo method directly as a general @code{monte-carlo} +procedure that takes as an argument an arbitrary @code{experiment} procedure. In our second version of the program, with no local state for the random-number -generator, @t{random-gcd-test} must explicitly manipulate the random numbers -@t{x1} and @t{x2} and recycle @t{x2} through the iterative loop as the -new input to @t{rand-update}. This explicit handling of the random numbers +generator, @code{random-gcd-test} must explicitly manipulate the random numbers +@code{x1} and @code{x2} and recycle @code{x2} through the iterative loop as the +new input to @code{rand-update}. This explicit handling of the random numbers intertwines the structure of accumulating test results with the fact that our particular experiment uses two random numbers, whereas other Monte Carlo experiments might use one random number or three. Even the top-level procedure -@t{estimate-pi} has to be concerned with supplying an initial random number. +@code{estimate-pi} has to be concerned with supplying an initial random number. The fact that the random-number generator's insides are leaking out into other parts of the program makes it difficult for us to isolate the Monte Carlo idea so that it can be applied to other tasks. In the first version of the program, assignment encapsulates the state of the random-number generator within the -@t{rand} procedure, so that the details of random-number generation remain +@code{rand} procedure, so that the details of random-number generation remain independent of the rest of the program. The general phenomenon illustrated by the Monte Carlo example is this: From the @@ -14470,20 +14470,20 @@ estimate of the proportion of the rectangle that lies in the region. Hence, multiplying this fraction by the area of the entire rectangle should produce an estimate of the integral. -Implement Monte Carlo integration as a procedure @t{estimate-@/integral} that -takes as arguments a predicate @t{P}, upper and lower bounds @t{x1}, -@t{x2}, @t{y1}, and @t{y2} for the rectangle, and the number of trials +Implement Monte Carlo integration as a procedure @code{estimate-@/integral} that +takes as arguments a predicate @code{P}, upper and lower bounds @code{x1}, +@code{x2}, @code{y1}, and @code{y2} for the rectangle, and the number of trials to perform in order to produce the estimate. Your procedure should use the -same @t{monte-carlo} procedure that was used above to estimate @math{\pi}. -Use your @t{estimate-integral} to produce an estimate of @math{\pi} by +same @code{monte-carlo} procedure that was used above to estimate @math{\pi}. +Use your @code{estimate-integral} to produce an estimate of @math{\pi} by measuring the area of a unit circle. You will find it useful to have a procedure that returns a number chosen at -random from a given range. The following @t{random-@/in-@/range} procedure -implements this in terms of the @t{random} procedure used in +random from a given range. The following @code{random-@/in-@/range} procedure +implements this in terms of the @code{random} procedure used in @ref{1.2.6}, which returns a nonnegative number less than its input.@footnote{@acronym{MIT} Scheme provides such a procedure. If -@t{random} is given an exact integer (as in @ref{1.2.6}) it returns +@code{random} is given an exact integer (as in @ref{1.2.6}) it returns an exact integer, but if it is given a decimal value (as in this exercise) it returns a decimal value.} @@ -14497,10 +14497,10 @@ returns a decimal value.} @quotation @strong{@anchor{Exercise 3.6}Exercise 3.6:} It is useful to be able to reset a random-number generator to produce a sequence starting from a given value. -Design a new @t{rand} procedure that is called with an argument that is -either the symbol @t{generate} or the symbol @t{reset} and behaves as -follows: @t{(rand 'generate)} produces a new random number; @t{((rand -'reset)}@math{\;\langle}@var{new-value}@math{\kern0.11em\rangle}@t{)} resets the internal state variable to the +Design a new @code{rand} procedure that is called with an argument that is +either the symbol @code{generate} or the symbol @code{reset} and behaves as +follows: @code{(rand 'generate)} produces a new random number; @code{((rand +'reset)}@math{\;\langle}@var{new-value}@math{\kern0.11em\rangle}@code{)} resets the internal state variable to the designated @math{\langle}@var{new-value}@math{\kern0.08em\rangle}. Thus, by resetting the state, one can generate repeatable sequences. These are very handy to have when testing and debugging programs that use random numbers. @@ -14509,7 +14509,7 @@ programs that use random numbers. @node 3.1.3, , 3.1.2, 3.1 @subsection The Costs of Introducing Assignment -As we have seen, the @t{set!} operation enables us to model objects that +As we have seen, the @code{set!} operation enables us to model objects that have local state. However, this advantage comes at a price. Our programming language can no longer be interpreted in terms of the substitution model of procedure application that we introduced in @ref{1.1.5}. Moreover, no @@ -14523,7 +14523,7 @@ assignments, as we did throughout the first two chapters of this book, is accordingly known as @newterm{functional programming}. To understand how assignment complicates matters, consider a simplified version -of the @t{make-withdraw} procedure of @ref{3.1.1} that does not +of the @code{make-withdraw} procedure of @ref{3.1.1} that does not bother to check for an insufficient amount: @lisp @@ -14540,8 +14540,8 @@ bother to check for an insufficient amount: @end lisp @noindent -Compare this procedure with the following @t{make-@/decre-@/menter} procedure, -which does not use @t{set!}: +Compare this procedure with the following @code{make-@/decre-@/menter} procedure, +which does not use @code{set!}: @lisp (define (make-decrementer balance) @@ -14550,9 +14550,9 @@ which does not use @t{set!}: @end lisp @noindent -@t{Make-decrementer} returns a procedure that subtracts its input from a -designated amount @t{balance}, but there is no accumulated effect over -successive calls, as with @t{make-@/simplified-@/withdraw}: +@code{Make-decrementer} returns a procedure that subtracts its input from a +designated amount @code{balance}, but there is no accumulated effect over +successive calls, as with @code{make-@/simplified-@/withdraw}: @lisp (define D (make-decrementer 25)) @@ -14563,7 +14563,7 @@ successive calls, as with @t{make-@/simplified-@/withdraw}: @end lisp @noindent -We can use the substitution model to explain how @t{make-@/decrementer} works. +We can use the substitution model to explain how @code{make-@/decrementer} works. For instance, let us analyze the evaluation of the expression @lisp @@ -14572,7 +14572,7 @@ For instance, let us analyze the evaluation of the expression @noindent We first simplify the operator of the combination by substituting 25 for -@t{balance} in the body of @t{make-decrementer}. This reduces the +@code{balance} in the body of @code{make-decrementer}. This reduces the expression to @lisp @@ -14580,8 +14580,8 @@ expression to @end lisp @noindent -Now we apply the operator by substituting 20 for @t{amount} in the body of -the @t{lambda} expression: +Now we apply the operator by substituting 20 for @code{amount} in the body of +the @code{lambda} expression: @lisp (- 25 20) @@ -14591,18 +14591,18 @@ the @t{lambda} expression: The final answer is 5. Observe, however, what happens if we attempt a similar substitution analysis -with @t{make-simplified-withdraw}: +with @code{make-simplified-withdraw}: @lisp ((make-simplified-withdraw 25) 20) @end lisp @noindent -We first simplify the operator by substituting 25 for @t{balance} in the -body of @t{make-simplified-withdraw}. This reduces the expression -to@footnote{We don't substitute for the occurrence of @t{balance} in the -@t{set!} expression because the @math{\langle}@var{name}@math{\kern0.08em\rangle} in a @t{set!} is not -evaluated. If we did substitute for it, we would get @t{(set! 25 (- 25 +We first simplify the operator by substituting 25 for @code{balance} in the +body of @code{make-simplified-withdraw}. This reduces the expression +to@footnote{We don't substitute for the occurrence of @code{balance} in the +@code{set!} expression because the @math{\langle}@var{name}@math{\kern0.08em\rangle} in a @code{set!} is not +evaluated. If we did substitute for it, we would get @code{(set! 25 (- 25 amount))}, which makes no sense.} @lisp @@ -14611,8 +14611,8 @@ amount))}, which makes no sense.} @end lisp @noindent -Now we apply the operator by substituting 20 for @t{amount} in the body of -the @t{lambda} expression: +Now we apply the operator by substituting 20 for @code{amount} in the body of +the @code{lambda} expression: @lisp (set! balance (- 25 20)) 25 @@ -14620,16 +14620,16 @@ the @t{lambda} expression: @noindent If we adhered to the substitution model, we would have to say that the meaning -of the procedure application is to first set @t{balance} to 5 and then +of the procedure application is to first set @code{balance} to 5 and then return 25 as the value of the expression. This gets the wrong answer. In order to get the correct answer, we would have to somehow distinguish the first -occurrence of @t{balance} (before the effect of the @t{set!}) from the -second occurrence of @t{balance} (after the effect of the @t{set!}), and +occurrence of @code{balance} (before the effect of the @code{set!}) from the +second occurrence of @code{balance} (after the effect of the @code{set!}), and the substitution model cannot do this. The trouble here is that substitution is based ultimately on the notion that the symbols in our language are essentially names for values. But as soon as -we introduce @t{set!} and the idea that the value of a variable can change, +we introduce @code{set!} and the idea that the value of a variable can change, a variable can no longer be simply a name. Now a variable somehow refers to a place where a value can be stored, and the value stored at this place can change. In @ref{3.2} we will see how environments play this role of @@ -14642,7 +14642,7 @@ particular model of computation. As soon as we introduce change into our computational models, many notions that were previously straightforward become problematical. Consider the concept of two things being ``the same.'' -Suppose we call @t{make-decrementer} twice with the same argument to create +Suppose we call @code{make-decrementer} twice with the same argument to create two procedures: @lisp @@ -14651,12 +14651,12 @@ two procedures: @end lisp @noindent -Are @t{D1} and @t{D2} the same? An acceptable answer is yes, because -@t{D1} and @t{D2} have the same computational behavior---each is a -procedure that subtracts its input from 25. In fact, @t{D1} could be -substituted for @t{D2} in any computation without changing the result. +Are @code{D1} and @code{D2} the same? An acceptable answer is yes, because +@code{D1} and @code{D2} have the same computational behavior---each is a +procedure that subtracts its input from 25. In fact, @code{D1} could be +substituted for @code{D2} in any computation without changing the result. -Contrast this with making two calls to @t{make-@/simpli-@/fied-@/withdraw}: +Contrast this with making two calls to @code{make-@/simpli-@/fied-@/withdraw}: @lisp (define W1 (make-simplified-withdraw 25)) @@ -14664,8 +14664,8 @@ Contrast this with making two calls to @t{make-@/simpli-@/fied-@/withdraw}: @end lisp @noindent -Are @t{W1} and @t{W2} the same? Surely not, because calls to @t{W1} -and @t{W2} have distinct effects, as shown by the following sequence of +Are @code{W1} and @code{W2} the same? Surely not, because calls to @code{W1} +and @code{W2} have distinct effects, as shown by the following sequence of interactions: @lisp @@ -14678,15 +14678,15 @@ interactions: @end lisp @noindent -Even though @t{W1} and @t{W2} are ``equal'' in the sense that they are -both created by evaluating the same expression, @t{(make-simplified-withdraw -25)}, it is not true that @t{W1} could be substituted for @t{W2} in any +Even though @code{W1} and @code{W2} are ``equal'' in the sense that they are +both created by evaluating the same expression, @code{(make-simplified-withdraw +25)}, it is not true that @code{W1} could be substituted for @code{W2} in any expression without changing the result of evaluating the expression. A language that supports the concept that ``equals can be substituted for equals'' in an expression without changing the value of the expression is said to be @newterm{referentially transparent}. Referential transparency is -violated when we include @t{set!} in our computer language. This makes it +violated when we include @code{set!} in our computer language. This makes it tricky to determine when we can simplify expressions by substituting equivalent expressions. Consequently, reasoning about programs that use assignment becomes drastically more difficult. @@ -14723,16 +14723,16 @@ and modeling it as @noindent In the first situation, the two bank accounts are distinct. Transactions made by Peter will not affect Paul's account, and vice versa. In the second -situation, however, we have defined @t{paul-acc} to be @emph{the same thing} -as @t{peter-acc}. In effect, Peter and Paul now have a joint bank account, -and if Peter makes a withdrawal from @t{peter-acc} Paul will observe less -money in @t{paul-acc}. These two similar but distinct situations can cause +situation, however, we have defined @code{paul-acc} to be @emph{the same thing} +as @code{peter-acc}. In effect, Peter and Paul now have a joint bank account, +and if Peter makes a withdrawal from @code{peter-acc} Paul will observe less +money in @code{paul-acc}. These two similar but distinct situations can cause confusion in building computational models. With the shared account, in particular, it can be especially confusing that there is one object (the bank -account) that has two different names (@t{peter-acc} and @t{paul-acc}); -if we are searching for all the places in our program where @t{paul-acc} can +account) that has two different names (@code{peter-acc} and @code{paul-acc}); +if we are searching for all the places in our program where @code{paul-acc} can be changed, we must remember to look also at things that change -@t{peter-acc}.@footnote{The phenomenon of a single computational object +@code{peter-acc}.@footnote{The phenomenon of a single computational object being accessed by more than one name is known as @newterm{aliasing}. The joint bank account situation illustrates a very simple example of an alias. In @ref{3.3} we will see much more complex examples, such as ``distinct'' @@ -14784,7 +14784,7 @@ programs. For example, recall the iterative factorial program from @noindent Instead of passing arguments in the internal iterative loop, we could adopt a more imperative style by using explicit assignment to update the values of the -variables @t{product} and @t{counter}: +variables @code{product} and @code{counter}: @lisp (define (factorial n) @@ -14834,16 +14834,16 @@ explore the uses of objects with local state in designing simulations. @quotation @strong{@anchor{Exercise 3.7}Exercise 3.7:} Consider the bank account objects -created by @t{make-account}, with the password modification described in +created by @code{make-account}, with the password modification described in @ref{Exercise 3.3}. Suppose that our banking system requires the ability to -make joint accounts. Define a procedure @t{make-joint} that accomplishes -this. @t{Make-joint} should take three arguments. The first is a +make joint accounts. Define a procedure @code{make-joint} that accomplishes +this. @code{Make-joint} should take three arguments. The first is a password-protected account. The second argument must match the password with -which the account was defined in order for the @t{make-joint} operation to -proceed. The third argument is a new password. @t{Make-joint} is to create +which the account was defined in order for the @code{make-joint} operation to +proceed. The third argument is a new password. @code{Make-joint} is to create an additional access to the original account using the new password. For -example, if @t{peter-acc} is a bank account with password -@t{open-sesame}, then +example, if @code{peter-acc} is a bank account with password +@code{open-sesame}, then @lisp (define paul-acc @@ -14853,8 +14853,8 @@ example, if @t{peter-acc} is a bank account with password @end lisp @noindent -will allow one to make transactions on @t{peter-acc} using the name -@t{paul-acc} and the password @t{rosebud}. You may wish to modify your +will allow one to make transactions on @code{peter-acc} using the name +@code{paul-acc} and the password @code{rosebud}. You may wish to modify your solution to @ref{Exercise 3.3} to accommodate this new feature. @end quotation @@ -14865,7 +14865,7 @@ expression is to evaluate its subexpressions. But we never specified the order in which the subexpressions should be evaluated (e.g., left to right or right to left). When we introduce assignment, the order in which the arguments to a procedure are evaluated can make a difference to the result. Define a simple -procedure @t{f} such that evaluating +procedure @code{f} such that evaluating @lisp (+ (f 0) (f 1)) @@ -14873,7 +14873,7 @@ procedure @t{f} such that evaluating @noindent will return 0 if -the arguments to @t{+} are evaluated from left to right but will return 1 if +the arguments to @code{+} are evaluated from left to right but will return 1 if the arguments are evaluated from right to left. @end quotation @@ -14913,16 +14913,16 @@ is said to be @newterm{unbound} in the environment. @ref{Figure 3.1} shows a simple environment structure consisting of three frames, labeled I, II, and III. In the diagram, A, B, C, and D are pointers to -environments. C and D point to the same environment. The variables @t{z} -and @t{x} are bound in frame II, while @t{y} and @t{x} are bound in -frame I. The value of @t{x} in environment D is 3. The value of @t{x} +environments. C and D point to the same environment. The variables @code{z} +and @code{x} are bound in frame II, while @code{y} and @code{x} are bound in +frame I. The value of @code{x} in environment D is 3. The value of @code{x} with respect to environment B is also 3. This is determined as follows: We examine the first frame in the sequence (frame III) and do not find a binding -for @t{x}, so we proceed to the enclosing environment D and find the binding -in frame I. On the other hand, the value of @t{x} in environment A is 7, +for @code{x}, so we proceed to the enclosing environment D and find the binding +in frame I. On the other hand, the value of @code{x} in environment A is 7, because the first frame in the sequence (frame II) contains a binding of -@t{x} to 7. With respect to environment A, the binding of @t{x} to 7 in -frame II is said to @newterm{shadow} the binding of @t{x} to 3 in frame I. +@code{x} to 7. With respect to environment A, the binding of @code{x} to 7 in +frame II is said to @newterm{shadow} the binding of @code{x} to 3 in frame I. @float @quotation @@ -14962,14 +14962,14 @@ context in which an expression should be evaluated. Indeed, one could say that expressions in a programming language do not, in themselves, have any meaning. Rather, an expression acquires a meaning only with respect to some environment in which it is evaluated. Even the interpretation of an expression as -straightforward as @t{(+ 1 1)} depends on an understanding that one is -operating in a context in which @t{+} is the symbol for addition. Thus, in +straightforward as @code{(+ 1 1)} depends on an understanding that one is +operating in a context in which @code{+} is the symbol for addition. Thus, in our model of evaluation we will always speak of evaluating an expression with respect to some environment. To describe interactions with the interpreter, we will suppose that there is a global environment, consisting of a single frame (with no enclosing environment) that includes values for the symbols associated -with the primitive procedures. For example, the idea that @t{+} is the -symbol for addition is captured by saying that the symbol @t{+} is bound in +with the primitive procedures. For example, the idea that @code{+} is the +symbol for addition is captured by saying that the symbol @code{+} is bound in the global environment to the primitive addition procedure. @menu @@ -15040,24 +15040,24 @@ have been equivalent to have used @end lisp @noindent -which evaluates @t{(lambda (x) (* x x))} and binds @t{square} to the +which evaluates @code{(lambda (x) (* x x))} and binds @code{square} to the resulting value, all in the global environment. -@ref{Figure 3.2} shows the result of evaluating this @t{define} expression. +@ref{Figure 3.2} shows the result of evaluating this @code{define} expression. The procedure object is a pair whose code specifies that the procedure has one -formal parameter, namely @t{x}, and a procedure body @t{(* x x)}. The +formal parameter, namely @code{x}, and a procedure body @code{(* x x)}. The environment part of the procedure is a pointer to the global environment, since that is the environment in which the @math{\lambda}-expression was evaluated to produce the procedure. A new binding, which associates the procedure object -with the symbol @t{square}, has been added to the global frame. In general, -@t{define} creates definitions by adding bindings to frames. +with the symbol @code{square}, has been added to the global frame. In general, +@code{define} creates definitions by adding bindings to frames. @float @quotation @anchor{Figure 3.2} @ifinfo @strong{Figure 3.2:} Environment structure produced by -evaluating @t{(define (square x) (* x x))} in the global environment. +evaluating @code{(define (square x) (* x x))} in the global environment. @example +----------------------+ @@ -15082,7 +15082,7 @@ env | square: --+ | @center @image{fig/chap3/Fig3.2b,81mm,,,.pdf} @sp 0.4 @strong{Figure 3.2:} Environment structure produced by -evaluating @t{(define (square x) (* x x))} in the global environment. +evaluating @code{(define (square x) (* x x))} in the global environment. @sp 0.6 @end iftex @end quotation @@ -15097,23 +15097,23 @@ frame is the environment specified by the procedure. Now, within this new environment, evaluate the procedure body. To show how this rule is followed, @ref{Figure 3.3} illustrates the environment -structure created by evaluating the expression @t{(square 5)} in the global -environment, where @t{square} is the procedure generated in @ref{Figure 3.2}. +structure created by evaluating the expression @code{(square 5)} in the global +environment, where @code{square} is the procedure generated in @ref{Figure 3.2}. Applying the procedure results in the creation of a new environment, -labeled E1 in the figure, that begins with a frame in which @t{x}, the +labeled E1 in the figure, that begins with a frame in which @code{x}, the formal parameter for the procedure, is bound to the argument 5. The pointer leading upward from this frame shows that the frame's enclosing environment is the global environment. The global environment is chosen here, because this is -the environment that is indicated as part of the @t{square} procedure -object. Within E1, we evaluate the body of the procedure, @t{(* x x)}. -Since the value of @t{x} in E1 is 5, the result is @t{(* 5 5)}, or 25. +the environment that is indicated as part of the @code{square} procedure +object. Within E1, we evaluate the body of the procedure, @code{(* x x)}. +Since the value of @code{x} in E1 is 5, the result is @code{(* 5 5)}, or 25. @float @quotation @anchor{Figure 3.3} @ifinfo @strong{Figure 3.3:} Environment created by evaluating -@t{(square 5)} in the global environment. +@code{(square 5)} in the global environment. @example +------------------------------------+ @@ -15138,7 +15138,7 @@ env | square: --+ | @center @image{fig/chap3/Fig3.3b,129mm,,,.pdf} @sp 0.5 @strong{Figure 3.3:} Environment created by evaluating -@t{(square 5)} in the global environment. +@code{(square 5)} in the global environment. @sp 0.0 @end iftex @end quotation @@ -15165,21 +15165,21 @@ the procedure was created. @end itemize @noindent -We also specify that defining a symbol using @t{define} creates a binding in +We also specify that defining a symbol using @code{define} creates a binding in the current environment frame and assigns to the symbol the indicated value.@footnote{If there is already a binding for the variable in the current frame, then the binding is changed. This is convenient because it allows -redefinition of symbols; however, it also means that @t{define} can be used +redefinition of symbols; however, it also means that @code{define} can be used to change values, and this brings up the issues of assignment without -explicitly using @t{set!}. Because of this, some people prefer +explicitly using @code{set!}. Because of this, some people prefer redefinitions of existing symbols to signal errors or warnings.} Finally, we -specify the behavior of @t{set!}, the operation that forced us to introduce +specify the behavior of @code{set!}, the operation that forced us to introduce the environment model in the first place. Evaluating the expression -@t{(set!}@math{\;\langle}@var{variable}@math{\kern0.08em\rangle}@math{\;\langle}@var{value}@math{\kern0.08em\rangle}@t{)} in some environment locates the +@code{(set!}@math{\;\langle}@var{variable}@math{\kern0.08em\rangle}@math{\;\langle}@var{value}@math{\kern0.08em\rangle}@code{)} in some environment locates the binding of the variable in the environment and changes that binding to indicate the new value. That is, one finds the first frame in the environment that contains a binding for the variable and modifies that frame. If the variable -is unbound in the environment, then @t{set!} signals an error. +is unbound in the environment, then @code{set!} signals an error. These evaluation rules, though considerably more complex than the substitution model, are still reasonably straightforward. Moreover, the evaluation model, @@ -15193,7 +15193,7 @@ programs. @subsection Applying Simple Procedures When we introduced the substitution model in @ref{1.1.5} we showed how -the combination @t{(f 5)} evaluates to 136, given the following procedure +the combination @code{(f 5)} evaluates to 136, given the following procedure definitions: @lisp @@ -15208,7 +15208,7 @@ definitions: @noindent We can analyze the same example using the environment model. @ref{Figure 3.4} shows the three procedure objects created by evaluating the definitions of -@t{f}, @t{square}, and @t{sum-of-squares} in the global environment. +@code{f}, @code{square}, and @code{sum-of-squares} in the global environment. Each procedure object consists of some code, together with a pointer to the global environment. @@ -15250,9 +15250,9 @@ env | f: --+ | @noindent In @ref{Figure 3.5} we see the environment structure created by evaluating the -expression @t{(f 5)}. The call to @t{f} creates a new environment E1 -beginning with a frame in which @t{a}, the formal parameter of @t{f}, is -bound to the argument 5. In E1, we evaluate the body of @t{f}: +expression @code{(f 5)}. The call to @code{f} creates a new environment E1 +beginning with a frame in which @code{a}, the formal parameter of @code{f}, is +bound to the argument 5. In E1, we evaluate the body of @code{f}: @lisp (sum-of-squares (+ a 1) (* a 2)) @@ -15260,20 +15260,20 @@ bound to the argument 5. In E1, we evaluate the body of @t{f}: @noindent To evaluate this combination, we first evaluate the subexpressions. The first -subexpression, @t{sum-of-squares}, has a value that is a procedure object. +subexpression, @code{sum-of-squares}, has a value that is a procedure object. (Notice how this value is found: We first look in the first frame of E1, which -contains no binding for @t{sum-of-squares}. Then we proceed to the +contains no binding for @code{sum-of-squares}. Then we proceed to the enclosing environment, i.e. the global environment, and find the binding shown in @ref{Figure 3.4}.) The other two subexpressions are evaluated by applying -the primitive operations @t{+} and @t{*} to evaluate the two combinations -@t{(+ a 1)} and @t{(* a 2)} to obtain 6 and 10, respectively. +the primitive operations @code{+} and @code{*} to evaluate the two combinations +@code{(+ a 1)} and @code{(* a 2)} to obtain 6 and 10, respectively. @float @c @quotation @anchor{Figure 3.5} @ifinfo @strong{Figure 3.5:} Environments created by evaluating -@t{(f 5)} using the procedures in @ref{Figure 3.4}. +@code{(f 5)} using the procedures in @ref{Figure 3.4}. @example +-----------------------------------------------------+ @@ -15296,36 +15296,36 @@ env +-----------------------------------------------------+ @sp 0.5 @noindent @strong{Figure 3.5:} Environments created by evaluating -@t{(f 5)} @w{using} the procedures in @ref{Figure 3.4}. +@code{(f 5)} @w{using} the procedures in @ref{Figure 3.4}. @sp 0.6 @end iftex @c @end quotation @end float @noindent -Now we apply the procedure object @t{sum-of-squares} to the arguments 6 and +Now we apply the procedure object @code{sum-of-squares} to the arguments 6 and 10. This results in a new environment E2 in which the formal parameters -@t{x} and @t{y} are bound to the arguments. Within E2 we evaluate the -combination @t{(+ (square x) (square y))}. This leads us to evaluate -@t{(square x)}, where @t{square} is found in the global frame and -@t{x} is 6. Once again, we set up a new environment, E3, in which @t{x} -is bound to 6, and within this we evaluate the body of @t{square}, which is -@t{(* x x)}. Also as part of applying @t{sum-of-squares}, we must -evaluate the subexpression @t{(square y)}, where @t{y} is 10. This -second call to @t{square} creates another environment, E4, in which -@t{x}, the formal parameter of @t{square}, is bound to 10. And within E4 -we must evaluate @t{(* x x)}. - -The important point to observe is that each call to @t{square} creates a new -environment containing a binding for @t{x}. We can see here how the +@code{x} and @code{y} are bound to the arguments. Within E2 we evaluate the +combination @code{(+ (square x) (square y))}. This leads us to evaluate +@code{(square x)}, where @code{square} is found in the global frame and +@code{x} is 6. Once again, we set up a new environment, E3, in which @code{x} +is bound to 6, and within this we evaluate the body of @code{square}, which is +@code{(* x x)}. Also as part of applying @code{sum-of-squares}, we must +evaluate the subexpression @code{(square y)}, where @code{y} is 10. This +second call to @code{square} creates another environment, E4, in which +@code{x}, the formal parameter of @code{square}, is bound to 10. And within E4 +we must evaluate @code{(* x x)}. + +The important point to observe is that each call to @code{square} creates a new +environment containing a binding for @code{x}. We can see here how the different frames serve to keep separate the different local variables all named -@t{x}. Notice that each frame created by @t{square} points to the global -environment, since this is the environment indicated by the @t{square} +@code{x}. Notice that each frame created by @code{square} points to the global +environment, since this is the environment indicated by the @code{square} procedure object. After the subexpressions are evaluated, the results are returned. The values -generated by the two calls to @t{square} are added by @t{sum-of-squares}, -and this result is returned by @t{f}. Since our focus here is on the +generated by the two calls to @code{square} are added by @code{sum-of-squares}, +and this result is returned by @code{f}. Since our focus here is on the environment structures, we will not dwell on how these returned values are passed from call to call; however, this is also an important aspect of the evaluation process, and we will return to it in detail in @ref{Chapter 5}. @@ -15358,10 +15358,10 @@ and an iterative version max-count))) @end lisp -Show the environment structures created by evaluating @t{(factorial 6)} -using each version of the @t{factorial} procedure.@footnote{The environment +Show the environment structures created by evaluating @code{(factorial 6)} +using each version of the @code{factorial} procedure.@footnote{The environment model will not clarify our claim in @ref{1.2.1} that the interpreter -can execute a procedure such as @t{fact-iter} in a constant amount of space +can execute a procedure such as @code{fact-iter} in a constant amount of space using tail recursion. We will discuss tail recursion when we deal with the control structure of the interpreter in @ref{5.4}.} @end quotation @@ -15400,7 +15400,7 @@ followed by @end lisp @noindent -@ref{Figure 3.6} shows the result of defining the @t{make-withdraw} +@ref{Figure 3.6} shows the result of defining the @code{make-withdraw} procedure in the global environment. This produces a procedure object that contains a pointer to the global environment. So far, this is no different from the examples we have already seen, except that the body of the procedure @@ -15410,7 +15410,7 @@ is itself a @math{\lambda}-expression. @quotation @anchor{Figure 3.6} @ifinfo -@strong{Figure 3.6:} Result of defining @t{make-withdraw} in the global environment. +@strong{Figure 3.6:} Result of defining @code{make-withdraw} in the global environment. @example +---------------------------+ @@ -15436,7 +15436,7 @@ env +------------------|--------+ @sp 0.4 @center @image{fig/chap3/Fig3.6c,128mm,,,.pdf} @sp 0.6 -@strong{Figure 3.6:} Result of defining @t{make-withdraw} in the global environment. +@strong{Figure 3.6:} Result of defining @code{make-withdraw} in the global environment. @sp 0.8 @end iftex @end quotation @@ -15444,7 +15444,7 @@ env +------------------|--------+ @noindent The interesting part of the computation happens when we apply the procedure -@t{make-withdraw} to an argument: +@code{make-withdraw} to an argument: @lisp (define W1 (make-withdraw 100)) @@ -15452,17 +15452,17 @@ The interesting part of the computation happens when we apply the procedure @noindent We begin, as usual, by setting up an environment E1 in which the formal -parameter @t{balance} is bound to the argument 100. Within this -environment, we evaluate the body of @t{make-withdraw}, namely the +parameter @code{balance} is bound to the argument 100. Within this +environment, we evaluate the body of @code{make-withdraw}, namely the @math{\lambda}-expression. This constructs a new procedure object, whose code -is as specified by the @t{lambda} and whose environment is E1, the -environment in which the @t{lambda} was evaluated to produce the procedure. +is as specified by the @code{lambda} and whose environment is E1, the +environment in which the @code{lambda} was evaluated to produce the procedure. The resulting procedure object is the value returned by the call to -@t{make-withdraw}. This is bound to @t{W1} in the global environment, -since the @t{define} itself is being evaluated in the global environment. +@code{make-withdraw}. This is bound to @code{W1} in the global environment, +since the @code{define} itself is being evaluated in the global environment. @ref{Figure 3.7} shows the resulting environment structure. -Now we can analyze what happens when @t{W1} is applied to an argument: +Now we can analyze what happens when @code{W1} is applied to an argument: @lisp (W1 50) @@ -15473,7 +15473,7 @@ Now we can analyze what happens when @t{W1} is applied to an argument: @c @quotation @anchor{Figure 3.7} @ifinfo -@strong{Figure 3.7:} Result of evaluating @t{(define W1 (make-withdraw 100))}. +@strong{Figure 3.7:} Result of evaluating @code{(define W1 (make-withdraw 100))}. @example +-----------------------------------------------+ @@ -15503,7 +15503,7 @@ global -->| | | @center @image{fig/chap3/Fig3.7b,145mm,,,.pdf} @sp 0.8 @quotation -@strong{Figure 3.7:} Result of evaluating @t{(define W1 (make-@/withdraw 100))}. +@strong{Figure 3.7:} Result of evaluating @code{(define W1 (make-@/withdraw 100))}. @end quotation @sp 0.1 @end iftex @@ -15514,7 +15514,7 @@ global -->| | | @c @quotation @anchor{Figure 3.8} @ifinfo -@strong{Figure 3.8:} Environments created by applying the procedure object @t{W1}. +@strong{Figure 3.8:} Environments created by applying the procedure object @code{W1}. @example +---------------------------------------------------+ @@ -15545,7 +15545,7 @@ env | W1: --+ | @center @image{fig/chap3/Fig3.8c,145mm,,,.pdf} @sp 0.8 @quotation -@strong{Figure 3.8:} Environments created by applying the procedure object @t{W1}. +@strong{Figure 3.8:} Environments created by applying the procedure object @code{W1}. @end quotation @sp 0.8 @end iftex @@ -15553,18 +15553,18 @@ env | W1: --+ | @end float @noindent -We begin by constructing a frame in which @t{amount}, the formal parameter -of @t{W1}, is bound to the argument 50. The crucial point to observe is +We begin by constructing a frame in which @code{amount}, the formal parameter +of @code{W1}, is bound to the argument 50. The crucial point to observe is that this frame has as its enclosing environment not the global environment, but rather the environment E1, because this is the environment that is -specified by the @t{W1} procedure object. Within this new environment, we +specified by the @code{W1} procedure object. Within this new environment, we evaluate the body of the procedure: @float @c @quotation @anchor{Figure 3.9} @ifinfo -@strong{Figure 3.9:} Environments after the call to @t{W1}. +@strong{Figure 3.9:} Environments after the call to @code{W1}. @example +------------------------------------+ @@ -15591,7 +15591,7 @@ env | W1: --+ | @sp 0.8 @center @image{fig/chap3/Fig3.9b,147mm,,,.pdf} @sp 0.8 -@center @strong{Figure 3.9:} Environments after the call to @t{W1}. +@center @strong{Figure 3.9:} Environments after the call to @code{W1}. @sp 0.8 @end iftex @c @end quotation @@ -15606,25 +15606,25 @@ env | W1: --+ | @noindent The resulting environment structure is shown in @ref{Figure 3.8}. The -expression being evaluated references both @t{amount} and @t{balance}. -@t{Amount} will be found in the first frame in the environment, while -@t{balance} will be found by following the enclosing-environment pointer to +expression being evaluated references both @code{amount} and @code{balance}. +@code{Amount} will be found in the first frame in the environment, while +@code{balance} will be found by following the enclosing-environment pointer to E1. -When the @t{set!} is executed, the binding of @t{balance} in E1 is -changed. At the completion of the call to @t{W1}, @t{balance} is 50, and -the frame that contains @t{balance} is still pointed to by the procedure -object @t{W1}. The frame that binds @t{amount} (in which we executed the -code that changed @t{balance}) is no longer relevant, since the procedure +When the @code{set!} is executed, the binding of @code{balance} in E1 is +changed. At the completion of the call to @code{W1}, @code{balance} is 50, and +the frame that contains @code{balance} is still pointed to by the procedure +object @code{W1}. The frame that binds @code{amount} (in which we executed the +code that changed @code{balance}) is no longer relevant, since the procedure call that constructed it has terminated, and there are no pointers to that -frame from other parts of the environment. The next time @t{W1} is called, -this will build a new frame that binds @t{amount} and whose enclosing +frame from other parts of the environment. The next time @code{W1} is called, +this will build a new frame that binds @code{amount} and whose enclosing environment is E1. We see that E1 serves as the ``place'' that holds the local -state variable for the procedure object @t{W1}. @ref{Figure 3.9} shows the -situation after the call to @t{W1}. +state variable for the procedure object @code{W1}. @ref{Figure 3.9} shows the +situation after the call to @code{W1}. Observe what happens when we create a second ``withdraw'' object by making -another call to @t{make-withdraw}: +another call to @code{make-withdraw}: @lisp (define W2 (make-withdraw 100)) @@ -15632,25 +15632,25 @@ another call to @t{make-withdraw}: @noindent This produces the environment structure of @ref{Figure 3.10}, which shows that -@t{W2} is a procedure object, that is, a pair with some code and an -environment. The environment E2 for @t{W2} was created by the call to -@t{make-withdraw}. It contains a frame with its own local binding for -@t{balance}. On the other hand, @t{W1} and @t{W2} have the same code: +@code{W2} is a procedure object, that is, a pair with some code and an +environment. The environment E2 for @code{W2} was created by the call to +@code{make-withdraw}. It contains a frame with its own local binding for +@code{balance}. On the other hand, @code{W1} and @code{W2} have the same code: the code specified by the @math{\lambda}-expression in the body of -@t{make-withdraw}.@footnote{Whether @t{W1} and @t{W2} share the same +@code{make-withdraw}.@footnote{Whether @code{W1} and @code{W2} share the same physical code stored in the computer, or whether they each keep a copy of the code, is a detail of the implementation. For the interpreter we implement in -@ref{Chapter 4}, the code is in fact shared.} We see here why @t{W1} and -@t{W2} behave as independent objects. Calls to @t{W1} reference the -state variable @t{balance} stored in E1, whereas calls to @t{W2} -reference the @t{balance} stored in E2. Thus, changes to the local state of +@ref{Chapter 4}, the code is in fact shared.} We see here why @code{W1} and +@code{W2} behave as independent objects. Calls to @code{W1} reference the +state variable @code{balance} stored in E1, whereas calls to @code{W2} +reference the @code{balance} stored in E2. Thus, changes to the local state of one object do not affect the other object. @float @c @quotation @anchor{Figure 3.10} @ifinfo -@strong{Figure 3.10:} Using @t{(define W2 (make-withdraw 100))} to create a second object. +@strong{Figure 3.10:} Using @code{(define W2 (make-withdraw 100))} to create a second object. @example +-------------------------------------------------+ @@ -15679,7 +15679,7 @@ env | W1: --+ | | @sp 0.4 @c @quotation @noindent -@strong{Figure 3.10:} Using @t{(define W2 (make-withdraw 100))} to create a second object. +@strong{Figure 3.10:} Using @code{(define W2 (make-withdraw 100))} to create a second object. @c @end quotation @sp 0.5 @end iftex @@ -15687,10 +15687,10 @@ env | W1: --+ | | @end float @quotation -@strong{@anchor{Exercise 3.10}Exercise 3.10:} In the @t{make-withdraw} -procedure, the local variable @t{balance} is created as a parameter of -@t{make-withdraw}. We could also create the local state variable -explicitly, using @t{let}, as follows: +@strong{@anchor{Exercise 3.10}Exercise 3.10:} In the @code{make-withdraw} +procedure, the local variable @code{balance} is created as a parameter of +@code{make-withdraw}. We could also create the local state variable +explicitly, using @code{let}, as follows: @lisp (define (make-withdraw initial-amount) @@ -15703,7 +15703,7 @@ explicitly, using @t{let}, as follows: "Insufficient funds")))) @end lisp -Recall from @ref{1.3.2} that @t{let} is simply syntactic sugar for a +Recall from @ref{1.3.2} that @code{let} is simply syntactic sugar for a procedure call: @lisp @@ -15718,7 +15718,7 @@ is interpreted as an alternate syntax for @end lisp Use the environment model to analyze this alternate version of -@t{make-@/withdraw}, drawing figures like the ones above to illustrate the +@code{make-@/withdraw}, drawing figures like the ones above to illustrate the interactions @lisp @@ -15727,7 +15727,7 @@ interactions (define W2 (make-withdraw 100)) @end lisp -Show that the two versions of @t{make-withdraw} create objects with the same +Show that the two versions of @code{make-withdraw} create objects with the same behavior. How do the environment structures differ for the two versions? @end quotation @@ -15754,15 +15754,15 @@ compute square roots: @noindent Now we can use the environment model to see why these internal definitions behave as desired. @ref{Figure 3.11} shows the point in the evaluation of the -expression @t{(sqrt 2)} where the internal procedure @t{good-enough?} has -been called for the first time with @t{guess} equal to 1. +expression @code{(sqrt 2)} where the internal procedure @code{good-enough?} has +been called for the first time with @code{guess} equal to 1. -Observe the structure of the environment. @t{Sqrt} is a symbol in the +Observe the structure of the environment. @code{Sqrt} is a symbol in the global environment that is bound to a procedure object whose associated -environment is the global environment. When @t{sqrt} was called, a new +environment is the global environment. When @code{sqrt} was called, a new environment E1 was formed, subordinate to the global environment, in which the -parameter @t{x} is bound to 2. The body of @t{sqrt} was then evaluated -in E1. Since the first expression in the body of @t{sqrt} is +parameter @code{x} is bound to 2. The body of @code{sqrt} was then evaluated +in E1. Since the first expression in the body of @code{sqrt} is @lisp (define (good-enough? guess) @@ -15770,18 +15770,18 @@ in E1. Since the first expression in the body of @t{sqrt} is @end lisp @noindent -evaluating this expression defined the procedure @t{good-enough?} in the -environment E1. To be more precise, the symbol @t{good-enough?} was added +evaluating this expression defined the procedure @code{good-enough?} in the +environment E1. To be more precise, the symbol @code{good-enough?} was added to the first frame of E1, bound to a procedure object whose associated -environment is E1. Similarly, @t{improve} and @t{sqrt-iter} were defined +environment is E1. Similarly, @code{improve} and @code{sqrt-iter} were defined as procedures in E1. For conciseness, @ref{Figure 3.11} shows only the -procedure object for @t{good-enough?}. +procedure object for @code{good-enough?}. @float @c @quotation @anchor{Figure 3.11} @ifinfo -@strong{Figure 3.11:} @t{Sqrt} procedure with internal definitions. +@strong{Figure 3.11:} @code{Sqrt} procedure with internal definitions. @example +--------------------------------------------------+ @@ -15813,28 +15813,28 @@ body: (define good-enough? ...) | sqrt-iter: ... | | @sp 0.5 @center @image{fig/chap3/Fig3.11b,147mm,,,.pdf} @sp 0.5 -@center @strong{Figure 3.11:} @t{Sqrt} procedure with internal definitions. +@center @strong{Figure 3.11:} @code{Sqrt} procedure with internal definitions. @sp 0.5 @end iftex @c @end quotation @end float @noindent -After the local procedures were defined, the expression @t{(sqrt-iter 1.0)} +After the local procedures were defined, the expression @code{(sqrt-iter 1.0)} was evaluated, still in environment E1. So the procedure object bound to -@t{sqrt-iter} in E1 was called with 1 as an argument. This created an -environment E2 in which @t{guess}, the parameter of @t{sqrt-iter}, is -bound to 1. @t{Sqrt-iter} in turn called @t{good-enough?} with the value -of @t{guess} (from E2) as the argument for @t{good-enough?}. This set up -another environment, E3, in which @t{guess} (the parameter of -@t{good-enough?}) is bound to 1. Although @t{sqrt-iter} and -@t{good-enough?} both have a parameter named @t{guess}, these are two +@code{sqrt-iter} in E1 was called with 1 as an argument. This created an +environment E2 in which @code{guess}, the parameter of @code{sqrt-iter}, is +bound to 1. @code{Sqrt-iter} in turn called @code{good-enough?} with the value +of @code{guess} (from E2) as the argument for @code{good-enough?}. This set up +another environment, E3, in which @code{guess} (the parameter of +@code{good-enough?}) is bound to 1. Although @code{sqrt-iter} and +@code{good-enough?} both have a parameter named @code{guess}, these are two distinct local variables located in different frames. Also, E2 and E3 both -have E1 as their enclosing environment, because the @t{sqrt-iter} and -@t{good-enough?} procedures both have E1 as their environment part. One -consequence of this is that the symbol @t{x} that appears in the body of -@t{good-enough?} will reference the binding of @t{x} that appears in E1, -namely the value of @t{x} with which the original @t{sqrt} procedure was +have E1 as their enclosing environment, because the @code{sqrt-iter} and +@code{good-enough?} procedures both have E1 as their environment part. One +consequence of this is that the symbol @code{x} that appears in the body of +@code{good-enough?} will reference the binding of @code{x} that appears in E1, +namely the value of @code{x} with which the original @code{sqrt} procedure was called. The environment model thus explains the two key properties that make local @@ -15894,7 +15894,7 @@ Show the environment structure generated by the sequence of interactions @i{30} @end lisp -Where is the local state for @t{acc} kept? Suppose we define another +Where is the local state for @code{acc} kept? Suppose we define another account @lisp @@ -15902,7 +15902,7 @@ account @end lisp How are the local states for the two accounts kept distinct? Which parts of -the environment structure are shared between @t{acc} and @t{acc2}? +the environment structure are shared between @code{acc} and @code{acc2}? @end quotation @node 3.3, 3.4, 3.2, Chapter 3 @@ -15951,25 +15951,25 @@ complex systems are modeled as collections of objects with local state. @node 3.3.1, 3.3.2, 3.3, 3.3 @subsection Mutable List Structure -The basic operations on pairs---@t{cons}, @t{car}, and @t{cdr}---can +The basic operations on pairs---@code{cons}, @code{car}, and @code{cdr}---can be used to construct list structure and to select parts from list structure, but they are incapable of modifying list structure. The same is true of the -list operations we have used so far, such as @t{append} and @t{list}, -since these can be defined in terms of @t{cons}, @t{car}, and @t{cdr}. +list operations we have used so far, such as @code{append} and @code{list}, +since these can be defined in terms of @code{cons}, @code{car}, and @code{cdr}. To modify list structures we need new operations. -The primitive mutators for pairs are @t{set-@/car!} and -@t{set-@/cdr!}. @t{Set-@/car!} takes two arguments, the first of which must -be a pair. It modifies this pair, replacing the @t{car} pointer by a -pointer to the second argument of @t{set-@/car!}.@footnote{@t{Set-car!} and -@t{set-cdr!} return implementation-dependent values. Like @t{set!}, they +The primitive mutators for pairs are @code{set-@/car!} and +@code{set-@/cdr!}. @code{Set-@/car!} takes two arguments, the first of which must +be a pair. It modifies this pair, replacing the @code{car} pointer by a +pointer to the second argument of @code{set-@/car!}.@footnote{@code{Set-car!} and +@code{set-cdr!} return implementation-dependent values. Like @code{set!}, they should be used only for their effect.} @float @quotation @anchor{Figure 3.12} @ifinfo -@strong{Figure 3.12:} Lists @t{x}: @t{((a b) c d)} and @t{y}: @t{(e f)}. +@strong{Figure 3.12:} Lists @code{x}: @code{((a b) c d)} and @code{y}: @code{(e f)}. @example +---+---+ +---+---+ +---+---+ @@ -15999,20 +15999,20 @@ x -->| * | *-+---->| * | *-+---->| * | / | @sp 0.4 @center @image{fig/chap3/Fig3.12b,123mm,,,.pdf} @sp 0.7 -@center @strong{Figure 3.12:} Lists @t{x}: @t{((a b) c d)} and @t{y}: @t{(e f)}. +@center @strong{Figure 3.12:} Lists @code{x}: @code{((a b) c d)} and @code{y}: @code{(e f)}. @sp 0.0 @end iftex @end quotation @end float @noindent -As an example, suppose that @t{x} is bound to the list @t{((a b) c d)} -and @t{y} to the list @t{(e f)} as illustrated in @ref{Figure 3.12}. -Evaluating the expression @t{ (set-car! x y)} modifies the pair to which -@t{x} is bound, replacing its @t{car} by the value of @t{y}. The -result of the operation is shown in @ref{Figure 3.13}. The structure @t{x} -has been modified and would now be printed as @t{((e f) c d)}. The pairs -representing the list @t{(a b)}, identified by the pointer that was +As an example, suppose that @code{x} is bound to the list @code{((a b) c d)} +and @code{y} to the list @code{(e f)} as illustrated in @ref{Figure 3.12}. +Evaluating the expression @code{ (set-car! x y)} modifies the pair to which +@code{x} is bound, replacing its @code{car} by the value of @code{y}. The +result of the operation is shown in @ref{Figure 3.13}. The structure @code{x} +has been modified and would now be printed as @code{((e f) c d)}. The pairs +representing the list @code{(a b)}, identified by the pointer that was replaced, are now detached from the original structure.@footnote{We see from this that mutation operations on lists can create ``garbage'' that is not part of any accessible structure. We will see in @ref{5.3.2} that Lisp @@ -16020,24 +16020,24 @@ memory-management systems include a @newterm{garbage collector}, which identifies and recycles the memory space used by unneeded pairs.} Compare @ref{Figure 3.13} with @ref{Figure 3.14}, which illustrates the result -of executing @t{(define z (cons y (cdr x)))} with @t{x} and @t{y} -bound to the original lists of @ref{Figure 3.12}. The variable @t{z} is now -bound to a new pair created by the @t{cons} operation; the list to which -@t{x} is bound is unchanged. - -The @t{set-cdr!} operation is similar to @t{set-car!}. The only -difference is that the @t{cdr} pointer of the pair, rather than the -@t{car} pointer, is replaced. The effect of executing @t{(set-cdr! x y)} +of executing @code{(define z (cons y (cdr x)))} with @code{x} and @code{y} +bound to the original lists of @ref{Figure 3.12}. The variable @code{z} is now +bound to a new pair created by the @code{cons} operation; the list to which +@code{x} is bound is unchanged. + +The @code{set-cdr!} operation is similar to @code{set-car!}. The only +difference is that the @code{cdr} pointer of the pair, rather than the +@code{car} pointer, is replaced. The effect of executing @code{(set-cdr! x y)} on the lists of @ref{Figure 3.12} is shown in @ref{Figure 3.15}. Here the -@t{cdr} pointer of @t{x} has been replaced by the pointer to @t{(e -f)}. Also, the list @t{(c d)}, which used to be the @t{cdr} of @t{x}, +@code{cdr} pointer of @code{x} has been replaced by the pointer to @code{(e +f)}. Also, the list @code{(c d)}, which used to be the @code{cdr} of @code{x}, is now detached from the structure. @float @quotation @anchor{Figure 3.13} @ifinfo -@strong{Figure 3.13:} Effect of @t{(set-car! x y)} on the lists in @ref{Figure 3.12}. +@strong{Figure 3.13:} Effect of @code{(set-car! x y)} on the lists in @ref{Figure 3.12}. @example +---+---+ +---+---+ +---+---+ @@ -16067,20 +16067,20 @@ x -->| * | *-+---->| * | *-+---->| * | / | @sp 0.0 @center @image{fig/chap3/Fig3.13b,123mm,,,.pdf} @sp 0.2 -@strong{Figure 3.13:} Effect of @t{(set-car! x y)} on the lists in @ref{Figure 3.12}. +@strong{Figure 3.13:} Effect of @code{(set-car! x y)} on the lists in @ref{Figure 3.12}. @sp 0.3 @end iftex @end quotation @end float @noindent -@t{Cons} builds new list structure by creating new pairs, while -@t{set-car!} and @t{set-cdr!} modify existing pairs. Indeed, we could -implement @t{cons} in terms of the two mutators, together with a procedure -@t{get-new-pair}, which returns a new pair that is not part of any existing -list structure. We obtain the new pair, set its @t{car} and @t{cdr} +@code{Cons} builds new list structure by creating new pairs, while +@code{set-car!} and @code{set-cdr!} modify existing pairs. Indeed, we could +implement @code{cons} in terms of the two mutators, together with a procedure +@code{get-new-pair}, which returns a new pair that is not part of any existing +list structure. We obtain the new pair, set its @code{car} and @code{cdr} pointers to the designated objects, and return the new pair as the result of -the @t{cons}.@footnote{@t{Get-new-pair} is one of the operations that +the @code{cons}.@footnote{@code{Get-new-pair} is one of the operations that must be implemented as part of the memory management required by a Lisp implementation. We will discuss this in @ref{5.3.1}.} @@ -16098,7 +16098,7 @@ implementation. We will discuss this in @ref{5.3.1}.} @quotation @anchor{Figure 3.14} @ifinfo -@strong{Figure 3.14:} Effect of @t{(define z (cons y (cdr x)))} on the lists in @ref{Figure 3.12}. +@strong{Figure 3.14:} Effect of @code{(define z (cons y (cdr x)))} on the lists in @ref{Figure 3.12}. @example +---+---+ +---+---+ +---+---+ @@ -16139,7 +16139,7 @@ z -->| * | *-+-+ +---+ +---+ @quotation @anchor{Figure 3.15} @ifinfo -@strong{Figure 3.15:} Effect of @t{(set-cdr! x y)} on the lists in @ref{Figure 3.12}. +@strong{Figure 3.15:} Effect of @code{(set-cdr! x y)} on the lists in @ref{Figure 3.12}. @example +---+---+ +---+---+ +---+---+ @@ -16169,7 +16169,7 @@ x -->| * | * | | * | *-+---->| * | / | @sp 0.0 @center @image{fig/chap3/Fig3.15b,123mm,,,.pdf} @sp 0.5 -@strong{Figure 3.15:} Effect of @t{(set-cdr! x y)} on the lists in @ref{Figure 3.12}. +@strong{Figure 3.15:} Effect of @code{(set-cdr! x y)} on the lists in @ref{Figure 3.12}. @sp 0.6 @end iftex @end quotation @@ -16186,12 +16186,12 @@ appending lists was introduced in @ref{2.2.1}: (cons (car x) (append (cdr x) y)))) @end lisp -@t{Append} forms a new list by successively @t{cons}ing the elements of -@t{x} onto @t{y}. The procedure @t{append!} is similar to -@t{append}, but it is a mutator rather than a constructor. It appends the -lists by splicing them together, modifying the final pair of @t{x} so that -its @t{cdr} is now @t{y}. (It is an error to call @t{append!} with an -empty @t{x}.) +@code{Append} forms a new list by successively @code{cons}ing the elements of +@code{x} onto @code{y}. The procedure @code{append!} is similar to +@code{append}, but it is a mutator rather than a constructor. It appends the +lists by splicing them together, modifying the final pair of @code{x} so that +its @code{cdr} is now @code{y}. (It is an error to call @code{append!} with an +empty @code{x}.) @lisp (define (append! x y) @@ -16199,7 +16199,7 @@ empty @t{x}.) x) @end lisp -Here @t{last-pair} is a procedure that returns the last pair in its +Here @code{last-pair} is a procedure that returns the last pair in its argument: @lisp @@ -16232,7 +16232,7 @@ explain your answer. @quotation @strong{@anchor{Exercise 3.13}Exercise 3.13:} Consider the following -@t{make-cycle} procedure, which uses the @t{last-pair} procedure defined +@code{make-cycle} procedure, which uses the @code{last-pair} procedure defined in @ref{Exercise 3.12}: @lisp @@ -16241,13 +16241,13 @@ in @ref{Exercise 3.12}: x) @end lisp -Draw a box-and-pointer diagram that shows the structure @t{z} created by +Draw a box-and-pointer diagram that shows the structure @code{z} created by @lisp (define z (make-cycle (list 'a 'b 'c))) @end lisp -What happens if we try to compute @t{(last-pair z)}? +What happens if we try to compute @code{(last-pair z)}? @end quotation @quotation @@ -16265,15 +16265,15 @@ useful, although obscure: (loop x '())) @end lisp -@t{Loop} uses the ``temporary'' variable @t{temp} to hold the old value -of the @t{cdr} of @t{x}, since the @t{set-cdr!} on the next line -destroys the @t{cdr}. Explain what @t{mystery} does in general. Suppose -@t{v} is defined by @t{(define v (list 'a 'b 'c 'd))}. Draw the -box-and-pointer diagram that represents the list to which @t{v} is bound. -Suppose that we now evaluate @t{(define w (mystery v))}. Draw -box-and-pointer diagrams that show the structures @t{v} and @t{w} after -evaluating this expression. What would be printed as the values of @t{v} -and @t{w}? +@code{Loop} uses the ``temporary'' variable @code{temp} to hold the old value +of the @code{cdr} of @code{x}, since the @code{set-cdr!} on the next line +destroys the @code{cdr}. Explain what @code{mystery} does in general. Suppose +@code{v} is defined by @code{(define v (list 'a 'b 'c 'd))}. Draw the +box-and-pointer diagram that represents the list to which @code{v} is bound. +Suppose that we now evaluate @code{(define w (mystery v))}. Draw +box-and-pointer diagrams that show the structures @code{v} and @code{w} after +evaluating this expression. What would be printed as the values of @code{v} +and @code{w}? @end quotation @subsubheading Sharing and identity @@ -16289,11 +16289,11 @@ objects. For example, consider the structure formed by @end lisp @noindent -As shown in @ref{Figure 3.16}, @t{z1} is a pair whose @t{car} and -@t{cdr} both point to the same pair @t{x}. This sharing of @t{x} by -the @t{car} and @t{cdr} of @t{z1} is a consequence of the -straightforward way in which @t{cons} is implemented. In general, using -@t{cons} to construct lists will result in an interlinked structure of pairs +As shown in @ref{Figure 3.16}, @code{z1} is a pair whose @code{car} and +@code{cdr} both point to the same pair @code{x}. This sharing of @code{x} by +the @code{car} and @code{cdr} of @code{z1} is a consequence of the +straightforward way in which @code{cons} is implemented. In general, using +@code{cons} to construct lists will result in an interlinked structure of pairs in which many individual pairs are shared by many different structures. In contrast to @ref{Figure 3.16}, @ref{Figure 3.17} shows the structure created @@ -16305,19 +16305,19 @@ by @end lisp @noindent -In this structure, the pairs in the two @t{(a b)} lists are distinct, +In this structure, the pairs in the two @code{(a b)} lists are distinct, although the actual symbols are shared.@footnote{The two pairs are distinct -because each call to @t{cons} returns a new pair. The symbols are shared; +because each call to @code{cons} returns a new pair. The symbols are shared; in Scheme there is a unique symbol with any given name. Since Scheme provides no way to mutate a symbol, this sharing is undetectable. Note also that the -sharing is what enables us to compare symbols using @t{eq?}, which simply +sharing is what enables us to compare symbols using @code{eq?}, which simply checks equality of pointers.} @float @quotation @anchor{Figure 3.16} @ifinfo -@strong{Figure 3.16:} The list @t{z1} formed by @t{(cons x x)}. +@strong{Figure 3.16:} The list @code{z1} formed by @code{(cons x x)}. @example +---+---+ @@ -16337,7 +16337,7 @@ z1 -->| * | * | @sp 0.1 @center @image{fig/chap3/Fig3.16b,78mm,,,.pdf} @sp 0.5 -@center @strong{Figure 3.16:} The list @t{z1} formed by @t{(cons x x)}. +@center @strong{Figure 3.16:} The list @code{z1} formed by @code{(cons x x)}. @sp 0.5 @end iftex @end quotation @@ -16347,7 +16347,7 @@ z1 -->| * | * | @quotation @anchor{Figure 3.17} @ifinfo -@strong{Figure 3.17:} The list @t{z2} formed by @t{(cons (list 'a 'b) (list 'a 'b))}. +@strong{Figure 3.17:} The list @code{z2} formed by @code{(cons (list 'a 'b) (list 'a 'b))}. @example +---+---+ +---+---+ +---+---+ @@ -16368,19 +16368,19 @@ z2 -->| * | *-+---->| * | *-+---->| * | / | @sp 0.3 @center @image{fig/chap3/Fig3.17b,121mm,,,.pdf} @sp 0.5 -@strong{Figure 3.17:} The list @t{z2} formed by @t{(cons (list 'a 'b) (list 'a 'b))}. +@strong{Figure 3.17:} The list @code{z2} formed by @code{(cons (list 'a 'b) (list 'a 'b))}. @sp 0.0 @end iftex @end quotation @end float @noindent -When thought of as a list, @t{z1} and @t{z2} both represent ``the same'' -list, @t{((a b) a b)}. In general, sharing is completely undetectable if we -operate on lists using only @t{cons}, @t{car}, and @t{cdr}. However, +When thought of as a list, @code{z1} and @code{z2} both represent ``the same'' +list, @code{((a b) a b)}. In general, sharing is completely undetectable if we +operate on lists using only @code{cons}, @code{car}, and @code{cdr}. However, if we allow mutators on list structure, sharing becomes significant. As an example of the difference that sharing can make, consider the following -procedure, which modifies the @t{car} of the structure to which it is +procedure, which modifies the @code{car} of the structure to which it is applied: @lisp @@ -16390,11 +16390,11 @@ applied: @end lisp @noindent -Even though @t{z1} and @t{z2} are ``the same'' structure, applying -@t{set-to-wow!} to them yields different results. With @t{z1}, altering -the @t{car} also changes the @t{cdr}, because in @t{z1} the @t{car} -and the @t{cdr} are the same pair. With @t{z2}, the @t{car} and -@t{cdr} are distinct, so @t{set-to-wow!} modifies only the @t{car}: +Even though @code{z1} and @code{z2} are ``the same'' structure, applying +@code{set-to-wow!} to them yields different results. With @code{z1}, altering +the @code{car} also changes the @code{cdr}, because in @code{z1} the @code{car} +and the @code{cdr} are the same pair. With @code{z2}, the @code{car} and +@code{cdr} are distinct, so @code{set-to-wow!} modifies only the @code{car}: @lisp z1 @@ -16412,18 +16412,18 @@ z2 @noindent One way to detect sharing in list structures is to use the predicate -@t{eq?}, which we introduced in @ref{2.3.1} as a way to test whether -two symbols are equal. More generally, @t{(eq? x y)} tests whether -@t{x} and @t{y} are the same object (that is, whether @t{x} and -@t{y} are equal as pointers). Thus, with @t{z1} and @t{z2} as defined -in @ref{Figure 3.16} and @ref{Figure 3.17}, @t{(eq? (car z1) (cdr -z1))} is true and @t{(eq? (car z2) (cdr z2))} is false. +@code{eq?}, which we introduced in @ref{2.3.1} as a way to test whether +two symbols are equal. More generally, @code{(eq? x y)} tests whether +@code{x} and @code{y} are the same object (that is, whether @code{x} and +@code{y} are equal as pointers). Thus, with @code{z1} and @code{z2} as defined +in @ref{Figure 3.16} and @ref{Figure 3.17}, @code{(eq? (car z1) (cdr +z1))} is true and @code{(eq? (car z2) (cdr z2))} is false. As will be seen in the following sections, we can exploit sharing to greatly extend the repertoire of data structures that can be represented by pairs. On the other hand, sharing can also be dangerous, since modifications made to structures will also affect other structures that happen to share the modified -parts. The mutation operations @t{set-car!} and @t{set-cdr!} should be +parts. The mutation operations @code{set-car!} and @code{set-cdr!} should be used with care; unless we have a good understanding of how our data objects are shared, mutation can have unanticipated results.@footnote{The subtleties of dealing with sharing of mutable data objects reflect the underlying issues of @@ -16431,7 +16431,7 @@ dealing with sharing of mutable data objects reflect the underlying issues of mentioned there that admitting change to our language requires that a compound object must have an ``identity'' that is something different from the pieces from which it is composed. In Lisp, we consider this ``identity'' to be the -quality that is tested by @t{eq?}, i.e., by equality of pointers. Since in +quality that is tested by @code{eq?}, i.e., by equality of pointers. Since in most Lisp implementations a pointer is essentially a memory address, we are ``solving the problem'' of defining the identity of objects by stipulating that a data object ``itself'' is the information stored in some particular set of @@ -16441,15 +16441,15 @@ models.} @quotation @strong{@anchor{Exercise 3.15}Exercise 3.15:} Draw box-and-pointer diagrams to -explain the effect of @t{set-to-wow!} on the structures @t{z1} and -@t{z2} above. +explain the effect of @code{set-to-wow!} on the structures @code{z1} and +@code{z2} above. @end quotation @quotation @strong{@anchor{Exercise 3.16}Exercise 3.16:} Ben Bitdiddle decides to write a procedure to count the number of pairs in any list structure. ``It's easy,'' he reasons. ``The number of pairs in any structure is the number in the -@t{car} plus the number in the @t{cdr} plus one more to count the current +@code{car} plus the number in the @code{cdr} plus one more to count the current pair.'' So Ben writes the following procedure: @lisp @@ -16468,7 +16468,7 @@ Ben's procedure would return 3; return 4; return 7; never return at all. @quotation @strong{@anchor{Exercise 3.17}Exercise 3.17:} Devise a correct version of the -@t{count-pairs} procedure of @ref{Exercise 3.16} that returns the number of +@code{count-pairs} procedure of @ref{Exercise 3.16} that returns the number of distinct pairs in any structure. (Hint: Traverse the structure, maintaining an auxiliary data structure that is used to keep track of which pairs have already been counted.) @@ -16477,7 +16477,7 @@ been counted.) @quotation @strong{@anchor{Exercise 3.18}Exercise 3.18:} Write a procedure that examines a list and determines whether it contains a cycle, that is, whether a program -that tried to find the end of the list by taking successive @t{cdr}s would +that tried to find the end of the list by taking successive @code{cdr}s would go into an infinite loop. @ref{Exercise 3.13} constructed such lists. @end quotation @@ -16508,9 +16508,9 @@ can be represented purely in terms of procedures: @noindent The same observation is true for mutable data. We can implement mutable data objects as procedures using assignment and local state. For instance, we can -extend the above pair implementation to handle @t{set-car!} and -@t{set-cdr!} in a manner analogous to the way we implemented bank accounts -using @t{make-account} in @ref{3.1.1}: +extend the above pair implementation to handle @code{set-car!} and +@code{set-cdr!} in a manner analogous to the way we implemented bank accounts +using @code{make-account} in @ref{3.1.1}: @lisp (define (cons x y) @@ -16537,7 +16537,7 @@ using @t{make-account} in @ref{3.1.1}: @noindent Assignment is all that is needed, theoretically, to account for the behavior of -mutable data. As soon as we admit @t{set!} to our language, we raise all +mutable data. As soon as we admit @code{set!} to our language, we raise all the issues, not only of assignment, but of mutable data in general.@footnote{On the other hand, from the viewpoint of implementation, assignment requires us to modify the environment, which is itself a mutable data structure. Thus, @@ -16565,17 +16565,17 @@ using the procedural implementation of pairs given above. (Compare @node 3.3.2, 3.3.3, 3.3.1, 3.3 @subsection Representing Queues -The mutators @t{set-car!} and @t{set-cdr!} enable us to use pairs to -construct data structures that cannot be built with @t{cons}, @t{car}, -and @t{cdr} alone. This section shows how to use pairs to represent a data +The mutators @code{set-car!} and @code{set-cdr!} enable us to use pairs to +construct data structures that cannot be built with @code{cons}, @code{car}, +and @code{cdr} alone. This section shows how to use pairs to represent a data structure called a queue. @ref{3.3.3} will show how to represent data structures called tables. A @newterm{queue} is a sequence in which items are inserted at one end (called the @newterm{rear} of the queue) and deleted from the other end (the @newterm{front}). @ref{Figure 3.18} shows an initially empty queue in which -the items @t{a} and @t{b} are inserted. Then @t{a} is removed, -@t{c} and @t{d} are inserted, and @t{b} is removed. Because items are +the items @code{a} and @code{b} are inserted. Then @code{a} is removed, +@code{c} and @code{d} are inserted, and @code{b} is removed. Because items are always removed in the order in which they are inserted, a queue is sometimes called a @newterm{FIFO} (first in, first out) buffer. @@ -16613,7 +16613,7 @@ set of operations: @itemize @bullet @item -a constructor: @t{(make-queue)} returns an empty queue (a queue containing +a constructor: @code{(make-queue)} returns an empty queue (a queue containing no items). @item @@ -16657,12 +16657,12 @@ its value, signaling an error if the queue is empty before the deletion. @noindent Because a queue is a sequence of items, we could certainly represent it as an -ordinary list; the front of the queue would be the @t{car} of the list, +ordinary list; the front of the queue would be the @code{car} of the list, inserting an item in the queue would amount to appending a new element at the end of the list, and deleting an item from the queue would just be taking the -@t{cdr} of the list. However, this representation is inefficient, because +@code{cdr} of the list. However, this representation is inefficient, because in order to insert an item we must scan the list until we reach the end. Since -the only method we have for scanning a list is by successive @t{cdr} +the only method we have for scanning a list is by successive @code{cdr} operations, this scanning requires @math{\Theta(n)} steps for a list of @math{n} items. A simple modification to the list representation overcomes this disadvantage by allowing the queue operations to be implemented so that they @@ -16711,11 +16711,11 @@ the rear pointer and so avoid scanning the list. @end float @noindent -A queue is represented, then, as a pair of pointers, @t{front-@/ptr} and -@t{rear-@/ptr}, which indicate, respectively, the first and last pairs in an +A queue is represented, then, as a pair of pointers, @code{front-@/ptr} and +@code{rear-@/ptr}, which indicate, respectively, the first and last pairs in an ordinary list. Since we would like the queue to be an identifiable object, we -can use @t{cons} to combine the two pointers. Thus, the queue itself will -be the @t{cons} of the two pointers. @ref{Figure 3.19} illustrates this +can use @code{cons} to combine the two pointers. Thus, the queue itself will +be the @code{cons} of the two pointers. @ref{Figure 3.19} illustrates this representation. To define the queue operations we use the following procedures, which enable us @@ -16740,15 +16740,15 @@ be empty if its front pointer is the empty list: @end lisp @noindent -The @t{make-queue} constructor returns, as an initially empty queue, a pair -whose @t{car} and @t{cdr} are both the empty list: +The @code{make-queue} constructor returns, as an initially empty queue, a pair +whose @code{car} and @code{cdr} are both the empty list: @lisp (define (make-queue) (cons '() '())) @end lisp @noindent -To select the item at the front of the queue, we return the @t{car} of the +To select the item at the front of the queue, we return the @code{car} of the pair indicated by the front pointer: @lisp @@ -16761,8 +16761,8 @@ pair indicated by the front pointer: @noindent To insert an item in a queue, we follow the method whose result is indicated in -@ref{Figure 3.20}. We first create a new pair whose @t{car} is the item to -be inserted and whose @t{cdr} is the empty list. If the queue was initially +@ref{Figure 3.20}. We first create a new pair whose @code{car} is the item to +be inserted and whose @code{cdr} is the empty list. If the queue was initially empty, we set the front and rear pointers of the queue to this new pair. Otherwise, we modify the final pair in the queue to point to the new pair, and also set the rear pointer to the new pair. @@ -16770,7 +16770,7 @@ also set the rear pointer to the new pair. @float @anchor{Figure 3.20} @ifinfo -@strong{Figure 3.20:} Result of using @t{(insert-queue! q 'd)} on the queue of @ref{Figure 3.19}. +@strong{Figure 3.20:} Result of using @code{(insert-queue! q 'd)} on the queue of @ref{Figure 3.19}. @example +---+---+ @@ -16793,7 +16793,7 @@ also set the rear pointer to the new pair. @center @image{fig/chap3/Fig3.20c,141mm,,,.pdf} @sp 0.5 @quotation -@strong{Figure 3.20:} Result of using @t{(insert-queue! q 'd)} on the queue of @ref{Figure 3.19}. +@strong{Figure 3.20:} Result of using @code{(insert-queue! q 'd)} on the queue of @ref{Figure 3.19}. @end quotation @sp 0.7 @end iftex @@ -16815,7 +16815,7 @@ also set the rear pointer to the new pair. @float @anchor{Figure 3.21} @ifinfo -@strong{Figure 3.21:} Result of using @t{(delete-queue! q)} on the queue of @ref{Figure 3.20}. +@strong{Figure 3.21:} Result of using @code{(delete-queue! q)} on the queue of @ref{Figure 3.20}. @example +---+---+ @@ -16838,7 +16838,7 @@ also set the rear pointer to the new pair. @center @image{fig/chap3/Fig3.21c,141mm,,,.pdf} @sp 0.5 @quotation -@strong{Figure 3.21:} Result of using @t{(delete-queue! q)} on the queue of @ref{Figure 3.20}. +@strong{Figure 3.21:} Result of using @code{(delete-queue! q)} on the queue of @ref{Figure 3.20}. @end quotation @sp 0.7 @end iftex @@ -16847,11 +16847,11 @@ also set the rear pointer to the new pair. @noindent To delete the item at the front of the queue, we merely modify the front pointer so that it now points at the second item in the queue, which can be -found by following the @t{cdr} pointer of the first item (see +found by following the @code{cdr} pointer of the first item (see @ref{Figure 3.21}):@footnote{If the first item is the final item in the queue, the front pointer will be the empty list after the deletion, which will mark the queue as empty; we needn't worry about updating the rear pointer, which will still point -to the deleted item, because @t{empty-queue?} looks only at the front +to the deleted item, because @code{empty-queue?} looks only at the front pointer.} @lisp @@ -16896,14 +16896,14 @@ interpreter and proceeds to try them out: ``It's all wrong!'' he complains. ``The interpreter's response shows that the last item is inserted into the queue twice. And when I delete both items, the -second @t{b} is still there, so the queue isn't empty, even though it's +second @code{b} is still there, so the queue isn't empty, even though it's supposed to be.'' Eva Lu Ator suggests that Ben has misunderstood what is happening. ``It's not that the items are going into the queue twice,'' she explains. ``It's just that the standard Lisp printer doesn't know how to make sense of the queue representation. If you want to see the queue printed correctly, you'll have to define your own print procedure for queues.'' Explain what Eva Lu is talking about. In particular, show why Ben's examples produce -the printed results that they do. Define a procedure @t{print-queue} that +the printed results that they do. Define a procedure @code{print-queue} that takes a queue as input and prints the sequence of items in the queue. @end quotation @@ -16911,7 +16911,7 @@ takes a queue as input and prints the sequence of items in the queue. @strong{@anchor{Exercise 3.22}Exercise 3.22:} Instead of representing a queue as a pair of pointers, we can build a queue as a procedure with local state. The local state will consist of pointers to the beginning and the end of an -ordinary list. Thus, the @t{make-queue} procedure will have the form +ordinary list. Thus, the @code{make-queue} procedure will have the form @lisp (define (make-queue) @@ -16922,18 +16922,18 @@ ordinary list. Thus, the @t{make-queue} procedure will have the form dispatch)) @end lisp -Complete the definition of @t{make-queue} and provide implementations of the +Complete the definition of @code{make-queue} and provide implementations of the queue operations using this representation. @end quotation @quotation @strong{@anchor{Exercise 3.23}Exercise 3.23:} A @newterm{deque} (``double-ended queue'') is a sequence in which items can be inserted and deleted at either the -front or the rear. Operations on deques are the constructor @t{make-@/deque}, -the predicate @t{empty-@/deque?}, selectors @t{front-@/deque} and -@t{rear-@/deque}, and mutators @t{front-@/insert-@/deque!}, -@t{rear-@/insert-@/deque!}, @t{front-@/delete-@/deque!}, -@t{rear-@/delete-@/deque!}. Show how to represent deques using pairs, and give +front or the rear. Operations on deques are the constructor @code{make-@/deque}, +the predicate @code{empty-@/deque?}, selectors @code{front-@/deque} and +@code{rear-@/deque}, and mutators @code{front-@/insert-@/deque!}, +@code{rear-@/insert-@/deque!}, @code{front-@/delete-@/deque!}, +@code{rear-@/delete-@/deque!}. Show how to represent deques using pairs, and give implementations of the operations.@footnote{Be careful not to make the interpreter try to print a structure that contains cycles. (See @ref{Exercise 3.13}.)} All operations should be accomplished in @math{\Theta}(1) steps. @@ -16952,12 +16952,12 @@ see how to build tables as mutable list structures. We first consider a one-dimensional table, in which each value is stored under a single key. We implement the table as a list of records, each of which is implemented as a pair consisting of a key and the associated value. The records -are glued together to form a list by pairs whose @t{car}s point to +are glued together to form a list by pairs whose @code{car}s point to successive records. These gluing pairs are called the @newterm{backbone} of the table. In order to have a place that we can change when we add a new record to the table, we build the table as a @newterm{headed list}. A headed list has a special backbone pair at the beginning, which holds a dummy -``record''---in this case the arbitrarily chosen symbol @t{*table*}. +``record''---in this case the arbitrarily chosen symbol @code{*table*}. @ref{Figure 3.22} shows the box-and-pointer diagram for the table @lisp @@ -16999,15 +16999,15 @@ V V V V V V @end float @noindent -To extract information from a table we use the @t{lookup} procedure, which +To extract information from a table we use the @code{lookup} procedure, which takes a key as argument and returns the associated value (or false if there is -no value stored under that key). @t{Lookup} is defined in terms of the -@t{assoc} operation, which expects a key and a list of records as arguments. -Note that @t{assoc} never sees the dummy record. @t{Assoc} returns the -record that has the given key as its @t{car}.@footnote{Because @t{assoc} -uses @t{equal?}, it can recognize keys that are symbols, numbers, or list -structure.} @t{Lookup} then checks to see that the resulting record -returned by @t{assoc} is not false, and returns the value (the @t{cdr}) +no value stored under that key). @code{Lookup} is defined in terms of the +@code{assoc} operation, which expects a key and a list of records as arguments. +Note that @code{assoc} never sees the dummy record. @code{Assoc} returns the +record that has the given key as its @code{car}.@footnote{Because @code{assoc} +uses @code{equal?}, it can recognize keys that are symbols, numbers, or list +structure.} @code{Lookup} then checks to see that the resulting record +returned by @code{assoc} is not false, and returns the value (the @code{cdr}) of the record. @lisp @@ -17024,16 +17024,16 @@ of the record. @end lisp @noindent -To insert a value in a table under a specified key, we first use @t{assoc} +To insert a value in a table under a specified key, we first use @code{assoc} to see if there is already a record in the table with this key. If not, we -form a new record by @t{cons}ing the key with the value, and insert this at +form a new record by @code{cons}ing the key with the value, and insert this at the head of the table's list of records, after the dummy record. If there -already is a record with this key, we set the @t{cdr} of this record to the +already is a record with this key, we set the @code{cdr} of this record to the designated new value. The header of the table provides us with a fixed location to modify in order to insert the new record.@footnote{Thus, the first backbone pair is the object that represents the table ``itself''; that is, a pointer to the table is a pointer to this pair. This same backbone pair always -starts the table. If we did not arrange things in this way, @t{insert!} +starts the table. If we did not arrange things in this way, @code{insert!} would have to return a new value for the start of the table when it added a new record.} @@ -17050,7 +17050,7 @@ record.} @noindent To construct a new table, we simply create a list containing the symbol -@t{*table*}: +@code{*table*}: @lisp (define (make-table) @@ -17137,9 +17137,9 @@ Then we use the second key to identify the record within the subtable. @end lisp @noindent -To insert a new item under a pair of keys, we use @t{assoc} to see if there +To insert a new item under a pair of keys, we use @code{assoc} to see if there is a subtable stored under the first key. If not, we build a new subtable -containing the single record (@t{key-2}, @t{value}) and insert it into +containing the single record (@code{key-2}, @code{value}) and insert it into the table under the first key. If a subtable already exists for the first key, we insert the new record into this subtable, using the insertion method for one-dimensional tables described above: @@ -17165,10 +17165,10 @@ one-dimensional tables described above: @subsubheading Creating local tables -The @t{lookup} and @t{insert!} operations defined above take the table as +The @code{lookup} and @code{insert!} operations defined above take the table as an argument. This enables us to use programs that access more than one table. -Another way to deal with multiple tables is to have separate @t{lookup} and -@t{insert!} procedures for each table. We can do this by representing a +Another way to deal with multiple tables is to have separate @code{lookup} and +@code{insert!} procedures for each table. We can do this by representing a table procedurally, as an object that maintains an internal table as part of its local state. When sent an appropriate message, this ``table object'' supplies the procedure with which to operate on the internal table. Here is a @@ -17214,7 +17214,7 @@ generator for two-dimensional tables represented in this fashion: @end lisp @noindent -Using @t{make-table}, we could implement the @t{get} and @t{put} +Using @code{make-table}, we could implement the @code{get} and @code{put} operations used in @ref{2.4.3} for data-directed programming, as follows: @@ -17225,20 +17225,20 @@ follows: @end lisp @noindent -@t{Get} takes as arguments two keys, and @t{put} takes as arguments two +@code{Get} takes as arguments two keys, and @code{put} takes as arguments two keys and a value. Both operations access the same local table, which is -encapsulated within the object created by the call to @t{make-table}. +encapsulated within the object created by the call to @code{make-table}. @quotation @strong{@anchor{Exercise 3.24}Exercise 3.24:} In the table implementations -above, the keys are tested for equality using @t{equal?} (called by -@t{assoc}). This is not always the appropriate test. For instance, we +above, the keys are tested for equality using @code{equal?} (called by +@code{assoc}). This is not always the appropriate test. For instance, we might have a table with numeric keys in which we don't need an exact match to the number we're looking up, but only a number within some tolerance of it. -Design a table constructor @t{make-table} that takes as an argument a -@t{same-key?} procedure that will be used to test ``equality'' of keys. -@t{Make-table} should return a @t{dispatch} procedure that can be used to -access appropriate @t{lookup} and @t{insert!} procedures for a local +Design a table constructor @code{make-table} that takes as an argument a +@code{same-key?} procedure that will be used to test ``equality'' of keys. +@code{Make-table} should return a @code{dispatch} procedure that can be used to +access appropriate @code{lookup} and @code{insert!} procedures for a local table. @end quotation @@ -17246,7 +17246,7 @@ table. @strong{@anchor{Exercise 3.25}Exercise 3.25:} Generalizing one- and two-dimensional tables, show how to implement a table in which values are stored under an arbitrary number of keys and different values may be stored -under different numbers of keys. The @t{lookup} and @t{insert!} +under different numbers of keys. The @code{lookup} and @code{insert!} procedures should take as input a list of keys used to access the table. @end quotation @@ -17309,10 +17309,10 @@ where the memoizer is defined as result)))))) @end lisp -Draw an environment diagram to analyze the computation of @t{(memo-fib 3)}. -Explain why @t{memo-fib} computes the @math{n^{\hbox{\ordrm th}}} Fibonacci number in a number +Draw an environment diagram to analyze the computation of @code{(memo-fib 3)}. +Explain why @code{memo-fib} computes the @math{n^{\hbox{\ordrm th}}} Fibonacci number in a number of steps proportional to @math{n}. Would the scheme still work if we had simply -defined @t{memo-fib} to be @t{(memoize fib)}? +defined @code{memo-fib} to be @code{(memoize fib)}? @end quotation @node 3.3.4, 3.3.5, 3.3.3, 3.3 @@ -17426,7 +17426,7 @@ study. The program will construct computational objects modeling the wires, which will ``hold'' the signals. Function boxes will be modeled by procedures that enforce the correct relationships among the signals. -One basic element of our simulation will be a procedure @t{make-wire}, which +One basic element of our simulation will be a procedure @code{make-wire}, which constructs wires. For example, we can construct six wires as follows: @lisp @@ -17458,7 +17458,7 @@ in @ref{Figure 3.25}: @noindent Better yet, we can explicitly name this operation by defining a procedure -@t{half-adder} that constructs this circuit, given the four external wires +@code{half-adder} that constructs this circuit, given the four external wires to be attached to the half-adder: @lisp @@ -17472,7 +17472,7 @@ to be attached to the half-adder: @end lisp @noindent -The advantage of making this definition is that we can use @t{half-adder} +The advantage of making this definition is that we can use @code{half-adder} itself as a building block in creating more complex circuits. @ref{Figure 3.26}, for example, shows a @newterm{full-adder} composed of two half-adders and an or-gate.@footnote{A full-adder is a basic circuit element used in adding @@ -17521,7 +17521,7 @@ C -----+ +---------------/___/ | @end float @noindent -Having defined @t{full-adder} as a procedure, we can now use it as a +Having defined @code{full-adder} as a procedure, we can now use it as a building block for creating still more complex circuits. (For example, see @ref{Exercise 3.30}.) @@ -17540,17 +17540,17 @@ boxes, we use the following operations on wires: @itemize @bullet -@item @t{(get-signal}@math{\;\;\langle\kern0.06em\hbox{\ttsl wire}\kern0.08em\rangle}@t{)} +@item @code{(get-signal}@math{\;\;\langle\kern0.06em\hbox{\ttsl wire}\kern0.08em\rangle}@code{)} @noindent returns the current value of the signal on the wire. -@item @t{(set-signal!}@math{\;\;\langle\kern0.08em\hbox{\ttsl wire}\kern0.08em\rangle\;\;\langle\kern0.08em\hbox{\ttsl new value}\kern0.08em\rangle}@t{)} +@item @code{(set-signal!}@math{\;\;\langle\kern0.08em\hbox{\ttsl wire}\kern0.08em\rangle\;\;\langle\kern0.08em\hbox{\ttsl new value}\kern0.08em\rangle}@code{)} @noindent changes the value of the signal on the wire to the new value. -@item @t{(add-action!}@math{\;\;\langle\kern0.08em\hbox{\ttsl wire}\kern0.08em\rangle\;\;\langle\kern0.08em\hbox{\ttsl procedure of no arguments}\kern0.02em\rangle}@t{)} +@item @code{(add-action!}@math{\;\;\langle\kern0.08em\hbox{\ttsl wire}\kern0.08em\rangle\;\;\langle\kern0.08em\hbox{\ttsl procedure of no arguments}\kern0.02em\rangle}@code{)} @noindent asserts that the designated procedure should be run whenever the signal on the @@ -17560,16 +17560,16 @@ signal value on the wire are communicated to other wires. @end itemize @noindent -In addition, we will make use of a procedure @t{after-delay} that takes a +In addition, we will make use of a procedure @code{after-delay} that takes a time delay and a procedure to be run and executes the given procedure after the given delay. Using these procedures, we can define the primitive digital logic functions. -To connect an input to an output through an inverter, we use @t{add-action!} +To connect an input to an output through an inverter, we use @code{add-action!} to associate with the input wire a procedure that will be run whenever the signal on the input wire changes value. The procedure computes the -@t{logical-not} of the input signal, and then, after one -@t{inverter-delay}, sets the output signal to be this new value: +@code{logical-not} of the input signal, and then, after one +@code{inverter-delay}, sets the output signal to be this new value: @lisp (define (inverter input output) @@ -17590,10 +17590,10 @@ signal on the input wire changes value. The procedure computes the @noindent An and-gate is a little more complex. The action procedure must be run if -either of the inputs to the gate changes. It computes the @t{logical-and} -(using a procedure analogous to @t{logical-not}) of the values of the +either of the inputs to the gate changes. It computes the @code{logical-and} +(using a procedure analogous to @code{logical-not}) of the values of the signals on the input wires and sets up a change to the new value to occur on -the output wire after one @t{and-gate-delay}. +the output wire after one @code{and-gate-delay}. @lisp (define (and-gate a1 a2 output) @@ -17612,16 +17612,16 @@ the output wire after one @t{and-gate-delay}. @quotation @strong{@anchor{Exercise 3.28}Exercise 3.28:} Define an or-gate as a primitive -function box. Your @t{or-gate} constructor should be similar to -@t{and-gate}. +function box. Your @code{or-gate} constructor should be similar to +@code{and-gate}. @end quotation @quotation @strong{@anchor{Exercise 3.29}Exercise 3.29:} Another way to construct an or-gate is as a compound digital logic device, built from and-gates and -inverters. Define a procedure @t{or-@/gate} that accomplishes this. What is -the delay time of the or-gate in terms of @t{and-@/gate-@/delay} and -@t{inverter-@/delay}? +inverters. Define a procedure @code{or-@/gate} that accomplishes this. What is +the delay time of the or-gate in terms of @code{and-@/gate-@/delay} and +@code{inverter-@/delay}? @end quotation @float @@ -17665,7 +17665,7 @@ numbers. The inputs @math{A_1}, @math{A_2}, @math{A_3}, @dots{}, @math{A_n} and @math{B_k} is a 0 or a 1). The circuit generates @math{S_1}, @math{S_2}, @math{S_3}, @dots{}, @math{S_n}, the @math{n} bits of the sum, and @math{C}, the carry from the addition. Write a -procedure @t{ripple-carry-adder} that generates this circuit. The procedure +procedure @code{ripple-carry-adder} that generates this circuit. The procedure should take as arguments three lists of @math{n} wires each---the @math{A_k}, the @math{B_k}, and the @math{S_k}---and also another wire @math{C}. The major drawback of the ripple-carry adder is the need to wait for the carry signals to propagate. @@ -17677,10 +17677,10 @@ and inverters? @subsubheading Representing wires A wire in our simulation will be a computational object with two local state -variables: a @t{signal-value} (initially taken to be 0) and a collection of -@t{action-procedures} to be run when the signal changes value. We implement +variables: a @code{signal-value} (initially taken to be 0) and a collection of +@code{action-procedures} to be run when the signal changes value. We implement the wire, using message-passing style, as a collection of local procedures -together with a @t{dispatch} procedure that selects the appropriate local +together with a @code{dispatch} procedure that selects the appropriate local operation, just as we did with the simple bank-account object in @ref{3.1.1}: @@ -17712,9 +17712,9 @@ operation, just as we did with the simple bank-account object in @end lisp @noindent -The local procedure @t{set-my-signal!} tests whether the new signal value +The local procedure @code{set-my-signal!} tests whether the new signal value changes the signal on the wire. If so, it runs each of the action procedures, -using the following procedure @t{call-each}, which calls each of the items +using the following procedure @code{call-each}, which calls each of the items in a list of no-argument procedures: @lisp @@ -17726,20 +17726,20 @@ in a list of no-argument procedures: @end lisp @noindent -The local procedure @t{accept-action-procedure!} adds the given procedure to +The local procedure @code{accept-action-procedure!} adds the given procedure to the list of procedures to be run, and then runs the new procedure once. (See @ref{Exercise 3.31}.) -With the local @t{dispatch} procedure set up as specified, we can provide +With the local @code{dispatch} procedure set up as specified, we can provide the following procedures to access the local operations on wires:@footnote{@anchor{Footnote 27} These procedures are simply syntactic sugar that allow us to use ordinary procedural syntax to access the local procedures of objects. It is striking that we can interchange the role of ``procedures'' and ``data'' in such a simple way. For example, if we write -@t{(wire 'get-signal)} we think of @t{wire} as a procedure that is called -with the message @t{get-signal} as input. Alternatively, writing -@t{(get-signal wire)} encourages us to think of @t{wire} as a data object -that is the input to a procedure @t{get-signal}. The truth of the matter is +@code{(wire 'get-signal)} we think of @code{wire} as a procedure that is called +with the message @code{get-signal} as input. Alternatively, writing +@code{(get-signal wire)} encourages us to think of @code{wire} as a data object +that is the input to a procedure @code{get-signal}. The truth of the matter is that, in a language in which we can deal with procedures as objects, there is no fundamental difference between ``procedures'' and ``data,'' and we can choose our syntactic sugar to allow us to program in whatever style we choose.} @@ -17757,8 +17757,8 @@ choose our syntactic sugar to allow us to program in whatever style we choose.} Wires, which have time-varying signals and may be incrementally attached to devices, are typical of mutable objects. We have modeled them as procedures with local state variables that are modified by assignment. When a new wire is -created, a new set of state variables is allocated (by the @t{let} -expression in @t{make-wire}) and a new @t{dispatch} procedure is +created, a new set of state variables is allocated (by the @code{let} +expression in @code{make-wire}) and a new @code{dispatch} procedure is constructed and returned, capturing the environment with the new state variables. @@ -17770,7 +17770,7 @@ connections were established. @subsubheading The agenda -The only thing needed to complete the simulator is @t{after-@/delay}. The +The only thing needed to complete the simulator is @code{after-@/delay}. The idea here is that we maintain a data structure, called an @newterm{agenda}, that contains a schedule of things to do. The following operations are defined for agendas: @@ -17778,31 +17778,31 @@ for agendas: @itemize @bullet @item -@t{(make-agenda)} returns a new empty agenda. +@code{(make-agenda)} returns a new empty agenda. @item -@t{(empty-agenda?}@math{\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} is true if the specified agenda is +@code{(empty-agenda?}@math{\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} is true if the specified agenda is empty. @item -@t{(first-agenda-item}@math{\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} returns the first item on the +@code{(first-agenda-item}@math{\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} returns the first item on the agenda. @item -@t{(remove-first-agenda-item!}@math{\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} modifies the agenda by +@code{(remove-first-agenda-item!}@math{\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} modifies the agenda by removing the first item. @item -@t{(add-to-agenda!}@math{\;\;\langle\kern0.03em\hbox{\ttsl time}\kern0.06em\rangle\;\;\langle\kern0.08em\hbox{\ttsl action}\kern0.06em\rangle\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} modifies the agenda by adding the given action procedure to be run at the specified time. +@code{(add-to-agenda!}@math{\;\;\langle\kern0.03em\hbox{\ttsl time}\kern0.06em\rangle\;\;\langle\kern0.08em\hbox{\ttsl action}\kern0.06em\rangle\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.06em\rangle\hbox{\tt)}} modifies the agenda by adding the given action procedure to be run at the specified time. @item -@t{(current-time}@math{\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.04em\rangle\hbox{\tt)}} returns the current simulation time. +@code{(current-time}@math{\;\;\langle\kern0.08em\hbox{\ttsl agenda}\kern0.04em\rangle\hbox{\tt)}} returns the current simulation time. @end itemize @noindent -The particular agenda that we use is denoted by @t{the-@/agenda}. The -procedure @t{after-@/delay} adds new elements to @t{the-@/agenda}: +The particular agenda that we use is denoted by @code{the-@/agenda}. The +procedure @code{after-@/delay} adds new elements to @code{the-@/agenda}: @lisp (define (after-delay delay action) @@ -17813,10 +17813,10 @@ procedure @t{after-@/delay} adds new elements to @t{the-@/agenda}: @end lisp @noindent -The simulation is driven by the procedure @t{propagate}, which operates on -@t{the-agenda}, executing each procedure on the agenda in sequence. In +The simulation is driven by the procedure @code{propagate}, which operates on +@code{the-agenda}, executing each procedure on the agenda in sequence. In general, as the simulation runs, new items will be added to the agenda, and -@t{propagate} will continue the simulation as long as there are items on the +@code{propagate} will continue the simulation as long as there are items on the agenda: @lisp @@ -17878,7 +17878,7 @@ Now we define four wires, placing probes on two of them: @noindent Next we connect the wires in a half-adder circuit (as in @ref{Figure 3.25}), -set the signal on @t{input-1} to 1, and run the simulation: +set the signal on @code{input-1} to 1, and run the simulation: @lisp (half-adder input-1 input-2 sum carry) @@ -17892,9 +17892,9 @@ set the signal on @t{input-1} to 1, and run the simulation: @end lisp @noindent -The @t{sum} signal changes to 1 at time 8. We are now eight time units from +The @code{sum} signal changes to 1 at time 8. We are now eight time units from the beginning of the simulation. At this point, we can set the signal on -@t{input-2} to 1 and allow the values to propagate: +@code{input-2} to 1 and allow the values to propagate: @lisp (set-signal! input-2 1) @@ -17907,16 +17907,16 @@ the beginning of the simulation. At this point, we can set the signal on @end lisp @noindent -The @t{carry} changes to 1 at time 11 and the @t{sum} changes to 0 at +The @code{carry} changes to 1 at time 11 and the @code{sum} changes to 0 at time 16. @quotation @strong{@anchor{Exercise 3.31}Exercise 3.31:} The internal procedure -@t{accept-@/action-@/procedure!} defined in @t{make-@/wire} specifies that when +@code{accept-@/action-@/procedure!} defined in @code{make-@/wire} specifies that when a new action procedure is added to a wire, the procedure is immediately run. Explain why this initialization is necessary. In particular, trace through the half-adder example in the paragraphs above and say how the system's response -would differ if we had defined @t{accept-@/action-@/procedure!} as +would differ if we had defined @code{accept-@/action-@/procedure!} as @lisp (define (accept-action-procedure! proc) @@ -17952,7 +17952,7 @@ in order of increasing time. In addition, we store the @newterm{current time} agenda. A newly constructed agenda has no time segments and has a current time of 0:@footnote{The agenda is a headed list, like the tables in @ref{3.3.3}, but since the list is headed by the time, we do not need an -additional dummy header (such as the @t{*table*} symbol used with tables).} +additional dummy header (such as the @code{*table*} symbol used with tables).} @lisp (define (make-agenda) (list 0)) @@ -18024,9 +18024,9 @@ agenda, we must create a new time segment at the end. The procedure that removes the first item from the agenda deletes the item at the front of the queue in the first time segment. If this deletion makes the time segment empty, we remove it from the list of segments:@footnote{Observe -that the @t{if} expression in this procedure has no @math{\langle}@var{alternative}@math{\kern0.08em\rangle} -expression. Such a ``one-armed @t{if} statement'' is used to decide whether -to do something, rather than to select between two expressions. An @t{if} +that the @code{if} expression in this procedure has no @math{\langle}@var{alternative}@math{\kern0.08em\rangle} +expression. Such a ``one-armed @code{if} statement'' is used to decide whether +to do something, rather than to select between two expressions. An @code{if} expression returns an unspecified value if the predicate is false and there is no @math{\langle}@var{alternative}@math{\kern0.08em\rangle}.} @@ -18113,10 +18113,10 @@ constraints.} In this section, we sketch the design of a language that enables us to work in terms of relations themselves. The primitive elements of the language are @newterm{primitive constraints}, which state that certain relations hold -between quantities. For example, @t{(adder a b c)} specifies that the +between quantities. For example, @code{(adder a b c)} specifies that the quantities @math{a}, @math{b}, and @math{c} must be related by the equation -@math{a + b = c}, @t{(multiplier x y z)} expresses the constraint -@math{xy = z}, and @t{(constant 3.14 x)} says that the value of @math{x} must be 3.14. +@math{a + b = c}, @code{(multiplier x y z)} expresses the constraint +@math{xy = z}, and @code{(constant 3.14 x)} says that the value of @math{x} must be 3.14. Our language provides a means of combining primitive constraints in order to express more complex relations. We combine constraints by constructing @@ -18192,8 +18192,8 @@ to @math{25 \cdot 9 = 225}. Then @math{u} awakens the second multiplier, which @subsubheading Using the constraint system To use the constraint system to carry out the temperature computation outlined -above, we first create two connectors, @t{C} and @t{F}, by calling the -constructor @t{make-connector}, and link @t{C} and @t{F} in an +above, we first create two connectors, @code{C} and @code{F}, by calling the +constructor @code{make-connector}, and link @code{C} and @code{F} in an appropriate network: @lisp @@ -18223,16 +18223,16 @@ The procedure that creates the network is defined as follows: @end lisp @noindent -This procedure creates the internal connectors @t{u}, @t{v}, @t{w}, -@t{x}, and @t{y}, and links them as shown in @ref{Figure 3.28} using the -primitive constraint constructors @t{adder}, @t{multiplier}, and -@t{constant}. Just as with the digital-circuit simulator of +This procedure creates the internal connectors @code{u}, @code{v}, @code{w}, +@code{x}, and @code{y}, and links them as shown in @ref{Figure 3.28} using the +primitive constraint constructors @code{adder}, @code{multiplier}, and +@code{constant}. Just as with the digital-circuit simulator of @ref{3.3.4}, expressing these combinations of primitive elements in terms of procedures automatically provides our language with a means of abstraction for compound objects. -To watch the network in action, we can place probes on the connectors @t{C} -and @t{F}, using a @t{probe} procedure similar to the one we used to +To watch the network in action, we can place probes on the connectors @code{C} +and @code{F}, using a @code{probe} procedure similar to the one we used to monitor wires in @ref{3.3.4}. Placing a probe on a connector will cause a message to be printed whenever the connector is given a value: @@ -18242,9 +18242,9 @@ cause a message to be printed whenever the connector is given a value: @end lisp @noindent -Next we set the value of @t{C} to 25. (The third argument to -@t{set-value!} tells @t{C} that this directive comes from the -@t{user}.) +Next we set the value of @code{C} to 25. (The third argument to +@code{set-value!} tells @code{C} that this directive comes from the +@code{user}.) @lisp (set-value! C 25 'user) @@ -18254,11 +18254,11 @@ Next we set the value of @t{C} to 25. (The third argument to @end lisp @noindent -The probe on @t{C} awakens and reports the value. @t{C} also propagates -its value through the network as described above. This sets @t{F} to 77, -which is reported by the probe on @t{F}. +The probe on @code{C} awakens and reports the value. @code{C} also propagates +its value through the network as described above. This sets @code{F} to 77, +which is reported by the probe on @code{F}. -Now we can try to set @t{F} to a new value, say 212: +Now we can try to set @code{F} to a new value, say 212: @lisp (set-value! F 212 'user) @@ -18268,7 +18268,7 @@ Now we can try to set @t{F} to a new value, say 212: @noindent The connector complains that it has sensed a contradiction: Its value is 77, and someone is trying to set it to 212. If we really want to reuse the network -with new values, we can tell @t{C} to forget its old value: +with new values, we can tell @code{C} to forget its old value: @lisp (forget-value! C 'user) @@ -18278,14 +18278,14 @@ with new values, we can tell @t{C} to forget its old value: @end lisp @noindent -@t{C} finds that the @t{user}, who set its value originally, is now -retracting that value, so @t{C} agrees to lose its value, as shown by the +@code{C} finds that the @code{user}, who set its value originally, is now +retracting that value, so @code{C} agrees to lose its value, as shown by the probe, and informs the rest of the network of this fact. This information -eventually propagates to @t{F}, which now finds that it has no reason for -continuing to believe that its own value is 77. Thus, @t{F} also gives up +eventually propagates to @code{F}, which now finds that it has no reason for +continuing to believe that its own value is 77. Thus, @code{F} also gives up its value, as shown by the probe. -Now that @t{F} has no value, we are free to set it to 212: +Now that @code{F} has no value, we are free to set it to 212: @lisp (set-value! F 212 'user) @@ -18295,10 +18295,10 @@ Now that @t{F} has no value, we are free to set it to 212: @end lisp @noindent -This new value, when propagated through the network, forces @t{C} to have a -value of 100, and this is registered by the probe on @t{C}. Notice that the -very same network is being used to compute @t{C} given @t{F} and to -compute @t{F} given @t{C}. This nondirectionality of computation is the +This new value, when propagated through the network, forces @code{C} to have a +value of 100, and this is registered by the probe on @code{C}. Notice that the +very same network is being used to compute @code{C} given @code{F} and to +compute @code{F} given @code{C}. This nondirectionality of computation is the distinguishing feature of constraint-based systems. @subsubheading Implementing the constraint system @@ -18314,35 +18314,35 @@ The basic operations on connectors are the following: @itemize @bullet @item -@t{(has-value? <@var{connector}>)} tells whether the connector has a value. +@code{(has-value? <@var{connector}>)} tells whether the connector has a value. @item -@t{(get-value <@var{connector}>)} returns the connector's current value. +@code{(get-value <@var{connector}>)} returns the connector's current value. @item -@t{(set-value! <@var{connector}> <@var{new-value}> <@var{informant}>)} +@code{(set-value! <@var{connector}> <@var{new-value}> <@var{informant}>)} indicates that the informant is requesting the connector to set its value to the new value. @item -@t{(forget-value! <@var{connector}> <@var{retractor}>)} tells the connector +@code{(forget-value! <@var{connector}> <@var{retractor}>)} tells the connector that the retractor is requesting it to forget its value. @item -@t{(connect <@var{connector}> <@var{new-constraint}>)} tells the connector +@code{(connect <@var{connector}> <@var{new-constraint}>)} tells the connector to participate in the new constraint. @end itemize @noindent The connectors communicate with the constraints by means of the procedures -@t{inform-about-value}, which tells the given constraint that the connector -has a value, and @t{inform-about-no-value}, which tells the constraint that +@code{inform-about-value}, which tells the given constraint that the connector +has a value, and @code{inform-about-no-value}, which tells the constraint that the connector has lost its value. -@t{Adder} constructs an adder constraint among summand connectors @t{a1} -and @t{a2} and a @t{sum} connector. An adder is implemented as a -procedure with local state (the procedure @t{me} below): +@code{Adder} constructs an adder constraint among summand connectors @code{a1} +and @code{a2} and a @code{sum} connector. An adder is implemented as a +procedure with local state (the procedure @code{me} below): @lisp (define (adder a1 a2 sum) @@ -18384,8 +18384,8 @@ procedure with local state (the procedure @t{me} below): @end lisp @noindent -@t{Adder} connects the new adder to the designated connectors and returns it -as its value. The procedure @t{me}, which represents the adder, acts as a +@code{Adder} connects the new adder to the designated connectors and returns it +as its value. The procedure @code{me}, which represents the adder, acts as a dispatch to the local procedures. The following ``syntax interfaces'' (see @ref{Footnote 27} in @ref{3.3.4}) are used in conjunction with the dispatch: @@ -18398,23 +18398,23 @@ the dispatch: @end lisp @noindent -The adder's local procedure @t{process-new-value} is called when the adder +The adder's local procedure @code{process-new-value} is called when the adder is informed that one of its connectors has a value. The adder first checks to -see if both @t{a1} and @t{a2} have values. If so, it tells @t{sum} to -set its value to the sum of the two addends. The @t{informant} argument to -@t{set-value!} is @t{me}, which is the adder object itself. If @t{a1} -and @t{a2} do not both have values, then the adder checks to see if perhaps -@t{a1} and @t{sum} have values. If so, it sets @t{a2} to the -difference of these two. Finally, if @t{a2} and @t{sum} have values, -this gives the adder enough information to set @t{a1}. If the adder is told +see if both @code{a1} and @code{a2} have values. If so, it tells @code{sum} to +set its value to the sum of the two addends. The @code{informant} argument to +@code{set-value!} is @code{me}, which is the adder object itself. If @code{a1} +and @code{a2} do not both have values, then the adder checks to see if perhaps +@code{a1} and @code{sum} have values. If so, it sets @code{a2} to the +difference of these two. Finally, if @code{a2} and @code{sum} have values, +this gives the adder enough information to set @code{a1}. If the adder is told that one of its connectors has lost a value, it requests that all of its connectors now lose their values. (Only those values that were set by this -adder are actually lost.) Then it runs @t{process-new-value}. The reason +adder are actually lost.) Then it runs @code{process-new-value}. The reason for this last step is that one or more connectors may still have a value (that is, a connector may have had a value that was not originally set by the adder), and these values may need to be propagated back through the adder. -A multiplier is very similar to an adder. It will set its @t{product} to 0 +A multiplier is very similar to an adder. It will set its @code{product} to 0 if either of the factors is 0, even if the other factor is not known. @lisp @@ -18464,8 +18464,8 @@ if either of the factors is 0, even if the other factor is not known. @end lisp @noindent -A @t{constant} constructor simply sets the value of the designated -connector. Any @t{I-have-a-value} or @t{I-@/lost-@/my-@/value} message sent to +A @code{constant} constructor simply sets the value of the designated +connector. Any @code{I-have-a-value} or @code{I-@/lost-@/my-@/value} message sent to the constant box will produce an error. @lisp @@ -18506,8 +18506,8 @@ the designated connector: @subsubheading Representing connectors A connector is represented as a procedural object with local state variables -@t{value}, the current value of the connector; @t{informant}, the object -that set the connector's value; and @t{constraints}, a list of the +@code{value}, the current value of the connector; @code{informant}, the object +that set the connector's value; and @code{constraints}, a list of the constraints in which the connector participates. @lisp @@ -18560,12 +18560,12 @@ constraints in which the connector participates. @end lisp @noindent -The connector's local procedure @t{set-my-value} is called when there is a +The connector's local procedure @code{set-my-value} is called when there is a request to set the connector's value. If the connector does not currently have -a value, it will set its value and remember as @t{informant} the constraint -that requested the value to be set.@footnote{The @t{setter} might not be a -constraint. In our temperature example, we used @t{user} as the -@t{setter}.} Then the connector will notify all of its participating +a value, it will set its value and remember as @code{informant} the constraint +that requested the value to be set.@footnote{The @code{setter} might not be a +constraint. In our temperature example, we used @code{user} as the +@code{setter}.} Then the connector will notify all of its participating constraints except the constraint that requested the value to be set. This is accomplished using the following iterator, which applies a designated procedure to all items in a list except a given one: @@ -18585,15 +18585,15 @@ to all items in a list except a given one: @noindent If a connector is asked to forget its value, it runs the local procedure -@t{forget-@/my-@/value}, which first checks to make sure that the request is +@code{forget-@/my-@/value}, which first checks to make sure that the request is coming from the same object that set the value originally. If so, the connector informs its associated constraints about the loss of the value. -The local procedure @t{connect} adds the designated new constraint to the +The local procedure @code{connect} adds the designated new constraint to the list of constraints if it is not already in that list. Then, if the connector has a value, it informs the new constraint of this fact. -The connector's procedure @t{me} serves as a dispatch to the other internal +The connector's procedure @code{me} serves as a dispatch to the other internal procedures and also represents the connector as an object. The following procedures provide a syntax interface for the dispatch: @@ -18616,17 +18616,17 @@ procedures provide a syntax interface for the dispatch: @quotation @strong{@anchor{Exercise 3.33}Exercise 3.33:} Using primitive multiplier, -adder, and constant constraints, define a procedure @t{averager} that takes -three connectors @t{a}, @t{b}, and @t{c} as inputs and establishes the -constraint that the value of @t{c} is the average of the values of @t{a} -and @t{b}. +adder, and constant constraints, define a procedure @code{averager} that takes +three connectors @code{a}, @code{b}, and @code{c} as inputs and establishes the +constraint that the value of @code{c} is the average of the values of @code{a} +and @code{b}. @end quotation @quotation @strong{@anchor{Exercise 3.34}Exercise 3.34:} Louis Reasoner wants to build a squarer, a constraint device with two terminals such that the value of -connector @t{b} on the second terminal will always be the square of the -value @t{a} on the first terminal. He proposes the following simple device +connector @code{b} on the second terminal will always be the square of the +value @code{a} on the first terminal. He proposes the following simple device made from a multiplier: @lisp @@ -18669,7 +18669,7 @@ sequence of expressions in the global environment: (set-value! a 10 'user) @end lisp -At some time during evaluation of the @t{set-value!}, the following +At some time during evaluation of the @code{set-value!}, the following expression from the connector's local procedure is evaluated: @lisp @@ -18683,7 +18683,7 @@ expression is evaluated. @quotation @strong{@anchor{Exercise 3.37}Exercise 3.37:} The -@t{celsius-fahrenheit-converter} procedure is cumbersome when compared with +@code{celsius-fahrenheit-converter} procedure is cumbersome when compared with a more expression-oriented style of definition, such as @lisp @@ -18696,8 +18696,8 @@ a more expression-oriented style of definition, such as (define F (celsius-fahrenheit-converter C)) @end lisp -Here @t{c+}, @t{c*}, etc. are the ``constraint'' versions of the -arithmetic operations. For example, @t{c+} takes two connectors as +Here @code{c+}, @code{c*}, etc. are the ``constraint'' versions of the +arithmetic operations. For example, @code{c+} takes two connectors as arguments and returns a connector that is related to these by an adder constraint: @@ -18708,7 +18708,7 @@ constraint: z)) @end lisp -Define analogous procedures @t{c-}, @t{c*}, @t{c/}, and @t{cv} +Define analogous procedures @code{c-}, @code{c*}, @code{c/}, and @code{cv} (constant value) that enable us to define compound constraints as in the converter example above.@footnote{The expression-oriented format is convenient because it avoids the need to name the intermediate expressions in a @@ -18726,8 +18726,8 @@ vector arguments but do not themselves return vectors as values: @end lisp Alternatively, we could deal with expressions, using procedures that return -vectors as values, and thus avoid explicitly mentioning @t{temp1} and -@t{temp2}: +vectors as values, and thus avoid explicitly mentioning @code{temp1} and +@code{temp2}: @lisp (define answer @@ -18743,7 +18743,7 @@ imperative style when manipulating compound objects. Given the advantage of the expression-oriented format, one might ask if there is any reason to have implemented the system in imperative style, as we did in this section. One reason is that the non-expression-oriented constraint language provides a -handle on constraint objects (e.g., the value of the @t{adder} procedure) as +handle on constraint objects (e.g., the value of the @code{adder} procedure) as well as on connector objects. This is useful if we wish to extend the system with new operations that communicate with constraints directly rather than only indirectly via operations on connectors. Although it is easy to implement the @@ -18779,7 +18779,7 @@ of @ref{3.1.1}: @noindent Here successive evaluations of the same expression yield different values. This behavior arises from the fact that the execution of assignment statements -(in this case, assignments to the variable @t{balance}) delineates +(in this case, assignments to the variable @code{balance}) delineates @newterm{moments in time} when values change. The result of evaluating an expression depends not only on the expression itself, but also on whether the evaluation occurs before or after these moments. Building models in terms of @@ -18835,7 +18835,7 @@ $65 in the account. Depending on the order of the two withdrawals, the sequence of balances in the account is either @math{\,\$100 \to \$90 \to \$65\,} or @math{\,\$100 \to \$75 \to \$65\,}. In a computer implementation of the banking system, this changing sequence of balances could be modeled by successive assignments to a variable -@t{balance}. +@code{balance}. In complex situations, however, such a view can be problematic. Suppose that Peter and Paul, and other people besides, are accessing the same bank account @@ -18847,7 +18847,7 @@ machines. This indeterminacy in the order of events can pose serious problems in the design of concurrent systems. For instance, suppose that the withdrawals made by Peter and Paul are implemented as two separate processes sharing a common -variable @t{balance}, each process specified by the procedure given in +variable @code{balance}, each process specified by the procedure given in @ref{3.1.1}: @lisp @@ -18875,10 +18875,10 @@ Things can be worse still. Consider the expression @noindent executed as part of each withdrawal process. This consists of three steps: (1) -accessing the value of the @t{balance} variable; (2) computing the new -balance; (3) setting @t{balance} to this new value. If Peter and Paul's +accessing the value of the @code{balance} variable; (2) computing the new +balance; (3) setting @code{balance} to this new value. If Peter and Paul's withdrawals execute this statement concurrently, then the two withdrawals might -interleave the order in which they access @t{balance} and set it to the new +interleave the order in which they access @code{balance} and set it to the new value. @float @@ -18933,16 +18933,16 @@ in two banking withdrawals can lead to an incorrect final balance. @noindent The timing diagram in @ref{Figure 3.29} depicts an order of events where -@t{balance} starts at 100, Peter withdraws 10, Paul withdraws 25, and yet -the final value of @t{balance} is 75. As shown in the diagram, the reason -for this anomaly is that Paul's assignment of 75 to @t{balance} is made -under the assumption that the value of @t{balance} to be decremented is 100. -That assumption, however, became invalid when Peter changed @t{balance} to +@code{balance} starts at 100, Peter withdraws 10, Paul withdraws 25, and yet +the final value of @code{balance} is 75. As shown in the diagram, the reason +for this anomaly is that Paul's assignment of 75 to @code{balance} is made +under the assumption that the value of @code{balance} to be decremented is 100. +That assumption, however, became invalid when Peter changed @code{balance} to 90. This is a catastrophic failure for the banking system, because the total amount of money in the system is not conserved. Before the transactions, the total amount of money was $100. Afterwards, Peter has $10, Paul has $25, and the bank has $75.@footnote{An even worse failure for this system could occur if -the two @t{set!} operations attempt to change the balance simultaneously, in +the two @code{set!} operations attempt to change the balance simultaneously, in which case the actual data appearing in memory might end up being a random combination of the information being written by the two processes. Most computers have interlocks on the primitive memory-write operations, which @@ -18967,7 +18967,7 @@ just before the moment of change, the balance is still what he thought it was. The above example typifies the subtle bugs that can creep into concurrent programs. The root of this complexity lies in the assignments to variables that are shared among the different processes. We already know that we must be -careful in writing programs that use @t{set!}, because the results of a +careful in writing programs that use @code{set!}, because the results of a computation depend on the order in which the assignments occur.@footnote{The factorial program in @ref{3.1.3} illustrates this for a single sequential process.} With concurrent processes we must be especially careful @@ -19085,7 +19085,7 @@ Mary: (set! balance (- balance @enumerate a @item -List all the different possible values for @t{balance} after these three +List all the different possible values for @code{balance} after these three transactions have been completed, assuming that the banking system forces the three processes to run sequentially in some order. @@ -19153,7 +19153,7 @@ changed between an access and the corresponding assignment. @subsubheading Serializers in Scheme To make the above mechanism more concrete, suppose that we have extended Scheme -to include a procedure called @t{parallel-execute}: +to include a procedure called @code{parallel-execute}: @lisp (parallel-execute @math{\langle}@math{p_1}@math{\rangle} @@ -19163,14 +19163,14 @@ to include a procedure called @t{parallel-execute}: @end lisp @noindent -Each @math{\langle}@math{p}@math{\kern0.08em\rangle} must be a procedure of no arguments. @t{Parallel-@/execute} +Each @math{\langle}@math{p}@math{\kern0.08em\rangle} must be a procedure of no arguments. @code{Parallel-@/execute} creates a separate process for each @math{\langle}@math{p}@math{\kern0.08em\rangle}, which applies @math{\langle}@math{p}@math{\kern0.08em\rangle} (to no arguments). These processes all run -concurrently.@footnote{@t{Parallel-execute} is not part of standard Scheme, +concurrently.@footnote{@code{Parallel-execute} is not part of standard Scheme, but it can be implemented in @acronym{MIT} Scheme. In our implementation, the new concurrent processes also run concurrently with the original Scheme process. Also, in our implementation, the value returned by -@t{parallel-execute} is a special control object that can be used to halt +@code{parallel-execute} is a special control object that can be used to halt the newly created processes.} As an example of how this is used, consider @@ -19182,29 +19182,29 @@ As an example of how this is used, consider @end lisp @noindent -This creates two concurrent processes---@math{P_1}, which sets @t{x} to -@t{x} times @t{x}, and @math{P_2}, which increments @t{x}. After -execution is complete, @t{x} will be left with one of five possible values, +This creates two concurrent processes---@math{P_1}, which sets @code{x} to +@code{x} times @code{x}, and @math{P_2}, which increments @code{x}. After +execution is complete, @code{x} will be left with one of five possible values, depending on the interleaving of the events of @math{P_1} and @math{P_2}: @example -101: @math{P_1} sets @t{x} to 100 and then @math{P_2} increments - @t{x} to 101. -121: @math{P_2} increments @t{x} to 11 and then @math{P_1} sets - @t{x} to @t{x} times @t{x}. -110: @math{P_2} changes @t{x} from 10 to 11 between the +101: @math{P_1} sets @code{x} to 100 and then @math{P_2} increments + @code{x} to 101. +121: @math{P_2} increments @code{x} to 11 and then @math{P_1} sets + @code{x} to @code{x} times @code{x}. +110: @math{P_2} changes @code{x} from 10 to 11 between the two times that @math{P_1} accesses the value of - @t{x} during the evaluation of @t{(* x x)}. - 11: @math{P_2} accesses @t{x}, then @math{P_1} sets @t{x} to 100, - then @math{P_2} sets @t{x}. -100: @math{P_1} accesses @t{x} (twice), then @math{P_2} sets - @t{x} to 11, then @math{P_1} sets @t{x}. + @code{x} during the evaluation of @code{(* x x)}. + 11: @math{P_2} accesses @code{x}, then @math{P_1} sets @code{x} to 100, + then @math{P_2} sets @code{x}. +100: @math{P_1} accesses @code{x} (twice), then @math{P_2} sets + @code{x} to 11, then @math{P_1} sets @code{x}. @end example @noindent We can constrain the concurrency by using serialized procedures, which are created by @newterm{serializers}. Serializers are constructed by -@t{make-serializer}, whose implementation is given below. A serializer +@code{make-serializer}, whose implementation is given below. A serializer takes a procedure as argument and returns a serialized procedure that behaves like the original procedure. All calls to a given serializer return serialized procedures in the same set. @@ -19220,11 +19220,11 @@ Thus, in contrast to the example above, executing @end lisp @noindent -can produce only two possible values for @t{x}, 101 or 121. The other +can produce only two possible values for @code{x}, 101 or 121. The other possibilities are eliminated, because the execution of @math{P_1} and @math{P_2} cannot be interleaved. -Here is a version of the @t{make-account} procedure from +Here is a version of the @code{make-account} procedure from @ref{3.1.1}, where the deposits and withdrawals have been serialized: @lisp @@ -19278,7 +19278,7 @@ as follows: @quotation @strong{@anchor{Exercise 3.40}Exercise 3.40:} Give all possible values of -@t{x} that can result from executing +@code{x} that can result from executing @lisp (define x 10) @@ -19342,9 +19342,9 @@ Ben's concern? @quotation @strong{@anchor{Exercise 3.42}Exercise 3.42:} Ben Bitdiddle suggests that it's a waste of time to create a new serialized procedure in response to every -@t{withdraw} and @t{deposit} message. He says that @t{make-account} -could be changed so that the calls to @t{protected} are done outside the -@t{dispatch} procedure. That is, an account would return the same +@code{withdraw} and @code{deposit} message. He says that @code{make-account} +could be changed so that the calls to @code{protected} are done outside the +@code{dispatch} procedure. That is, an account would return the same serialized procedure (which was created at the same time as the account) each time it is asked for a withdrawal procedure. @@ -19379,7 +19379,7 @@ time it is asked for a withdrawal procedure. @end lisp Is this a safe change to make? In particular, is there any difference in what -concurrency is allowed by these two versions of @t{make-account} ? +concurrency is allowed by these two versions of @code{make-account} ? @end quotation @subsubheading Complexity of using multiple shared resources @@ -19395,8 +19395,8 @@ To illustrate one of the difficulties that can arise, suppose we wish to swap the balances in two bank accounts. We access each account to find the balance, compute the difference between the balances, withdraw this difference from one account, and deposit it in the other account. We could implement this as -follows:@footnote{We have simplified @t{exchange} by exploiting the fact -that our @t{deposit} message accepts negative amounts. (This is a serious +follows:@footnote{We have simplified @code{exchange} by exploiting the fact +that our @code{deposit} message accepts negative amounts. (This is a serious bug in our banking system!)} @lisp @@ -19412,8 +19412,8 @@ This procedure works well when only a single process is trying to do the exchange. Suppose, however, that Peter and Paul both have access to accounts @math{a}1, @math{a}2, and @math{a}3, and that Peter exchanges @math{a}1 and @math{a}2 while Paul concurrently exchanges @math{a}1 and @math{a}3. Even with account deposits and -withdrawals serialized for individual accounts (as in the @t{make-account} -procedure shown above in this section), @t{exchange} can still produce +withdrawals serialized for individual accounts (as in the @code{make-account} +procedure shown above in this section), @code{exchange} can still produce incorrect results. For example, Peter might compute the difference in the balances for @math{a}1 and @math{a}2, but then Paul might change the balance in @math{a}1 before Peter is able to complete the exchange.@footnote{If the account @@ -19421,14 +19421,14 @@ balances start out as $10, $20, and $30, then after any number of concurrent exchanges, the balances should still be $10, $20, and $30 in some order. Serializing the deposits to individual accounts is not sufficient to guarantee this. See @ref{Exercise 3.43}.} For correct behavior, we must arrange for the -@t{exchange} procedure to lock out any other concurrent accesses to the +@code{exchange} procedure to lock out any other concurrent accesses to the accounts during the entire time of the exchange. One way we can accomplish this is by using both accounts' serializers to -serialize the entire @t{exchange} procedure. To do this, we will arrange +serialize the entire @code{exchange} procedure. To do this, we will arrange for access to an account's serializer. Note that we are deliberately breaking the modularity of the bank-account object by exposing the serializer. The -following version of @t{make-account} is identical to the original version +following version of @code{make-account} is identical to the original version given in @ref{3.1.1}, except that a serializer is provided to protect the balance variable, and the serializer is exported via message passing: @@ -19473,7 +19473,7 @@ are no longer automatically serialized by the account.} @noindent Exporting the serializer in this way gives us enough flexibility to implement a -serialized exchange program. We simply serialize the original @t{exchange} +serialized exchange program. We simply serialize the original @code{exchange} procedure with the serializers for both accounts: @lisp @@ -19494,7 +19494,7 @@ should be $10, $20, and $30 in some order. Draw a timing diagram like the one in @ref{Figure 3.29} to show how this condition can be violated if the exchanges are implemented using the first version of the account-exchange program in this section. On the other hand, argue that even with this -@t{exchange} program, the sum of the balances in the accounts will be +@code{exchange} program, the sum of the balances in the accounts will be preserved. Draw a timing diagram to show how even this condition would be violated if we did not serialize the transactions on individual accounts. @end quotation @@ -19505,7 +19505,7 @@ transferring an amount from one account to another. Ben Bitdiddle claims that this can be accomplished with the following procedure, even if there are multiple people concurrently transferring money among multiple accounts, using any account mechanism that serializes deposit and withdrawal transactions, for -example, the version of @t{make-account} in the text above. +example, the version of @code{make-account} in the text above. @lisp (define @@ -19518,16 +19518,16 @@ Louis Reasoner claims that there is a problem here, and that we need to use a more sophisticated method, such as the one required for dealing with the exchange problem. Is Louis right? If not, what is the essential difference between the transfer problem and the exchange problem? (You should assume that -the balance in @t{from-account} is at least @t{amount}.) +the balance in @code{from-account} is at least @code{amount}.) @end quotation @quotation @strong{@anchor{Exercise 3.45}Exercise 3.45:} Louis Reasoner thinks our bank-account system is unnecessarily complex and error-prone now that deposits and withdrawals aren't automatically serialized. He suggests that -@t{make-@/account-@/and-@/serializer} should have exported the serializer (for use -by such procedures as @t{serialized-@/exchange}) in addition to (rather than -instead of) using it to serialize accounts and deposits as @t{make-@/account} +@code{make-@/account-@/and-@/serializer} should have exported the serializer (for use +by such procedures as @code{serialized-@/exchange}) in addition to (rather than +instead of) using it to serialize accounts and deposits as @code{make-@/account} did. He proposes to redefine accounts as follows: @lisp @@ -19559,7 +19559,7 @@ did. He proposes to redefine accounts as follows: dispatch)) @end lisp -Then deposits are handled as with the original @t{make-@/account}: +Then deposits are handled as with the original @code{make-@/account}: @lisp (define (deposit account amount) @@ -19567,7 +19567,7 @@ Then deposits are handled as with the original @t{make-@/account}: @end lisp Explain what is wrong with Louis's reasoning. In particular, consider what -happens when @t{serialized-@/exchange} is called. +happens when @code{serialized-@/exchange} is called. @end quotation @subsubheading Implementing serializers @@ -19589,8 +19589,8 @@ called P and V, from the Dutch words @emph{passeren} (to pass) and systems. Dijkstra's classic exposition (@ref{1968b}) was one of the first to clearly present the issues of concurrency control, and showed how to use semaphores to handle a variety of concurrency problems.} In our implementation, each -serializer has an associated mutex. Given a procedure @t{p}, the serializer -returns a procedure that acquires the mutex, runs @t{p}, and then releases +serializer has an associated mutex. Given a procedure @code{p}, the serializer +returns a procedure that acquires the mutex, runs @code{p}, and then releases the mutex. This ensures that only one of the procedures produced by the serializer can be running at once, which is precisely the serialization property that we need to guarantee. @@ -19615,7 +19615,7 @@ value is false, the mutex is available to be acquired. When the value is true, the mutex is unavailable, and any process that attempts to acquire the mutex must wait. -Our mutex constructor @t{make-mutex} begins by initializing the cell +Our mutex constructor @code{make-mutex} begins by initializing the cell contents to false. To acquire the mutex, we test the cell. If the mutex is available, we set the cell contents to true and proceed. Otherwise, we wait in a loop, attempting to acquire over and over again, until we find that the mutex @@ -19638,8 +19638,8 @@ mutex, we set the cell contents to false. @end lisp @noindent -@t{Test-and-set!} tests the cell and returns the result of the test. In -addition, if the test was false, @t{test-and-set!} sets the cell contents to +@code{Test-and-set!} tests the cell and returns the result of the test. In +addition, if the test was false, @code{test-and-set!} sets the cell contents to true before returning false. We can express this behavior as the following procedure: @@ -19652,23 +19652,23 @@ procedure: @end lisp @noindent -However, this implementation of @t{test-and-set!} does not suffice as it +However, this implementation of @code{test-and-set!} does not suffice as it stands. There is a crucial subtlety here, which is the essential place where -concurrency control enters the system: The @t{test-and-set!} operation must +concurrency control enters the system: The @code{test-and-set!} operation must be performed @newterm{atomically}. That is, we must guarantee that, once a process has tested the cell and found it to be false, the cell contents will actually be set to true before any other process can test the cell. If we do not make this guarantee, then the mutex can fail in a way similar to the bank-account failure in @ref{Figure 3.29}. (See @ref{Exercise 3.46}.) -The actual implementation of @t{test-and-set!} depends on the details of how +The actual implementation of @code{test-and-set!} depends on the details of how our system runs concurrent processes. For example, we might be executing concurrent processes on a sequential processor using a time-slicing mechanism that cycles through the processes, permitting each process to run for a short time before interrupting it and moving on to the next process. In that case, -@t{test-and-set!} can work by disabling time slicing during the testing and +@code{test-and-set!} can work by disabling time slicing during the testing and setting.@footnote{In @acronym{MIT} Scheme for a single processor, which uses a -time-slicing model, @t{test-and-set!} can be implemented as follows: +time-slicing model, @code{test-and-set!} can be implemented as follows: @lisp (define (test-and-set! cell) @@ -19680,7 +19680,7 @@ time-slicing model, @t{test-and-set!} can be implemented as follows: false))))) @end lisp -@t{Without-interrupts} disables time-slicing interrupts while its procedure +@code{Without-interrupts} disables time-slicing interrupts while its procedure ar@-gu@-ment is being executed.} Alternatively, multiprocessing computers provide instructions that support atomic operations directly in hardware.@footnote{There are many variants of such instructions---including @@ -19702,7 +19702,7 @@ deciding which to go to first.} @quotation @strong{@anchor{Exercise 3.46}Exercise 3.46:} Suppose that we implement -@t{test-@/and-@/set!} using an ordinary procedure as shown in the text, without +@code{test-@/and-@/set!} using an ordinary procedure as shown in the text, without attempting to make the operation atomic. Draw a timing diagram like the one in @ref{Figure 3.29} to demonstrate how the mutex implementation can fail by allowing two processes to acquire the mutex at the same time. @@ -19721,7 +19721,7 @@ semaphore must wait for release operations. Give implementations of semaphores in terms of mutexes @item -in terms of atomic @t{test-and-set!} operations. +in terms of atomic @code{test-and-set!} operations. @end enumerate @end quotation @@ -19729,7 +19729,7 @@ in terms of atomic @t{test-and-set!} operations. @subsubheading Deadlock Now that we have seen how to implement serializers, we can see that account -exchanging still has a problem, even with the @t{serialized-exchange} +exchanging still has a problem, even with the @code{serialized-exchange} procedure above. Imagine that Peter attempts to exchange @math{a}1 with @math{a}2 while Paul concurrently attempts to exchange @math{a}2 with @math{a}1. Suppose that Peter's process reaches the point where it has entered a serialized procedure @@ -19743,7 +19743,7 @@ Deadlock is always a danger in systems that provide concurrent access to multiple shared resources. One way to avoid the deadlock in this situation is to give each account a -unique identification number and rewrite @t{serialized-exchange} so that a +unique identification number and rewrite @code{serialized-exchange} so that a process will always attempt to enter a procedure protecting the lowest-numbered account first. Although this method works well for the exchange problem, there are other situations that require more sophisticated deadlock-avoidance @@ -19760,8 +19760,8 @@ used in database management systems, a topic that is treated in detail in @strong{@anchor{Exercise 3.48}Exercise 3.48:} Explain in detail why the deadlock-avoidance method described above, (i.e., the accounts are numbered, and each process attempts to acquire the smaller-numbered account first) avoids -deadlock in the exchange problem. Rewrite @t{serialized-exchange} to -incorporate this idea. (You will also need to modify @t{make-account} so +deadlock in the exchange problem. Rewrite @code{serialized-exchange} to +incorporate this idea. (You will also need to modify @code{make-account} so that each account is created with a number, which can be accessed by sending an appropriate message.) @end quotation @@ -19783,7 +19783,7 @@ achieve this control through judicious use of serializers. But the problems of concurrency lie deeper than this, because, from a fundamental point of view, it's not always clear what is meant by ``shared state.'' -Mechanisms such as @t{test-and-set!} require processes to examine a global +Mechanisms such as @code{test-and-set!} require processes to examine a global shared flag at arbitrary times. This is problematic and inefficient to implement in modern high-speed processors, where due to optimization techniques such as pipelining and cached memory, the contents of memory may not be in a @@ -19895,8 +19895,8 @@ more modular and more easily maintained systems remains open. As we saw in @ref{2.2.3}, sequences can serve as standard interfaces for combining program modules. We formulated powerful abstractions for -manipulating sequences, such as @t{map}, @t{filter}, and -@t{accumulate}, that capture a wide variety of operations in a manner that +manipulating sequences, such as @code{map}, @code{filter}, and +@code{accumulate}, that capture a wide variety of operations in a manner that is both succinct and elegant. Unfortunately, if we represent sequences as lists, this elegance is bought at @@ -19907,7 +19907,7 @@ transformations of lists, our programs must construct and copy data structures To see why this is true, let us compare two programs for computing the sum of all the prime numbers in an interval. The first program is written in standard -iterative style:@footnote{Assume that we have a predicate @t{prime?} (e.g., +iterative style:@footnote{Assume that we have a predicate @code{prime?} (e.g., as in @ref{1.2.6}) that tests for primality.} @lisp @@ -19936,9 +19936,9 @@ of @ref{2.2.3}: @noindent In carrying out the computation, the first program needs to store only the sum being accumulated. In contrast, the filter in the second program cannot do any -testing until @t{enumerate-interval} has constructed a complete list of the +testing until @code{enumerate-interval} has constructed a complete list of the numbers in the interval. The filter generates another list, which in turn is -passed to @t{accumulate} before being collapsed to form a sum. Such large +passed to @code{accumulate} before being collapsed to form a sum. Such large intermediate storage is not needed by the first program, which we can think of as enumerating the interval incrementally, adding each prime to the sum as it is generated. @@ -19976,8 +19976,8 @@ to automatically and transparently interleave the construction of the stream with its use. On the surface, streams are just lists with different names for the procedures -that manipulate them. There is a constructor, @t{cons-stream}, and two -selectors, @t{stream-car} and @t{stream-cdr}, which satisfy the +that manipulate them. There is a constructor, @code{cons-stream}, and two +selectors, @code{stream-car} and @code{stream-cdr}, which satisfy the constraints @example @@ -19986,15 +19986,15 @@ constraints @end example @noindent -There is a distinguishable object, @t{the-empty-stream}, which cannot be the -result of any @t{cons-stream} operation, and which can be identified with -the predicate @t{stream-null?}.@footnote{In the @acronym{MIT} -implementation, @t{the-empty-stream} is the same as the empty list -@t{'()}, and @t{stream-null?} is the same as @t{null?}.} Thus we can +There is a distinguishable object, @code{the-empty-stream}, which cannot be the +result of any @code{cons-stream} operation, and which can be identified with +the predicate @code{stream-null?}.@footnote{In the @acronym{MIT} +implementation, @code{the-empty-stream} is the same as the empty list +@code{'()}, and @code{stream-null?} is the same as @code{null?}.} Thus we can make and use streams, in just the same way as we can make and use lists, to represent aggregate data arranged in a sequence. In particular, we can build stream analogs of the list operations from @ref{Chapter 2}, such as -@t{list-ref}, @t{map}, and @t{for-each}:@footnote{This should bother +@code{list-ref}, @code{map}, and @code{for-each}:@footnote{This should bother you. The fact that we are defining such similar procedures for streams and lists indicates that we are missing some underlying abstraction. Unfortunately, in order to exploit this abstraction, we will need to exert @@ -20023,7 +20023,7 @@ discuss this point further at the end of @ref{3.5.4}. In @end lisp @noindent -@t{Stream-for-each} is useful for viewing streams: +@code{Stream-for-each} is useful for viewing streams: @lisp (define (display-stream s) @@ -20036,9 +20036,9 @@ discuss this point further at the end of @ref{3.5.4}. In @noindent To make the stream implementation automatically and transparently interleave -the construction of a stream with its use, we will arrange for the @t{cdr} -of a stream to be evaluated when it is accessed by the @t{stream-cdr} -procedure rather than when the stream is constructed by @t{cons-stream}. +the construction of a stream with its use, we will arrange for the @code{cdr} +of a stream to be evaluated when it is accessed by the @code{stream-cdr} +procedure rather than when the stream is constructed by @code{cons-stream}. This implementation choice is reminiscent of our discussion of rational numbers in @ref{2.1.2}, where we saw that we can choose to implement rational numbers so that the reduction of numerator and denominator to lowest terms is @@ -20047,21 +20047,21 @@ rational-number implementations produce the same data abstraction, but the choice has an effect on efficiency. There is a similar relationship between streams and ordinary lists. As a data abstraction, streams are the same as lists. The difference is the time at which the elements are evaluated. With -ordinary lists, both the @t{car} and the @t{cdr} are evaluated at -construction time. With streams, the @t{cdr} is evaluated at selection +ordinary lists, both the @code{car} and the @code{cdr} are evaluated at +construction time. With streams, the @code{cdr} is evaluated at selection time. Our implementation of streams will be based on a special form called -@t{delay}. Evaluating @t{(delay <@var{exp}>)} does not evaluate the +@code{delay}. Evaluating @code{(delay <@var{exp}>)} does not evaluate the expression @math{\langle}@var{exp}@math{\kern0.08em\rangle}, but rather returns a so-called @newterm{delayed object}, which we can think of as a ``promise'' to evaluate @math{\langle}@var{exp}@math{\kern0.08em\rangle} at some -future time. As a companion to @t{delay}, there is a procedure called -@t{force} that takes a delayed object as argument and performs the -evaluation---in effect, forcing the @t{delay} to fulfill its promise. We -will see below how @t{delay} and @t{force} can be implemented, but first +future time. As a companion to @code{delay}, there is a procedure called +@code{force} that takes a delayed object as argument and performs the +evaluation---in effect, forcing the @code{delay} to fulfill its promise. We +will see below how @code{delay} and @code{force} can be implemented, but first let us use these to construct streams. -@t{Cons-stream} is a special form defined so that +@code{Cons-stream} is a special form defined so that @lisp (cons-stream @math{\langle}@var{a}@math{\rangle} @math{\langle}@var{b}@math{\rangle}) @@ -20076,9 +20076,9 @@ is equivalent to @noindent What this means is that we will construct streams using pairs. However, rather -than placing the value of the rest of the stream into the @t{cdr} of the +than placing the value of the rest of the stream into the @code{cdr} of the pair we will put there a promise to compute the rest if it is ever requested. -@t{Stream-car} and @t{stream-cdr} can now be defined as procedures: +@code{Stream-car} and @code{stream-cdr} can now be defined as procedures: @lisp (define (stream-car stream) @@ -20089,15 +20089,15 @@ pair we will put there a promise to compute the rest if it is ever requested. @end lisp @noindent -@t{Stream-car} selects the @t{car} of the pair; @t{stream-cdr} selects -the @t{cdr} of the pair and evaluates the delayed expression found there to -obtain the rest of the stream.@footnote{Although @t{stream-car} and -@t{stream-cdr} can be defined as procedures, @t{cons-stream} must be a -special form. If @t{cons-stream} were a procedure, then, according to our -model of evaluation, evaluating @t{(cons-stream <@var{a}> <@var{b}>)} would +@code{Stream-car} selects the @code{car} of the pair; @code{stream-cdr} selects +the @code{cdr} of the pair and evaluates the delayed expression found there to +obtain the rest of the stream.@footnote{Although @code{stream-car} and +@code{stream-cdr} can be defined as procedures, @code{cons-stream} must be a +special form. If @code{cons-stream} were a procedure, then, according to our +model of evaluation, evaluating @code{(cons-stream <@var{a}> <@var{b}>)} would automatically cause @math{\langle}@var{b}@math{\kern0.08em\rangle} to be evaluated, which is precisely what we do -not want to happen. For the same reason, @t{delay} must be a special form, -though @t{force} can be an ordinary procedure.} +not want to happen. For the same reason, @code{delay} must be a special form, +though @code{force} can be an ordinary procedure.} @subsubheading The stream implementation in action @@ -20115,9 +20115,9 @@ computation we saw above, reformulated in terms of streams: @noindent We will see that it does indeed work efficiently. -We begin by calling @t{stream-enumerate-interval} with the arguments 10,000 -and 1,000,000. @t{Stream-@/enumerate-@/interval} is the stream analog of -@t{enumerate-interval} (@ref{2.2.3}): +We begin by calling @code{stream-enumerate-interval} with the arguments 10,000 +and 1,000,000. @code{Stream-@/enumerate-@/interval} is the stream analog of +@code{enumerate-interval} (@ref{2.2.3}): @lisp (define (stream-enumerate-interval low high) @@ -20130,12 +20130,12 @@ and 1,000,000. @t{Stream-@/enumerate-@/interval} is the stream analog of @end lisp @noindent -and thus the result returned by @t{stream-enumerate-inter-@/val}, formed by the -@t{cons-stream}, is@footnote{The numbers shown here do not really appear in +and thus the result returned by @code{stream-enumerate-inter-@/val}, formed by the +@code{cons-stream}, is@footnote{The numbers shown here do not really appear in the delayed expression. What actually appears is the original expression, in an environment in which the variables are bound to the appropriate numbers. -For example, @t{(+ low 1)} with @t{low} bound to 10,000 actually appears -where @t{10001} is shown.} +For example, @code{(+ low 1)} with @code{low} bound to 10,000 actually appears +where @code{10001} is shown.} @lisp (cons 10000 @@ -20146,10 +20146,10 @@ where @t{10001} is shown.} @end lisp @noindent -That is, @t{stream-enumerate-interval} returns a stream represented as a -pair whose @t{car} is 10,000 and whose @t{cdr} is a promise to enumerate +That is, @code{stream-enumerate-interval} returns a stream represented as a +pair whose @code{car} is 10,000 and whose @code{cdr} is a promise to enumerate more of the interval if so requested. This stream is now filtered for primes, -using the stream analog of the @t{filter} procedure (@ref{2.2.3}): +using the stream analog of the @code{filter} procedure (@ref{2.2.3}): @lisp (define (stream-filter pred stream) @@ -20167,11 +20167,11 @@ using the stream analog of the @t{filter} procedure (@ref{2.2.3}): @end lisp @noindent -@t{Stream-filter} tests the @t{stream-car} of the stream (the @t{car} -of the pair, which is 10,000). Since this is not prime, @t{stream-filter} -examines the @t{stream-cdr} of its input stream. The call to -@t{stream-cdr} forces evaluation of the delayed -@t{stream-@/enumerate-@/interval}, which now returns +@code{Stream-filter} tests the @code{stream-car} of the stream (the @code{car} +of the pair, which is 10,000). Since this is not prime, @code{stream-filter} +examines the @code{stream-cdr} of its input stream. The call to +@code{stream-cdr} forces evaluation of the delayed +@code{stream-@/enumerate-@/interval}, which now returns @lisp (cons 10001 @@ -20182,10 +20182,10 @@ examines the @t{stream-cdr} of its input stream. The call to @end lisp @noindent -@t{Stream-filter} now looks at the @t{stream-car} of this stream, 10,001, -sees that this is not prime either, forces another @t{stream-cdr}, and so -on, until @t{stream-@/enumerate-@/interval} yields the prime 10,007, whereupon -@t{stream-filter}, according to its definition, returns +@code{Stream-filter} now looks at the @code{stream-car} of this stream, 10,001, +sees that this is not prime either, forces another @code{stream-cdr}, and so +on, until @code{stream-@/enumerate-@/interval} yields the prime 10,007, whereupon +@code{stream-filter}, according to its definition, returns @lisp (cons-stream @@ -20208,10 +20208,10 @@ which in this case is @end lisp @noindent -This result is now passed to @t{stream-cdr} in our original expression. -This forces the delayed @t{stream-filter}, which in turn keeps forcing the -delayed @t{stream-@/enumerate-@/interval} until it finds the next prime, which -is 10,009. Finally, the result passed to @t{stream-car} in our original +This result is now passed to @code{stream-cdr} in our original expression. +This forces the delayed @code{stream-filter}, which in turn keeps forcing the +delayed @code{stream-@/enumerate-@/interval} until it finds the next prime, which +is 10,009. Finally, the result passed to @code{stream-car} in our original expression is @lisp @@ -20226,7 +20226,7 @@ expression is @end lisp @noindent -@t{Stream-car} returns 10,009, and the computation is complete. Only as +@code{Stream-car} returns 10,009, and the computation is complete. Only as many integers were tested for primality as were necessary to find the second prime, and the interval was enumerated only as far as was necessary to feed the prime filter. @@ -20239,13 +20239,13 @@ write procedures as if the streams existed ``all at once'' when, in reality, the computation is performed incrementally, as in traditional programming styles. -@subsubheading Implementing @t{delay} and @t{force} +@subsubheading Implementing @code{delay} and @code{force} -Although @t{delay} and @t{force} may seem like mysterious operations, -their implementation is really quite straightforward. @t{Delay} must +Although @code{delay} and @code{force} may seem like mysterious operations, +their implementation is really quite straightforward. @code{Delay} must package an expression so that it can be evaluated later on demand, and we can accomplish this simply by treating the expression as the body of a procedure. -@t{Delay} can be a special form such that +@code{Delay} can be a special form such that @lisp (delay @math{\langle}@var{exp}@math{\rangle}) @@ -20259,8 +20259,8 @@ is syntactic sugar for @end lisp @noindent -@t{Force} simply calls the procedure (of no arguments) produced by -@t{delay}, so we can implement @t{force} as a procedure: +@code{Force} simply calls the procedure (of no arguments) produced by +@code{delay}, so we can implement @code{force} as a procedure: @lisp (define (force delayed-object) @@ -20268,14 +20268,14 @@ is syntactic sugar for @end lisp @noindent -This implementation suffices for @t{delay} and @t{force} to work as +This implementation suffices for @code{delay} and @code{force} to work as advertised, but there is an important optimization that we can include. In many applications, we end up forcing the same delayed object many times. This can lead to serious inefficiency in recursive programs involving streams. (See @ref{Exercise 3.57}.) The solution is to build delayed objects so that the first time they are forced, they store the value that is computed. Subsequent forcings will simply return the stored value without repeating the computation. -In other words, we implement @t{delay} as a special-purpose memoized +In other words, we implement @code{delay} as a special-purpose memoized procedure similar to the one described in @ref{Exercise 3.27}. One way to accomplish this is to use the following procedure, which takes as argument a procedure (of no arguments) and returns a memoized version of the procedure. @@ -20294,7 +20294,7 @@ subsequent evaluations, it simply returns the result. @end lisp @noindent -@t{Delay} is then defined so that @t{(delay <@var{exp}>)} is equivalent +@code{Delay} is then defined so that @code{(delay <@var{exp}>)} is equivalent to @lisp @@ -20302,13 +20302,13 @@ to @end lisp @noindent -and @t{force} is as defined previously.@footnote{There are many possible +and @code{force} is as defined previously.@footnote{There are many possible implementations of streams other than the one described in this section. Delayed evaluation, which is the key to making streams practical, was inherent in Algol 60's @newterm{call-by-name} parameter-passing method. The use of this mechanism to implement streams was first described by @ref{Landin (1965)}. Delayed evaluation for streams was introduced into Lisp by @ref{Friedman and Wise (1976)}. In -their implementation, @t{cons} always delays evaluating its arguments, so +their implementation, @code{cons} always delays evaluating its arguments, so that lists automatically behave as streams. The memoizing optimization is also known as @newterm{call-by-need}. The Algol community would refer to our original delayed objects as @newterm{call-by-name thunks} and to the optimized @@ -20316,8 +20316,8 @@ versions as @newterm{call-by-need thunks}.} @quotation @strong{@anchor{Exercise 3.50}Exercise 3.50:} Complete the following -definition, which generalizes @t{stream-map} to allow procedures that take -multiple arguments, analogous to @t{map} in @ref{2.2.1}, +definition, which generalizes @code{stream-map} to allow procedures that take +multiple arguments, analogous to @code{map} in @ref{2.2.1}, @ref{Footnote 12}. @lisp @@ -20347,7 +20347,7 @@ its argument after printing it: What does the interpreter print in response to evaluating each expression in the following sequence?@footnote{Exercises such as @ref{Exercise 3.51} and @ref{Exercise 3.52} are valuable for testing our understanding of how -@t{delay} works. On the other hand, intermixing delayed evaluation with +@code{delay} works. On the other hand, intermixing delayed evaluation with printing---and, even worse, with assignment---is extremely confusing, and instructors of courses on computer languages have traditionally tormented their students with examination questions such as the ones in this section. Needless @@ -20393,11 +20393,11 @@ expressions (display-stream z) @end lisp -What is the value of @t{sum} after each of the above expressions is -evaluated? What is the printed response to evaluating the @t{stream-ref} -and @t{display-stream} expressions? Would these responses differ if we had -implemented @t{(delay <@var{exp}>)} simply as @t{(lambda () <@var{exp}>)} -without using the optimization provided by @t{memo-proc}? Explain. +What is the value of @code{sum} after each of the above expressions is +evaluated? What is the printed response to evaluating the @code{stream-ref} +and @code{display-stream} expressions? Would these responses differ if we had +implemented @code{(delay <@var{exp}>)} simply as @code{(lambda () <@var{exp}>)} +without using the optimization provided by @code{memo-proc}? Explain. @end quotation @node 3.5.2, 3.5.3, 3.5.1, 3.5 @@ -20419,13 +20419,13 @@ integers: @end lisp @noindent -This makes sense because @t{integers} will be a pair whose @t{car} is 1 -and whose @t{cdr} is a promise to produce the integers beginning with 2. +This makes sense because @code{integers} will be a pair whose @code{car} is 1 +and whose @code{cdr} is a promise to produce the integers beginning with 2. This is an infinitely long stream, but in any given time we can examine only a finite portion of it. Thus, our programs will never know that the entire infinite stream is not there. -Using @t{integers} we can define other infinite streams, such as the stream +Using @code{integers} we can define other infinite streams, such as the stream of integers that are not divisible by 7: @lisp @@ -20446,7 +20446,7 @@ this stream: @end lisp @noindent -In analogy with @t{integers}, we can define the infinite stream of Fibonacci +In analogy with @code{integers}, we can define the infinite stream of Fibonacci numbers: @lisp @@ -20456,13 +20456,13 @@ numbers: @end lisp @noindent -@t{Fibs} is a pair whose @t{car} is 0 and whose @t{cdr} is a promise -to evaluate @t{(fibgen 1 1)}. When we evaluate this delayed @t{(fibgen 1 -1)}, it will produce a pair whose @t{car} is 1 and whose @t{cdr} is a -promise to evaluate @t{(fibgen 1 2)}, and so on. +@code{Fibs} is a pair whose @code{car} is 0 and whose @code{cdr} is a promise +to evaluate @code{(fibgen 1 1)}. When we evaluate this delayed @code{(fibgen 1 +1)}, it will produce a pair whose @code{car} is 1 and whose @code{cdr} is a +promise to evaluate @code{(fibgen 1 2)}, and so on. For a look at a more exciting infinite stream, we can generalize the -@t{no-sevens} example to construct the infinite stream of prime numbers, +@code{no-sevens} example to construct the infinite stream of prime numbers, using a method known as the @newterm{sieve of Eratosthenes}.@footnote{Eratosthenes, a third-century @acronym{B.C.} Alexandrian Greek philosopher, is famous for giving the first accurate estimate @@ -20478,9 +20478,9 @@ of the integers. This leaves a stream beginning with 3, which is the next prime. Now we filter the multiples of 3 from the rest of this stream. This leaves a stream beginning with 5, which is the next prime, and so on. In other words, we construct the primes by a sieving process, described as follows: To -sieve a stream @t{S}, form a stream whose first element is the first element -of @t{S} and the rest of which is obtained by filtering all multiples of the -first element of @t{S} out of the rest of @t{S} and sieving the +sieve a stream @code{S}, form a stream whose first element is the first element +of @code{S} and the rest of which is obtained by filtering all multiples of the +first element of @code{S} out of the rest of @code{S} and sieving the result. This process is readily described in terms of stream operations: @lisp @@ -20541,41 +20541,41 @@ Now to find a particular prime we need only ask for it: @noindent It is interesting to contemplate the signal-processing system set up by -@t{sieve}, shown in the ``Henderson diagram'' in +@code{sieve}, shown in the ``Henderson diagram'' in @ref{Figure 3.31}.@footnote{We have named these figures after Peter Henderson, who was the first person to show us diagrams of this sort as a way of thinking about stream processing. Each solid line represents a stream of values being transmitted. -The dashed line from the @t{car} to the @t{cons} and the @t{filter} +The dashed line from the @code{car} to the @code{cons} and the @code{filter} indicates that this is a single value rather than a stream.} The input stream -feeds into an ``un@t{cons}er'' that separates the first element of the +feeds into an ``un@code{cons}er'' that separates the first element of the stream from the rest of the stream. The first element is used to construct a divisibility filter, through which the rest is passed, and the output of the filter is fed to another sieve box. Then the original first element is -@t{cons}ed onto the output of the internal sieve to form the output stream. +@code{cons}ed onto the output of the internal sieve to form the output stream. Thus, not only is the stream infinite, but the signal processor is also infinite, because the sieve contains a sieve within it. @subsubheading Defining streams implicitly -The @t{integers} and @t{fibs} streams above were defined by specifying +The @code{integers} and @code{fibs} streams above were defined by specifying ``generating'' procedures that explicitly compute the stream elements one by one. An alternative way to specify streams is to take advantage of delayed evaluation to define streams implicitly. For example, the following expression -defines the stream @t{ones} to be an infinite stream of ones: +defines the stream @code{ones} to be an infinite stream of ones: @lisp (define ones (cons-stream 1 ones)) @end lisp @noindent -This works much like the definition of a recursive procedure: @t{ones} is a -pair whose @t{car} is 1 and whose @t{cdr} is a promise to evaluate -@t{ones}. Evaluating the @t{cdr} gives us again a 1 and a promise to -evaluate @t{ones}, and so on. +This works much like the definition of a recursive procedure: @code{ones} is a +pair whose @code{car} is 1 and whose @code{cdr} is a promise to evaluate +@code{ones}. Evaluating the @code{cdr} gives us again a 1 and a promise to +evaluate @code{ones}, and so on. We can do more interesting things by manipulating streams with operations such -as @t{add-streams}, which produces the elementwise sum of two given -streams:@footnote{This uses the generalized version of @t{stream-map} from +as @code{add-streams}, which produces the elementwise sum of two given +streams:@footnote{This uses the generalized version of @code{stream-map} from @ref{Exercise 3.50}.} @lisp @@ -20592,12 +20592,12 @@ Now we can define the integers as follows: @end lisp @noindent -This defines @t{integers} to be a stream whose first element is 1 and the -rest of which is the sum of @t{ones} and @t{integers}. Thus, the second -element of @t{integers} is 1 plus the first element of @t{integers}, or -2; the third element of @t{integers} is 1 plus the second element of -@t{integers}, or 3; and so on. This definition works because, at any point, -enough of the @t{integers} stream has been generated so that we can feed it +This defines @code{integers} to be a stream whose first element is 1 and the +rest of which is the sum of @code{ones} and @code{integers}. Thus, the second +element of @code{integers} is 1 plus the first element of @code{integers}, or +2; the third element of @code{integers} is 1 plus the second element of +@code{integers}, or 3; and so on. This definition works because, at any point, +enough of the @code{integers} stream has been generated so that we can feed it back into the definition to produce the next integer. We can define the Fibonacci numbers in the same style: @@ -20610,18 +20610,18 @@ We can define the Fibonacci numbers in the same style: @end lisp @noindent -This definition says that @t{fibs} is a stream beginning with 0 and 1, such -that the rest of the stream can be generated by adding @t{fibs} to itself +This definition says that @code{fibs} is a stream beginning with 0 and 1, such +that the rest of the stream can be generated by adding @code{fibs} to itself shifted by one place: @example - 1 1 2 3 5 8 13 21 @dots{} = @t{(stream-cdr fibs)} - 0 1 1 2 3 5 8 13 @dots{} = @t{fibs} -0 1 1 2 3 5 8 13 21 34 @dots{} = @t{fibs} + 1 1 2 3 5 8 13 21 @dots{} = @code{(stream-cdr fibs)} + 0 1 1 2 3 5 8 13 @dots{} = @code{fibs} +0 1 1 2 3 5 8 13 21 34 @dots{} = @code{fibs} @end example @noindent -@t{Scale-stream} is another useful procedure in formulating such stream +@code{Scale-stream} is another useful procedure in formulating such stream definitions. This multiplies each item in a stream by a given constant: @lisp @@ -20668,9 +20668,9 @@ prime (not by just any integer) less than or equal to @math{\sqrt{n}}: @end lisp @noindent -This is a recursive definition, since @t{primes} is defined in terms of the -@t{prime?} predicate, which itself uses the @t{primes} stream. The -reason this procedure works is that, at any point, enough of the @t{primes} +This is a recursive definition, since @code{primes} is defined in terms of the +@code{prime?} predicate, which itself uses the @code{primes} stream. The +reason this procedure works is that, at any point, enough of the @code{primes} stream has been generated to test the primality of the numbers we need to check next. That is, for every @math{n} we test for primality, either @math{n} is not prime (in which case there is a prime already generated that divides it) or @@ -20697,9 +20697,9 @@ describe the elements of the stream defined by @quotation @strong{@anchor{Exercise 3.54}Exercise 3.54:} Define a procedure -@t{mul-streams}, analogous to @t{add-streams}, that produces the +@code{mul-streams}, analogous to @code{add-streams}, that produces the elementwise product of its two input streams. Use this together with the -stream of @t{integers} to complete the following definition of the stream +stream of @code{integers} to complete the following definition of the stream whose @math{n^{\hbox{\ordrm th}}} element (counting from 0) is @math{n + 1} factorial: @lisp @@ -20710,9 +20710,9 @@ whose @math{n^{\hbox{\ordrm th}}} element (counting from 0) is @math{n + 1} fact @quotation @strong{@anchor{Exercise 3.55}Exercise 3.55:} Define a procedure -@t{partial-sums} that takes as argument a stream @math{S} and returns the +@code{partial-sums} that takes as argument a stream @math{S} and returns the stream whose elements are @math{S_0}, @math{S_0 + S_1}, @math{S_0 + S_1 + S_2, \dots}. -For example, @t{(partial-sums integers)} should be the +For example, @code{(partial-sums integers)} should be the stream 1, 3, 6, 10, 15, @dots{}. @end quotation @@ -20723,29 +20723,29 @@ positive integers with no prime factors other than 2, 3, or 5. One obvious way to do this is to simply test each integer in turn to see whether it has any factors other than 2, 3, and 5. But this is very inefficient, since, as the integers get larger, fewer and fewer of them fit the requirement. As an -alternative, let us call the required stream of numbers @t{S} and notice the +alternative, let us call the required stream of numbers @code{S} and notice the following facts about it. @itemize @bullet @item -@t{S} begins with 1. +@code{S} begins with 1. @item -The elements of @t{(scale-stream S 2)} are also -elements of @t{S}. +The elements of @code{(scale-stream S 2)} are also +elements of @code{S}. @item -The same is true for @t{(scale-stream S 3)} -and @t{(scale-stream 5 S)}. +The same is true for @code{(scale-stream S 3)} +and @code{(scale-stream 5 S)}. @item -These are all the elements of @t{S}. +These are all the elements of @code{S}. @end itemize Now all we have to do is combine elements from these sources. For this we -define a procedure @t{merge} that combines two ordered streams into one +define a procedure @code{merge} that combines two ordered streams into one ordered result stream, eliminating repetitions: @lisp @@ -20774,7 +20774,7 @@ ordered result stream, eliminating repetitions: (stream-cdr s2))))))))) @end lisp -Then the required stream may be constructed with @t{merge}, as follows: +Then the required stream may be constructed with @code{merge}, as follows: @lisp (define S (cons-stream 1 (merge @math{\langle}@var{??}@math{\rangle} @math{\langle}@var{??}@math{\rangle}))) @@ -20786,10 +20786,10 @@ Fill in the missing expressions in the places marked @math{\langle}@var{??}@math @quotation @strong{@anchor{Exercise 3.57}Exercise 3.57:} How many additions are performed when we compute the @math{n^{\hbox{\ordrm th}}} Fibonacci number using the definition of -@t{fibs} based on the @t{add-streams} procedure? Show that the number of -additions would be exponentially greater if we had implemented @t{(delay -<@var{exp}>)} simply as @t{(lambda () <@var{exp}>)}, without using the -optimization provided by the @t{memo-proc} procedure described in +@code{fibs} based on the @code{add-streams} procedure? Show that the number of +additions would be exponentially greater if we had implemented @code{(delay +<@var{exp}>)} simply as @code{(lambda () <@var{exp}>)}, without using the +optimization provided by the @code{memo-proc} procedure described in @ref{3.5.1}.@footnote{This exercise shows how call-by-need is closely related to ordinary memoization as described in @ref{Exercise 3.27}. In that exercise, we used assignment to explicitly construct a local table. Our call-by-need @@ -20810,9 +20810,9 @@ stream computed by the following procedure: radix))) @end lisp -(@t{Quotient} is a primitive that returns the integer quotient of two -integers.) What are the successive elements produced by @t{(expand 1 7 -10)}? What is produced by @t{(expand 3 8 10)}? +(@code{Quotient} is a primitive that returns the integer quotient of two +integers.) What are the successive elements produced by @code{(expand 1 7 +10)}? What is produced by @code{(expand 3 8 10)}? @end quotation @quotation @@ -20866,12 +20866,12 @@ c + a_0 x + --- a_1 x^2 + --- a_2 x^3 + --- a_3 x^4 + ... $$ c + a_0 x + {1\over2} a_1 x^2 + {1\over3} a_2 x^3 + {1\over4} a_3 x^4 + \dots, $$ @end tex @noindent -where @math{c} is any constant. Define a procedure @t{integrate-@/series} that +where @math{c} is any constant. Define a procedure @code{integrate-@/series} that takes as input a stream @math{a_0}, @math{a_1}, @math{a_2}, @dots{} representing a power series and returns the stream @math{a_0}, @math{{1\over2}a_1}, @math{{1\over3}a_2}, @dots{} of coefficients of the non-constant terms of the integral of the series. (Since the result has no constant term, it doesn't represent a power series; when we -use @t{integrate-@/series}, we will @t{cons} on the appropriate constant.) +use @code{integrate-@/series}, we will @code{cons} on the appropriate constant.) @item The function @math{x \mapsto e^x} is its own derivative. This implies that @@ -20902,7 +20902,7 @@ negative of sine: @quotation @strong{@anchor{Exercise 3.60}Exercise 3.60:} With power series represented as streams of coefficients as in @ref{Exercise 3.59}, adding series is implemented -by @t{add-streams}. Complete the definition of the following procedure for +by @code{add-streams}. Complete the definition of the following procedure for multiplying series: @lisp @@ -20940,18 +20940,18 @@ $$ \eqalign{ @end tex In other words, @math{X} is the power series whose constant term is 1 and whose higher-order terms are given by the negative of @math{S_R} times @math{X}. Use -this idea to write a procedure @t{invert-unit-series} that computes @math{1 \big/ S} +this idea to write a procedure @code{invert-unit-series} that computes @math{1 \big/ S} for a power series @math{S} with constant term 1. You will need to use -@t{mul-series} from @ref{Exercise 3.60}. +@code{mul-series} from @ref{Exercise 3.60}. @end quotation @quotation @strong{@anchor{Exercise 3.62}Exercise 3.62:} Use the results of @ref{Exercise 3.60} -and @ref{Exercise 3.61} to define a procedure @t{div-series} that -divides two power series. @t{Div-series} should work for any two series, +and @ref{Exercise 3.61} to define a procedure @code{div-series} that +divides two power series. @code{Div-series} should work for any two series, provided that the denominator series begins with a nonzero constant term. (If -the denominator has a zero constant term, then @t{div-series} should signal -an error.) Show how to use @t{div-series} together with the result of +the denominator has a zero constant term, then @code{div-series} should signal +an error.) Show how to use @code{div-series} together with the result of @ref{Exercise 3.59} to generate the power series for tangent. @end quotation @@ -20979,7 +20979,7 @@ updating state variables. We know now that we can represent state as a Let's adopt this perspective in revisiting the square-root procedure from @ref{1.1.7}. Recall that the idea is to generate a sequence of better and better guesses for the square root of @math{x} by applying over and over again -the procedure that improves guesses: @t{ (define (sqrt-improve guess x)} +the procedure that improves guesses: @code{ (define (sqrt-improve guess x)} @lisp (average guess (/ x guess))) @@ -20987,11 +20987,11 @@ the procedure that improves guesses: @t{ (define (sqrt-improve guess x)} @endpage @noindent -In our original @t{sqrt} procedure, we made these guesses be the successive +In our original @code{sqrt} procedure, we made these guesses be the successive values of a state variable. Instead we can generate the infinite stream of -guesses, starting with an initial guess of 1:@footnote{We can't use @t{let} -to bind the local variable @t{guesses}, because the value of @t{guesses} -depends on @t{guesses} itself. @ref{Exercise 3.63} addresses why we want a +guesses, starting with an initial guess of 1:@footnote{We can't use @code{let} +to bind the local variable @code{guesses}, because the value of @code{guesses} +depends on @code{guesses} itself. @ref{Exercise 3.63} addresses why we want a local variable here.} @lisp @@ -21035,7 +21035,7 @@ $$ {\pi\over4} = 1 - {1\over3} + {1\over5} - {1\over7} + \dots. $$ @end tex We first generate the stream of summands of the series (the reciprocals of the odd integers, with alternating signs). Then we take the stream of sums of more -and more terms (using the @t{partial-sums} procedure of @ref{Exercise 3.55}) +and more terms (using the @code{partial-sums} procedure of @ref{Exercise 3.55}) and scale the result by 4: @lisp @@ -21204,8 +21204,8 @@ manipulated with a uniform set of operations. @quotation @strong{@anchor{Exercise 3.63}Exercise 3.63:} Louis Reasoner asks why the -@t{sqrt-@/stream} procedure was not written in the following more -straightforward way, without the local variable @t{guesses}: +@code{sqrt-@/stream} procedure was not written in the following more +straightforward way, without the local variable @code{guesses}: @lisp (define (sqrt-stream x) @@ -21219,13 +21219,13 @@ straightforward way, without the local variable @t{guesses}: Alyssa P. Hacker replies that this version of the procedure is considerably less efficient because it performs redundant computation. Explain Alyssa's answer. Would the two versions still differ in efficiency if our -implementation of @t{delay} used only @t{(lambda () <@var{exp}>)} without -using the optimization provided by @t{memo-proc} (@ref{3.5.1})? +implementation of @code{delay} used only @code{(lambda () <@var{exp}>)} without +using the optimization provided by @code{memo-proc} (@ref{3.5.1})? @end quotation @quotation @strong{@anchor{Exercise 3.64}Exercise 3.64:} Write a procedure -@t{stream-limit} that takes as arguments a stream and a number (the +@code{stream-limit} that takes as arguments a stream and a number (the tolerance). It should examine the stream until it finds two successive elements that differ in absolute value by less than the tolerance, and return the second of the two elements. Using this, we could compute square roots up @@ -21264,10 +21264,10 @@ nested loops as processes defined on sequences of pairs. If we generalize this technique to infinite streams, then we can write programs that are not easily represented as loops, because the ``looping'' must range over an infinite set. -For example, suppose we want to generalize the @t{prime-sum-pairs} procedure +For example, suppose we want to generalize the @code{prime-sum-pairs} procedure of @ref{2.2.3} to produce the stream of pairs of @emph{all} integers @math{(i, j)} with @math{i \le j} such that @math{i + j} is prime. If -@t{int-pairs} is the sequence of all pairs of integers @math{(i, j)} with +@code{int-pairs} is the sequence of all pairs of integers @math{(i, j)} with @math{i \le j}, then our required stream is simply@footnote{As in @ref{2.2.3}, we represent a pair of integers as a list rather than a Lisp pair.} @@ -21280,7 +21280,7 @@ pair.} @end lisp @noindent -Our problem, then, is to produce the stream @t{int-pairs}. More generally, +Our problem, then, is to produce the stream @code{int-pairs}. More generally, suppose we have two streams @math{S = (S_i)} and @math{T = (T_j)}, and imagine the infinite rectangular array @ifinfo @@ -21337,9 +21337,9 @@ $ (S_0, T_0) $ & $ (S_0, T_1) $ & $ (S_0, T_2) $ & $ \dots $ \cr @end tex @noindent (If we take both @math{S} and @math{T} to be the stream of integers, then this will -be our desired stream @t{int-pairs}.) +be our desired stream @code{int-pairs}.) -Call the general stream of pairs @t{(pairs S T)}, and consider it to be +Call the general stream of pairs @code{(pairs S T)}, and consider it to be composed of three parts: the pair @math{(S_0, T_0)}, the rest of the pairs in the first row, and the remaining pairs:@footnote{See @ref{Exercise 3.68} for some insight into why we chose this decomposition.} @@ -21371,8 +21371,8 @@ $ (S_0, T_0) $ & $ (S_0, T_1) $ & $ (S_0, T_2) $ & $ \dots $ \cr } $$ @end tex Observe that the third piece in this decomposition (pairs that are not in the -first row) is (recursively) the pairs formed from @t{(stream-cdr S)} and -@t{(stream-cdr T)}. Also note that the second piece (the rest of the first +first row) is (recursively) the pairs formed from @code{(stream-cdr S)} and +@code{(stream-cdr T)}. Also note that the second piece (the rest of the first row) is @lisp @@ -21398,7 +21398,7 @@ Thus we can form our stream of pairs as follows: @noindent In order to complete the procedure, we must choose some way to combine the two -inner streams. One idea is to use the stream analog of the @t{append} +inner streams. One idea is to use the stream analog of the @code{append} procedure from @ref{2.2.1}: @lisp @@ -21427,12 +21427,12 @@ the first integer. To handle infinite streams, we need to devise an order of combination that ensures that every element will eventually be reached if we let our program run long enough. An elegant way to accomplish this is with the following -@t{interleave} procedure:@footnote{The precise statement of the required +@code{interleave} procedure:@footnote{The precise statement of the required property on the order of combination is as follows: There should be a function @math{f} of two arguments such that the pair corresponding to element @math{i} of the first stream and element @math{j} of the second stream will appear as element number @math{f(i, j)} of the output stream. The trick of using -@t{interleave} to accomplish this was shown to us by David Turner, who +@code{interleave} to accomplish this was shown to us by David Turner, who employed it in the language KRC (@ref{Turner 1981}).} @lisp @@ -21445,7 +21445,7 @@ employed it in the language KRC (@ref{Turner 1981}).} @end lisp @noindent -Since @t{interleave} takes elements alternately from the two streams, every +Since @code{interleave} takes elements alternately from the two streams, every element of the second stream will eventually find its way into the interleaved stream, even if the first stream is infinite. @@ -21463,7 +21463,7 @@ We can thus generate the required stream of pairs as @end lisp @quotation -@strong{@anchor{Exercise 3.66}Exercise 3.66:} Examine the stream @t{(pairs +@strong{@anchor{Exercise 3.66}Exercise 3.66:} Examine the stream @code{(pairs integers integers)}. Can you make any general comments about the order in which the pairs are placed into the stream? For example, approximately how many pairs precede the pair (1, 100)? the pair (99, 100)? the pair (100, 100)? (If you can make @@ -21472,8 +21472,8 @@ more qualitative answers if you find yourself getting bogged down.) @end quotation @quotation -@strong{@anchor{Exercise 3.67}Exercise 3.67:} Modify the @t{pairs} procedure -so that @t{(pairs integers integers)} will produce the stream of @emph{all} +@strong{@anchor{Exercise 3.67}Exercise 3.67:} Modify the @code{pairs} procedure +so that @code{(pairs integers integers)} will produce the stream of @emph{all} pairs of integers @math{(i, j)} (without the condition @math{i \le j}). Hint: You will need to mix in an additional stream. @end quotation @@ -21495,15 +21495,15 @@ the first row, he proposes to work with the whole first row, as follows: (stream-cdr t)))) @end lisp -Does this work? Consider what happens if we evaluate @t{(pairs integers -integers)} using Louis's definition of @t{pairs}. +Does this work? Consider what happens if we evaluate @code{(pairs integers +integers)} using Louis's definition of @code{pairs}. @end quotation @quotation -@strong{@anchor{Exercise 3.69}Exercise 3.69:} Write a procedure @t{triples} +@strong{@anchor{Exercise 3.69}Exercise 3.69:} Write a procedure @code{triples} that takes three infinite streams, @math{S}, @math{T}, and @math{U}, and produces the stream of triples @math{(S_i, T_j, U_k)} such that @math{i \le j \le k}. -Use @t{triples} to generate the stream of all Pythagorean +Use @code{triples} to generate the stream of all Pythagorean triples of positive integers, i.e., the triples @math{(i, j, k)} such that @math{i \le j} and @math{i^2 + j^2 = k^2}. @end quotation @@ -21512,19 +21512,19 @@ triples of positive integers, i.e., the triples @math{(i, j, k)} such that @strong{@anchor{Exercise 3.70}Exercise 3.70:} It would be nice to be able to generate streams in which the pairs appear in some useful order, rather than in the order that results from an @emph{ad hoc} interleaving process. We can use -a technique similar to the @t{merge} procedure of @ref{Exercise 3.56}, if we +a technique similar to the @code{merge} procedure of @ref{Exercise 3.56}, if we define a way to say that one pair of integers is ``less than'' another. One way to do this is to define a ``weighting function'' @math{W(i, j)} and stipulate that @math{(i_1, j_1)} is less than @math{(i_2, j_2)} if @math{W(i_1, j_1) < W(i_2, j_2)}. Write a procedure -@t{merge-weighted} that is like @t{merge}, except that -@t{merge-weighted} takes an additional argument @t{weight}, which is a +@code{merge-weighted} that is like @code{merge}, except that +@code{merge-weighted} takes an additional argument @code{weight}, which is a procedure that computes the weight of a pair, and is used to determine the order in which elements should appear in the resulting merged stream.@footnote{We will require that the weighting function be such that the weight of a pair increases as we move out along a row or down along a column of -the array of pairs.} Using this, generalize @t{pairs} to a procedure -@t{weighted-pairs} that takes two streams, together with a procedure that +the array of pairs.} Using this, generalize @code{pairs} to a procedure +@code{weighted-pairs} that takes two streams, together with a procedure that computes a weighting function, and generates the stream of pairs, ordered according to weight. Use your procedure to generate @@ -21594,7 +21594,7 @@ $$ S_i = C + \sum_{j=1}^i x_j d\!t $$ @end tex @noindent and returns the stream of values @math{S = (S_i)}. The following -@t{integral} procedure is reminiscent of the ``implicit style'' definition +@code{integral} procedure is reminiscent of the ``implicit style'' definition of the stream of integers (@ref{3.5.2}): @lisp @@ -21609,9 +21609,9 @@ of the stream of integers (@ref{3.5.2}): @noindent @ref{Figure 3.32} is a picture of a signal-processing system that corresponds -to the @t{integral} procedure. The input stream is scaled by @math{d\!t} and +to the @code{integral} procedure. The input stream is scaled by @math{d\!t} and passed through an adder, whose output is passed back through the same adder. -The self-reference in the definition of @t{int} is reflected in the figure +The self-reference in the definition of @code{int} is reflected in the figure by the feedback loop that connects the output of the adder to one of the inputs. @@ -21619,7 +21619,7 @@ inputs. @c @quotation @anchor{Figure 3.32} @ifinfo -@strong{Figure 3.32:} The @t{integral} procedure viewed as a signal-processing system. +@strong{Figure 3.32:} The @code{integral} procedure viewed as a signal-processing system. @example initial-value @@ -21640,7 +21640,7 @@ input | | |\__ +-->| \_ integral @sp 0.6 @c @quotation @noindent -@strong{Figure 3.32:} The @t{integral} procedure viewed as a signal-processing system. +@strong{Figure 3.32:} The @code{integral} procedure viewed as a signal-processing system. @c @end quotation @sp 0.9 @end iftex @@ -21697,13 +21697,13 @@ accompanying signal-flow diagram. @c @end quotation @end float -Write a procedure @t{RC} that models this circuit. @t{RC} should take as +Write a procedure @code{RC} that models this circuit. @code{RC} should take as inputs the values of @math{R}, @math{C}, and @math{d\!t} and should return a procedure that takes as inputs a stream representing the current @math{i} and an initial value for the capacitor voltage @math{v_0} and produces as output the stream of -voltages @math{v}. For example, you should be able to use @t{RC} to model an +voltages @math{v}. For example, you should be able to use @code{RC} to model an RC circuit with @math{R} = 5 ohms, @math{C} = 1 farad, and a 0.5-second time step by -evaluating @t{(define RC1 (RC 5 1 0.5))}. This defines @t{RC1} as a +evaluating @code{(define RC1 (RC 5 1 0.5))}. This defines @code{RC1} as a procedure that takes a stream representing the time sequence of currents and an initial capacitor voltage and produces the output stream of voltages. @end quotation @@ -21724,9 +21724,9 @@ zero-crossing signal would be @end smalllisp In Alyssa's system, the signal from the sensor is represented as a stream -@t{sense-@/data} and the stream @t{zero-@/crossings} is the corresponding +@code{sense-@/data} and the stream @code{zero-@/crossings} is the corresponding stream of zero crossings. Alyssa first writes a procedure -@t{sign-@/change-@/detector} that takes two values as arguments and compares the +@code{sign-@/change-@/detector} that takes two values as arguments and compares the signs of the values to produce an appropriate 0, 1, or @math{-1}. She then constructs her zero-@/crossing stream as follows: @@ -21747,7 +21747,7 @@ constructs her zero-@/crossing stream as follows: Alyssa's boss, Eva Lu Ator, walks by and suggests that this program is approximately equivalent to the following one, which uses the generalized -version of @t{stream-map} from @ref{Exercise 3.50}: +version of @code{stream-map} from @ref{Exercise 3.50}: @lisp (define zero-crossings @@ -21785,7 +21785,7 @@ idea, altering Alyssa's program as follows: This does not correctly implement Alyssa's plan. Find the bug that Louis has installed and fix it without changing the structure of the program. (Hint: You -will need to increase the number of arguments to @t{make-zero-crossings}.) +will need to increase the number of arguments to @code{make-zero-crossings}.) @end quotation @quotation @@ -21794,19 +21794,19 @@ Louis's approach in @ref{Exercise 3.75}. The program he wrote is not modular, because it intermixes the operation of smoothing with the zero-crossing extraction. For example, the extractor should not have to be changed if Alyssa finds a better way to condition her input signal. Help Louis by writing a -procedure @t{smooth} that takes a stream as input and produces a stream in +procedure @code{smooth} that takes a stream as input and produces a stream in which each element is the average of two successive input stream elements. -Then use @t{smooth} as a component to implement the zero-crossing detector +Then use @code{smooth} as a component to implement the zero-crossing detector in a more modular style. @end quotation @node 3.5.4, 3.5.5, 3.5.3, 3.5 @subsection Streams and Delayed Evaluation -The @t{integral} procedure at the end of the preceding section shows how we +The @code{integral} procedure at the end of the preceding section shows how we can use streams to model signal-processing systems that contain feedback loops. The feedback loop for the adder shown in @ref{Figure 3.32} is modeled by the -fact that @t{integral}'s internal stream @t{int} is defined in terms of +fact that @code{integral}'s internal stream @code{int} is defined in terms of itself: @lisp @@ -21819,11 +21819,11 @@ itself: @noindent The interpreter's ability to deal with such an implicit definition depends on -the @t{delay} that is incorporated into @t{cons-stream}. Without this -@t{delay}, the interpreter could not construct @t{int} before evaluating -both arguments to @t{cons-stream}, which would require that @t{int} -already be defined. In general, @t{delay} is crucial for using streams to -model signal-processing systems that contain loops. Without @t{delay}, our +the @code{delay} that is incorporated into @code{cons-stream}. Without this +@code{delay}, the interpreter could not construct @code{int} before evaluating +both arguments to @code{cons-stream}, which would require that @code{int} +already be defined. In general, @code{delay} is crucial for using streams to +model signal-processing systems that contain loops. Without @code{delay}, our models would have to be formulated so that the inputs to any signal-processing component would be fully evaluated before the output could be produced. This would outlaw loops. @@ -21857,7 +21857,7 @@ would outlaw loops. @noindent Unfortunately, stream models of systems with loops may require uses of -@t{delay} beyond the ``hidden'' @t{delay} supplied by @t{cons-stream}. +@code{delay} beyond the ``hidden'' @code{delay} supplied by @code{cons-stream}. For instance, @ref{Figure 3.34} shows a signal-processing system for solving the differential equation @math{d\!y\! \big/\! d\!t = f(y)} where @math{f} is a given function. The figure shows a mapping component, which applies @math{f} to its @@ -21876,25 +21876,25 @@ this system using the procedure @end lisp @noindent -This procedure does not work, because in the first line of @t{solve} the -call to @t{integral} requires that the input @t{dy} be defined, which -does not happen until the second line of @t{solve}. +This procedure does not work, because in the first line of @code{solve} the +call to @code{integral} requires that the input @code{dy} be defined, which +does not happen until the second line of @code{solve}. On the other hand, the intent of our definition does make sense, because we -can, in principle, begin to generate the @t{y} stream without knowing -@t{dy}. Indeed, @t{integral} and many other stream operations have -properties similar to those of @t{cons-stream}, in that we can generate part +can, in principle, begin to generate the @code{y} stream without knowing +@code{dy}. Indeed, @code{integral} and many other stream operations have +properties similar to those of @code{cons-stream}, in that we can generate part of the answer given only partial information about the arguments. For -@t{integral}, the first element of the output stream is the specified -@t{initial-value}. Thus, we can generate the first element of the output -stream without evaluating the integrand @t{dy}. Once we know the first -element of @t{y}, the @t{stream-map} in the second line of @t{solve} -can begin working to generate the first element of @t{dy}, which will -produce the next element of @t{y}, and so on. - -To take advantage of this idea, we will redefine @t{integral} to expect the -integrand stream to be a @newterm{delayed argument}. @t{Integral} will -@t{force} the integrand to be evaluated only when it is required to generate +@code{integral}, the first element of the output stream is the specified +@code{initial-value}. Thus, we can generate the first element of the output +stream without evaluating the integrand @code{dy}. Once we know the first +element of @code{y}, the @code{stream-map} in the second line of @code{solve} +can begin working to generate the first element of @code{dy}, which will +produce the next element of @code{y}, and so on. + +To take advantage of this idea, we will redefine @code{integral} to expect the +integrand stream to be a @newterm{delayed argument}. @code{Integral} will +@code{force} the integrand to be evaluated only when it is required to generate more than the first element of the output stream: @lisp @@ -21912,8 +21912,8 @@ more than the first element of the output stream: @end lisp @noindent -Now we can implement our @t{solve} procedure by delaying the evaluation of -@t{dy} in the definition of @t{y}:@footnote{This procedure is not +Now we can implement our @code{solve} procedure by delaying the evaluation of +@code{dy} in the definition of @code{y}:@footnote{This procedure is not guaranteed to work in all Scheme implementations, although for any implementation there is a simple variation that will work. The problem has to do with subtle differences in the ways that Scheme implementations handle @@ -21927,8 +21927,8 @@ internal definitions. (See @ref{4.1.6}.)} @end lisp @noindent -In general, every caller of @t{integral} must now @t{delay} the integrand -argument. We can demonstrate that the @t{solve} procedure works by +In general, every caller of @code{integral} must now @code{delay} the integrand +argument. We can demonstrate that the @code{solve} procedure works by approximating @math{e \approx 2.718} by computing the value at @math{y = 1} of the solution to the differential equation @math{d\!y\! \big/\! d\!t = y} with initial condition @math{y(0) = 1}: @@ -21940,10 +21940,10 @@ condition @math{y(0) = 1}: @end lisp @quotation -@strong{@anchor{Exercise 3.77}Exercise 3.77:} The @t{integral} procedure +@strong{@anchor{Exercise 3.77}Exercise 3.77:} The @code{integral} procedure used above was analogous to the ``implicit'' definition of the infinite stream of integers in @ref{3.5.2}. Alternatively, we can give a definition of -@t{integral} that is more like @t{integers-starting-from} (also in +@code{integral} that is more like @code{integers-starting-from} (also in @ref{3.5.2}): @lisp @@ -21961,9 +21961,9 @@ of integers in @ref{3.5.2}. Alternatively, we can give a definition of @end lisp When used in systems with loops, this procedure has the same problem as does -our original version of @t{integral}. Modify the procedure so that it -expects the @t{integrand} as a delayed argument and hence can be used in the -@t{solve} procedure shown above. +our original version of @code{integral}. Modify the procedure so that it +expects the @code{integrand} as a delayed argument and hence can be used in the +@code{solve} procedure shown above. @end quotation @float @@ -22019,14 +22019,14 @@ The output stream, modeling @math{y}, is generated by a network that contains a loop. This is because the value of @math{d^2\!y\! \big/\! d\!t^2} depends upon the values of @math{y} and @math{d\!y\! \big/\! d\!t} and both of these are determined by integrating @math{d^2\!y\! \big/\! d\!t^2}. The diagram we would like to encode is -shown in @ref{Figure 3.35}. Write a procedure @t{solve-2nd} that takes as +shown in @ref{Figure 3.35}. Write a procedure @code{solve-2nd} that takes as arguments the constants @math{a}, @math{b}, and @math{d\!t} and the initial values @math{y_0} and @math{d\!y_0} for @math{y} and @math{d\!y\! \big/\! d\!t} and generates the stream of successive values of @math{y}. @end quotation @quotation -@strong{@anchor{Exercise 3.79}Exercise 3.79:} Generalize the @t{solve-2nd} +@strong{@anchor{Exercise 3.79}Exercise 3.79:} Generalize the @code{solve-2nd} procedure of @ref{Exercise 3.78} so that it can be used to solve general second-order differential equations @math{d^2\!y\! \big/\! d\!t^2 = f(d\!y\! \big/\! d\!t, y)}. @@ -22139,13 +22139,13 @@ shown in @ref{Figure 3.37}. @end quotation @quotation -Write a procedure @t{RLC} that takes as arguments the parameters @math{R}, +Write a procedure @code{RLC} that takes as arguments the parameters @math{R}, @math{L}, and @math{C} of the circuit and the time increment @math{d\!t}. In a manner -similar to that of the @t{RC} procedure of @ref{Exercise 3.73}, @t{RLC} +similar to that of the @code{RC} procedure of @ref{Exercise 3.73}, @code{RLC} should produce a procedure that takes the initial values of the state variables, @math{v_{C_0}} and @math{i_{L_0}}, and produces a pair (using -@t{cons}) of the streams of states @math{v_C} and @math{i_L}. Using -@t{RLC}, generate the pair of streams that models the behavior of a series +@code{cons}) of the streams of states @math{v_C} and @math{i_L}. Using +@code{RLC}, generate the pair of streams that models the behavior of a series RLC circuit with @math{R} = 1 ohm, @math{C} = 0.2 farad, @math{L} = 1 henry, @math{d\!t} = 0.1 second, and initial values @math{i_{L_0}} = 0 amps and @math{v_{C_0}} = 10 volts. @@ -22195,12 +22195,12 @@ RLC circuit with @math{R} = 1 ohm, @math{C} = 0.2 farad, @math{L} = 1 henry, @ma @subsubheading Normal-order evaluation -The examples in this section illustrate how the explicit use of @t{delay} -and @t{force} provides great programming flexibility, but the same examples -also show how this can make our programs more complex. Our new @t{integral} +The examples in this section illustrate how the explicit use of @code{delay} +and @code{force} provides great programming flexibility, but the same examples +also show how this can make our programs more complex. Our new @code{integral} procedure, for instance, gives us the power to model systems with loops, but we -must now remember that @t{integral} should be called with a delayed -integrand, and every procedure that uses @t{integral} must be aware of this. +must now remember that @code{integral} should be called with a delayed +integrand, and every procedure that uses @code{integral} must be aware of this. In effect, we have created two classes of procedures: ordinary procedures and procedures that take delayed arguments. In general, creating separate classes of procedures forces us to create separate classes of higher-order procedures @@ -22209,11 +22209,11 @@ conventional strongly typed languages such as Pascal have in coping with higher-order procedures. In such languages, the programmer must specify the data types of the arguments and the result of each procedure: number, logical value, sequence, and so on. Consequently, we could not express an abstraction -such as ``map a given procedure @t{proc} over all the elements in a -sequence'' by a single higher-order procedure such as @t{stream-map}. +such as ``map a given procedure @code{proc} over all the elements in a +sequence'' by a single higher-order procedure such as @code{stream-map}. Rather, we would need a different mapping procedure for each different combination of argument and result data types that might be specified for a -@t{proc}. Maintaining a practical notion of ``data type'' in the presence +@code{proc}. Maintaining a practical notion of ``data type'' in the presence of higher-order procedures raises many difficult issues. One way of dealing with this problem is illustrated by the language ML (@ref{Gordon et al. 1979}), whose ``polymorphic data types'' include templates for @@ -22236,7 +22236,7 @@ studied the evaluator, we will see how to transform our language in just this way. Unfortunately, including delays in procedure calls wreaks havoc with our ability to design programs that depend on the order of events, such as programs that use assignment, mutate data, or perform input or output. Even the single -@t{delay} in @t{cons-stream} can cause great confusion, as illustrated by +@code{delay} in @code{cons-stream} can cause great confusion, as illustrated by @ref{Exercise 3.51} and @ref{Exercise 3.52}. As far as anyone knows, mutability and delayed evaluation do not mix well in programming languages, and devising ways to deal with both of these at once is an active area of research. @@ -22254,7 +22254,7 @@ stream-processing point of view. The key modularity issue was that we wished to hide the internal state of a random-number generator from programs that used random numbers. We began with -a procedure @t{rand-update}, whose successive values furnished our supply of +a procedure @code{rand-update}, whose successive values furnished our supply of random numbers, and used this to produce a random-number generator: @lisp @@ -22268,7 +22268,7 @@ random numbers, and used this to produce a random-number generator: @noindent In the stream formulation there is no random-number generator @emph{per se}, just a stream of random numbers produced by successive calls to -@t{rand-update}: +@code{rand-update}: @lisp (define random-numbers @@ -22279,7 +22279,7 @@ just a stream of random numbers produced by successive calls to @noindent We use this to construct the stream of outcomes of the Ces@`aro experiment -performed on consecutive pairs in the @t{random-numbers} stream: +performed on consecutive pairs in the @code{random-numbers} stream: @lisp (define cesaro-stream @@ -22295,12 +22295,12 @@ performed on consecutive pairs in the @t{random-numbers} stream: @end lisp @noindent -The @t{cesaro-stream} is now fed to a @t{monte-carlo} procedure, which +The @code{cesaro-stream} is now fed to a @code{monte-carlo} procedure, which produces a stream of estimates of probabilities. The results are then converted into a stream of estimates of @math{\pi}. This version of the program doesn't need a parameter telling how many trials to perform. Better estimates of @math{\pi} (from performing more experiments) are obtained by looking farther -into the @t{pi} stream: +into the @code{pi} stream: @lisp (define (monte-carlo experiment-stream @@ -22323,7 +22323,7 @@ into the @t{pi} stream: @noindent There is considerable modularity in this approach, because we still can -formulate a general @t{monte-carlo} procedure that can deal with arbitrary +formulate a general @code{monte-carlo} procedure that can deal with arbitrary experiments. Yet there is no assignment or local state. @quotation @@ -22331,15 +22331,15 @@ experiments. Yet there is no assignment or local state. generalizing the random-number generator to allow one to reset the random-number sequence so as to produce repeatable sequences of ``random'' numbers. Produce a stream formulation of this same generator that operates on -an input stream of requests to @t{generate} a new random number or to -@t{reset} the sequence to a specified value and that produces the desired +an input stream of requests to @code{generate} a new random number or to +@code{reset} the sequence to a specified value and that produces the desired stream of random numbers. Don't use assignment in your solution. @end quotation @quotation @strong{@anchor{Exercise 3.82}Exercise 3.82:} Redo @ref{Exercise 3.5} on Monte Carlo integration in terms of streams. The stream version of -@t{estimate-integral} will not have an argument telling how many trials to +@code{estimate-integral} will not have an argument telling how many trials to perform. Instead, it will produce a stream of estimates based on successively more trials. @end quotation @@ -22359,7 +22359,7 @@ local state. We can model a changing quantity, such as the local state of some object, using a stream that represents the time history of successive states. In essence, we represent time explicitly, using streams, so that we decouple time in our simulated world from the sequence of events that take place during -evaluation. Indeed, because of the presence of @t{delay} there may be +evaluation. Indeed, because of the presence of @code{delay} there may be little relation between simulated time in the model and the order of events during the evaluation. @@ -22376,9 +22376,9 @@ such a processor: @end lisp @noindent -Calls to @t{make-simplified-withdraw} produce computational objects, each -with a local state variable @t{balance} that is decremented by successive -calls to the object. The object takes an @t{amount} as an argument and +Calls to @code{make-simplified-withdraw} produce computational objects, each +with a local state variable @code{balance} that is decremented by successive +calls to the object. The object takes an @code{amount} as an argument and returns the new balance. We can imagine the user of a bank account typing a sequence of inputs to such an object and observing the sequence of returned values shown on a display screen. @@ -22397,17 +22397,17 @@ successive balances in the account: @end lisp @noindent -@t{Stream-withdraw} implements a well-defined mathematical function whose +@code{Stream-withdraw} implements a well-defined mathematical function whose output is fully determined by its input. Suppose, however, that the input -@t{amount-stream} is the stream of successive values typed by the user and +@code{amount-stream} is the stream of successive values typed by the user and that the resulting stream of balances is displayed. Then, from the perspective of the user who is typing values and watching results, the stream process has -the same behavior as the object created by @t{make-simplified-withdraw}. +the same behavior as the object created by @code{make-simplified-withdraw}. However, with the stream version, there is no assignment, no local state variable, and consequently none of the theoretical difficulties that we encountered in @ref{3.1.3}. Yet the system has state! -This is really remarkable. Even though @t{stream-withdraw} implements a +This is really remarkable. Even though @code{stream-withdraw} implements a well-defined mathematical function whose behavior does not change, the user's perception here is one of interacting with a system that has a changing state. One way to resolve this paradox is to realize that it is the user's temporal @@ -22728,7 +22728,7 @@ is applied. @c @quotation @anchor{Figure 4.1} @ifinfo -@strong{Figure 4.1:} The @t{eval}-@t{apply} cycle exposes the essence of a computer language. +@strong{Figure 4.1:} The @code{eval}-@code{apply} cycle exposes the essence of a computer language. @example .,ad88888888baa, @@ -22759,7 +22759,7 @@ Arguments | 8 Eval `888888888888888888) | Environment @center @image{fig/chap4/Fig4.1a,147mm,,,.pdf} @sp 0.7 @noindent -@strong{Figure 4.1:} The @t{eval}-@t{apply} cycle exposes the essence of a computer language. +@strong{Figure 4.1:} The @code{eval}-@code{apply} cycle exposes the essence of a computer language. @sp 0.0 @end iftex @c @end quotation @@ -22780,15 +22780,15 @@ primitives to form a language. Specifically: @math{\bullet} The evaluator enables us to deal with nested expressions. For example, although simply applying primitives would suffice for evaluating the expression -@t{(+ 1 6)}, it is not adequate for handling @t{(+ 1 (* 2 3))}. As far -as the primitive procedure @t{+} is concerned, its arguments must be -numbers, and it would choke if we passed it the expression @t{(* 2 3)} as an +@code{(+ 1 6)}, it is not adequate for handling @code{(+ 1 (* 2 3))}. As far +as the primitive procedure @code{+} is concerned, its arguments must be +numbers, and it would choke if we passed it the expression @code{(* 2 3)} as an argument. One important role of the evaluator is to choreograph procedure -composition so that @t{(* 2 3)} is reduced to 6 before being passed as an -argument to @t{+}. +composition so that @code{(* 2 3)} is reduced to 6 before being passed as an +argument to @code{+}. @math{\bullet} The evaluator allows us to use variables. For example, the primitive procedure -for addition has no way to deal with expressions such as @t{(+ x 1)}. We +for addition has no way to deal with expressions such as @code{(+ x 1)}. We need an evaluator to keep track of variables and obtain their values before invoking the primitive procedures. @@ -22800,22 +22800,22 @@ accept arguments. @math{\bullet} The evaluator provides the special forms, which must be evaluated differently from procedure calls.} This evaluation cycle will be embodied by the interplay between the two -critical procedures in the evaluator, @t{eval} and @t{apply}, which are +critical procedures in the evaluator, @code{eval} and @code{apply}, which are described in @ref{4.1.1} (see @ref{Figure 4.1}). The implementation of the evaluator will depend upon procedures that define the @newterm{syntax} of the expressions to be evaluated. We will use data abstraction to make the evaluator independent of the representation of the language. For example, rather than committing to a choice that an assignment -is to be represented by a list beginning with the symbol @t{set!} we use an -abstract predicate @t{assignment?} to test for an assignment, and we use -abstract selectors @t{assignment-variable} and @t{assignment-value} to +is to be represented by a list beginning with the symbol @code{set!} we use an +abstract predicate @code{assignment?} to test for an assignment, and we use +abstract selectors @code{assignment-variable} and @code{assignment-value} to access the parts of an assignment. Implementation of expressions will be described in detail in @ref{4.1.2}. There are also operations, described in @ref{4.1.3}, that specify the representation of procedures -and environments. For example, @t{make-procedure} constructs compound -procedures, @t{lookup-variable-value} accesses the values of variables, and -@t{apply-primitive-procedure} applies a primitive procedure to a given list +and environments. For example, @code{make-procedure} constructs compound +procedures, @code{lookup-variable-value} accesses the values of variables, and +@code{apply-primitive-procedure} applies a primitive procedure to a given list of arguments. @menu @@ -22832,12 +22832,12 @@ of arguments. @subsection The Core of the Evaluator The evaluation process can be described as the interplay between two -procedures: @t{eval} and @t{apply}. +procedures: @code{eval} and @code{apply}. @subsubheading Eval -@t{Eval} takes as arguments an expression and an environment. It classifies -the expression and directs its evaluation. @t{Eval} is structured as a case +@code{Eval} takes as arguments an expression and an environment. It classifies +the expression and directs its evaluation. @code{Eval} is structured as a case analysis of the syntactic type of the expression to be evaluated. In order to keep the procedure general, we express the determination of the type of an expression abstractly, making no commitment to any particular representation @@ -22853,11 +22853,11 @@ syntax procedures. @itemize @bullet @item -For self-evaluating expressions, such as numbers, @t{eval} returns the +For self-evaluating expressions, such as numbers, @code{eval} returns the expression itself. @item -@t{Eval} must look up variables in the environment to find their values. +@code{Eval} must look up variables in the environment to find their values. @end itemize @@ -22867,29 +22867,29 @@ expression itself. @itemize @bullet @item -For quoted expressions, @t{eval} returns the expression that was quoted. +For quoted expressions, @code{eval} returns the expression that was quoted. @item An assignment to (or a definition of) a variable must recursively call -@t{eval} to compute the new value to be associated with the variable. The +@code{eval} to compute the new value to be associated with the variable. The environment must be modified to change (or create) the binding of the variable. @item -An @t{if} expression requires special processing of its parts, so as to +An @code{if} expression requires special processing of its parts, so as to evaluate the consequent if the predicate is true, and otherwise to evaluate the alternative. @item -A @t{lambda} expression must be transformed into an applicable procedure by -packaging together the parameters and body specified by the @t{lambda} +A @code{lambda} expression must be transformed into an applicable procedure by +packaging together the parameters and body specified by the @code{lambda} expression with the environment of the evaluation. @item -A @t{begin} expression requires evaluating its sequence of expressions in +A @code{begin} expression requires evaluating its sequence of expressions in the order in which they appear. @item -A case analysis (@t{cond}) is transformed into a nest of @t{if} +A case analysis (@code{cond}) is transformed into a nest of @code{if} expressions and then evaluated. @end itemize @@ -22900,15 +22900,15 @@ expressions and then evaluated. @itemize @bullet @item -For a procedure application, @t{eval} must recursively evaluate the operator +For a procedure application, @code{eval} must recursively evaluate the operator part and the operands of the combination. The resulting procedure and -arguments are passed to @t{apply}, which handles the actual procedure +arguments are passed to @code{apply}, which handles the actual procedure application. @end itemize @noindent -Here is the definition of @t{eval}: +Here is the definition of @code{eval}: @lisp (define (eval exp env) @@ -22946,26 +22946,26 @@ Here is the definition of @t{eval}: @end lisp @noindent -For clarity, @t{eval} has been implemented as a case analysis using -@t{cond}. The disadvantage of this is that our procedure handles only a few +For clarity, @code{eval} has been implemented as a case analysis using +@code{cond}. The disadvantage of this is that our procedure handles only a few distinguishable types of expressions, and no new ones can be defined without -editing the definition of @t{eval}. In most Lisp implementations, +editing the definition of @code{eval}. In most Lisp implementations, dispatching on the type of an expression is done in a data-directed style. -This allows a user to add new types of expressions that @t{eval} can -distinguish, without modifying the definition of @t{eval} itself. (See +This allows a user to add new types of expressions that @code{eval} can +distinguish, without modifying the definition of @code{eval} itself. (See @ref{Exercise 4.3}.) @subsubheading Apply -@t{Apply} takes two arguments, a procedure and a list of arguments to which -the procedure should be applied. @t{Apply} classifies procedures into two -kinds: It calls @t{apply-@/primitive-@/procedure} to apply primitives; it +@code{Apply} takes two arguments, a procedure and a list of arguments to which +the procedure should be applied. @code{Apply} classifies procedures into two +kinds: It calls @code{apply-@/primitive-@/procedure} to apply primitives; it applies compound procedures by sequentially evaluating the expressions that make up the body of the procedure. The environment for the evaluation of the body of a compound procedure is constructed by extending the base environment carried by the procedure to include a frame that binds the parameters of the procedure to the arguments to which the procedure is to be applied. Here is -the definition of @t{apply}: +the definition of @code{apply}: @lisp (define (apply procedure arguments) @@ -22990,14 +22990,14 @@ the definition of @t{apply}: @subsubheading Procedure arguments -When @t{eval} processes a procedure application, it uses -@t{list-of-values} to produce the list of arguments to which the procedure -is to be applied. @t{List-of-values} takes as an argument the operands of +When @code{eval} processes a procedure application, it uses +@code{list-of-values} to produce the list of arguments to which the procedure +is to be applied. @code{List-of-values} takes as an argument the operands of the combination. It evaluates each operand and returns a list of the -corresponding values:@footnote{We could have simplified the @t{application?} -clause in @t{eval} by using @t{map} (and stipulating that @t{operands} -returns a list) rather than writing an explicit @t{list-of-values} -procedure. We chose not to use @t{map} here to emphasize the fact that the +corresponding values:@footnote{We could have simplified the @code{application?} +clause in @code{eval} by using @code{map} (and stipulating that @code{operands} +returns a list) rather than writing an explicit @code{list-of-values} +procedure. We chose not to use @code{map} here to emphasize the fact that the evaluator can be implemented without any use of higher-order procedures (and thus could be written in a language that doesn't have higher-order procedures), even though the language that it supports will include higher-order @@ -23015,8 +23015,8 @@ procedures.} @subsubheading Conditionals -@t{Eval-if} evaluates the predicate part of an @t{if} expression in the -given environment. If the result is true, @t{eval-if} evaluates the +@code{Eval-if} evaluates the predicate part of an @code{if} expression in the +given environment. If the result is true, @code{eval-if} evaluates the consequent, otherwise it evaluates the alternative: @lisp @@ -23027,22 +23027,22 @@ consequent, otherwise it evaluates the alternative: @end lisp @noindent -The use of @t{true?} in @t{eval-if} highlights the issue of the +The use of @code{true?} in @code{eval-if} highlights the issue of the connection between an implemented language and an implementation language. The -@t{if-predicate} is evaluated in the language being implemented and thus -yields a value in that language. The interpreter predicate @t{true?} -translates that value into a value that can be tested by the @t{if} in the +@code{if-predicate} is evaluated in the language being implemented and thus +yields a value in that language. The interpreter predicate @code{true?} +translates that value into a value that can be tested by the @code{if} in the implementation language: The metacircular representation of truth might not be the same as that of the underlying Scheme.@footnote{In this case, the language being implemented and the implementation language are the same. Contemplation -of the meaning of @t{true?} here yields expansion of consciousness without +of the meaning of @code{true?} here yields expansion of consciousness without the abuse of substance.} @subsubheading Sequences -@t{Eval-sequence} is used by @t{apply} to evaluate the sequence of -expressions in a procedure body and by @t{eval} to evaluate the sequence of -expressions in a @t{begin} expression. It takes as arguments a sequence of +@code{Eval-sequence} is used by @code{apply} to evaluate the sequence of +expressions in a procedure body and by @code{eval} to evaluate the sequence of +expressions in a @code{begin} expression. It takes as arguments a sequence of expressions and an environment, and evaluates the expressions in the order in which they occur. The value returned is the value of the final expression. @@ -23058,9 +23058,9 @@ which they occur. The value returned is the value of the final expression. @subsubheading Assignments and definitions -The following procedure handles assignments to variables. It calls @t{eval} +The following procedure handles assignments to variables. It calls @code{eval} to find the value to be assigned and transmits the variable and the resulting -value to @t{set-variable-value!} to be installed in the designated +value to @code{set-variable-value!} to be installed in the designated environment. @lisp @@ -23074,7 +23074,7 @@ environment. @noindent Definitions of variables are handled in a similar manner.@footnote{This -implementation of @t{define} ignores a subtle issue in the handling of +implementation of @code{define} ignores a subtle issue in the handling of internal definitions, although it works correctly in most cases. We will see what the problem is and how to solve it in @ref{4.1.6}.} @@ -23088,23 +23088,23 @@ what the problem is and how to solve it in @ref{4.1.6}.} @end lisp @noindent -We have chosen here to return the symbol @t{ok} as the value of an +We have chosen here to return the symbol @code{ok} as the value of an assignment or a definition.@footnote{As we said when we introduced -@t{define} and @t{set!}, these values are implementation-dependent in +@code{define} and @code{set!}, these values are implementation-dependent in Scheme---that is, the implementor can choose what value to return.} @quotation @strong{@anchor{Exercise 4.1}Exercise 4.1:} Notice that we cannot tell whether the metacircular evaluator evaluates operands from left to right or from right to left. Its evaluation order is inherited from the underlying Lisp: If the -arguments to @t{cons} in @t{list-of-values} are evaluated from left to -right, then @t{list-of-values} will evaluate operands from left to right; -and if the arguments to @t{cons} are evaluated from right to left, then -@t{list-of-values} will evaluate operands from right to left. +arguments to @code{cons} in @code{list-of-values} are evaluated from left to +right, then @code{list-of-values} will evaluate operands from left to right; +and if the arguments to @code{cons} are evaluated from right to left, then +@code{list-of-values} will evaluate operands from right to left. -Write a version of @t{list-of-values} that evaluates operands from left to +Write a version of @code{list-of-values} that evaluates operands from left to right regardless of the order of evaluation in the underlying Lisp. Also write -a version of @t{list-of-values} that evaluates operands from right to left. +a version of @code{list-of-values} that evaluates operands from right to left. @end quotation @node 4.1.2, 4.1.3, 4.1.1, 4.1 @@ -23145,11 +23145,11 @@ Variables are represented by symbols: @end lisp @item -Quotations have the form @t{(quote <@var{text-@/of-@/quot-@/ation}>)}:@footnote{As +Quotations have the form @code{(quote <@var{text-@/of-@/quot-@/ation}>)}:@footnote{As mentioned in @ref{2.3.1}, the evaluator sees a quoted expression as a -list beginning with @t{quote}, even if the expression is typed with the -quotation mark. For example, the expression @t{'a} would be seen by the -evaluator as @t{(quote a)}. See @ref{Exercise 2.55}.} +list beginning with @code{quote}, even if the expression is typed with the +quotation mark. For example, the expression @code{'a} would be seen by the +evaluator as @code{(quote a)}. See @ref{Exercise 2.55}.} @lisp (define (quoted? exp) @@ -23158,7 +23158,7 @@ evaluator as @t{(quote a)}. See @ref{Exercise 2.55}.} (cadr exp)) @end lisp -@t{Quoted?} is defined in terms of the procedure @t{tagged-@/list?}, which +@code{Quoted?} is defined in terms of the procedure @code{tagged-@/list?}, which identifies lists beginning with a designated symbol: @lisp @@ -23169,7 +23169,7 @@ identifies lists beginning with a designated symbol: @end lisp @item -Assignments have the form @t{(set! <@var{var}> +Assignments have the form @code{(set! <@var{var}> <@var{value}>)}: @lisp @@ -23221,7 +23221,7 @@ The corresponding syntax procedures are the following: @end lisp @item -@t{Lambda} expressions are lists that begin with the symbol @t{lambda}: +@code{Lambda} expressions are lists that begin with the symbol @code{lambda}: @lisp (define (lambda? exp) @@ -23230,8 +23230,8 @@ The corresponding syntax procedures are the following: (define (lambda-body exp) (cddr exp)) @end lisp -We also provide a constructor for @t{lambda} expressions, which is used by -@t{definition-value}, above: +We also provide a constructor for @code{lambda} expressions, which is used by +@code{definition-value}, above: @lisp (define (make-lambda parameters body) @@ -23239,12 +23239,12 @@ We also provide a constructor for @t{lambda} expressions, which is used by @end lisp @item -Conditionals begin with @t{if} and have a predicate, a consequent, and an +Conditionals begin with @code{if} and have a predicate, a consequent, and an (optional) alternative. If the expression has no alternative part, we provide -@t{false} as the alternative.@footnote{The value of an @t{if} expression +@code{false} as the alternative.@footnote{The value of an @code{if} expression when the predicate is false and there is no alternative is unspecified in Scheme; we have chosen here to make it false. We will support the use of the -variables @t{true} and @t{false} in expressions to be evaluated by +variables @code{true} and @code{false} in expressions to be evaluated by binding them in the global environment. See @ref{4.1.4}.} @lisp @@ -23257,8 +23257,8 @@ binding them in the global environment. See @ref{4.1.4}.} 'false)) @end lisp -We also provide a constructor for @t{if} expressions, to be used by -@t{cond->if} to transform @t{cond} expressions into @t{if} +We also provide a constructor for @code{if} expressions, to be used by +@code{cond->if} to transform @code{cond} expressions into @code{if} expressions: @lisp @@ -23272,9 +23272,9 @@ expressions: @end lisp @item -@t{Begin} packages a sequence of expressions into a single expression. We -include syntax operations on @t{begin} expressions to extract the actual -sequence from the @t{begin} expression, as well as selectors that return the +@code{Begin} packages a sequence of expressions into a single expression. We +include syntax operations on @code{begin} expressions to extract the actual +sequence from the @code{begin} expression, as well as selectors that return the first expression and the rest of the expressions in the sequence.@footnote{These selectors for a list of expressions---and the corresponding ones for a list of operands---are not intended as a data @@ -23291,8 +23291,8 @@ evaluator in @ref{5.4}.} (define (rest-exps seq) (cdr seq)) @end lisp -We also include a constructor @t{sequence->exp} (for use by @t{cond->if}) -that transforms a sequence into a single expression, using @t{begin} if +We also include a constructor @code{sequence->exp} (for use by @code{cond->if}) +that transforms a sequence into a single expression, using @code{begin} if necessary: @lisp @@ -23305,8 +23305,8 @@ necessary: @item A procedure application is any compound expression that is not one of the above -expression types. The @t{car} of the expression is the operator, and the -@t{cdr} is the list of operands: +expression types. The @code{car} of the expression is the operator, and the +@code{cdr} is the list of operands: @lisp (define (application? exp) (pair? exp)) @@ -23323,7 +23323,7 @@ expression types. The @t{car} of the expression is the operator, and the Some special forms in our language can be defined in terms of expressions involving other special forms, rather than being implemented directly. One -example is @t{cond}, which can be implemented as a nest of @t{if} +example is @code{cond}, which can be implemented as a nest of @code{if} expressions. For example, we can reduce the problem of evaluating the expression @@ -23334,8 +23334,8 @@ expression @end lisp @noindent -to the problem of evaluating the following expression involving @t{if} and -@t{begin} expressions: +to the problem of evaluating the following expression involving @code{if} and +@code{begin} expressions: @lisp (if (> x 0) @@ -23346,17 +23346,17 @@ to the problem of evaluating the following expression involving @t{if} and @end lisp @noindent -Implementing the evaluation of @t{cond} in this way simplifies the evaluator +Implementing the evaluation of @code{cond} in this way simplifies the evaluator because it reduces the number of special forms for which the evaluation process must be explicitly specified. -We include syntax procedures that extract the parts of a @t{cond} -expression, and a procedure @t{cond->if} that transforms @t{cond} -expressions into @t{if} expressions. A case analysis begins with -@t{cond} and has a list of predicate-action clauses. A clause is an -@t{else} clause if its predicate is the symbol @t{else}.@footnote{The -value of a @t{cond} expression when all the predicates are false and there -is no @t{else} clause is unspecified in Scheme; we have chosen here to make +We include syntax procedures that extract the parts of a @code{cond} +expression, and a procedure @code{cond->if} that transforms @code{cond} +expressions into @code{if} expressions. A case analysis begins with +@code{cond} and has a list of predicate-action clauses. A clause is an +@code{else} clause if its predicate is the symbol @code{else}.@footnote{The +value of a @code{cond} expression when all the predicates are false and there +is no @code{else} clause is unspecified in Scheme; we have chosen here to make it false.} @lisp @@ -23373,7 +23373,7 @@ it false.} (expand-clauses (cond-clauses exp))) (define (expand-clauses clauses) (if (null? clauses) - 'false @r{; no @t{else} clause} + 'false @r{; no @code{else} clause} (let ((first (car clauses)) (rest (cdr clauses))) (if (cond-else-clause? first) @@ -23391,8 +23391,8 @@ it false.} @end lisp @noindent -Expressions (such as @t{cond}) that we choose to implement as syntactic -transformations are called @newterm{derived expressions}. @t{Let} +Expressions (such as @code{cond}) that we choose to implement as syntactic +transformations are called @newterm{derived expressions}. @code{Let} expressions are also derived expressions (see @ref{Exercise 4.6}).@footnote{Practical Lisp systems provide a mechanism that allows a user to add new derived expressions and specify their implementation as syntactic @@ -23405,73 +23405,73 @@ definition that do not cause these difficulties. See, for example, @ref{Kohlbec @quotation @strong{@anchor{Exercise 4.2}Exercise 4.2:} Louis Reasoner plans to reorder the -@t{cond} clauses in @t{eval} so that the clause for procedure +@code{cond} clauses in @code{eval} so that the clause for procedure applications appears before the clause for assignments. He argues that this will make the interpreter more efficient: Since programs usually contain more -applications than assignments, definitions, and so on, his modified @t{eval} -will usually check fewer clauses than the original @t{eval} before +applications than assignments, definitions, and so on, his modified @code{eval} +will usually check fewer clauses than the original @code{eval} before identifying the type of an expression. @enumerate a @item What is wrong with Louis's plan? (Hint: What will Louis's evaluator do with -the expression @t{(define x 3)}?) +the expression @code{(define x 3)}?) @item Louis is upset that his plan didn't work. He is willing to go to any lengths to make his evaluator recognize procedure applications before it checks for most other kinds of expressions. Help him by changing the syntax of the -evaluated language so that procedure applications start with @t{call}. For -example, instead of @t{(factorial 3)} we will now have to write @t{(call -factorial 3)} and instead of @t{(+ 1 2)} we will have to write @t{(call + +evaluated language so that procedure applications start with @code{call}. For +example, instead of @code{(factorial 3)} we will now have to write @code{(call +factorial 3)} and instead of @code{(+ 1 2)} we will have to write @code{(call + 1 2)}. @end enumerate @end quotation @quotation -@strong{@anchor{Exercise 4.3}Exercise 4.3:} Rewrite @t{eval} so that the +@strong{@anchor{Exercise 4.3}Exercise 4.3:} Rewrite @code{eval} so that the dispatch is done in data-directed style. Compare this with the data-directed -differentiation procedure of @ref{Exercise 2.73}. (You may use the @t{car} +differentiation procedure of @ref{Exercise 2.73}. (You may use the @code{car} of a compound expression as the type of the expression, as is appropriate for the syntax implemented in this section.) @end quotation @quotation @strong{@anchor{Exercise 4.4}Exercise 4.4:} Recall the definitions of the -special forms @t{and} and @t{or} from @ref{Chapter 1}: +special forms @code{and} and @code{or} from @ref{Chapter 1}: @itemize @bullet @item -@t{and}: The expressions are evaluated from left to right. If any +@code{and}: The expressions are evaluated from left to right. If any expression evaluates to false, false is returned; any remaining expressions are not evaluated. If all the expressions evaluate to true values, the value of the last expression is returned. If there are no expressions then true is returned. @item -@t{or}: The expressions are evaluated from left to right. If any expression +@code{or}: The expressions are evaluated from left to right. If any expression evaluates to a true value, that value is returned; any remaining expressions are not evaluated. If all expressions evaluate to false, or if there are no expressions, then false is returned. @end itemize -Install @t{and} and @t{or} as new special forms for the evaluator by +Install @code{and} and @code{or} as new special forms for the evaluator by defining appropriate syntax procedures and evaluation procedures -@t{eval-and} and @t{eval-or}. Alternatively, show how to implement -@t{and} and @t{or} as derived expressions. +@code{eval-and} and @code{eval-or}. Alternatively, show how to implement +@code{and} and @code{or} as derived expressions. @end quotation @quotation @strong{@anchor{Exercise 4.5}Exercise 4.5:} Scheme allows an additional syntax -for @t{cond} clauses, @t{(<@var{test}> => <@var{recipient}>)}. If +for @code{cond} clauses, @code{(<@var{test}> => <@var{recipient}>)}. If @math{\langle}@var{test}@math{\kern0.08em\rangle} evaluates to a true value, then @math{\langle}@var{recipient}@math{\kern0.08em\rangle} is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the @math{\langle}@var{test}@math{\kern0.08em\rangle}, and the result is returned as the value of -the @t{cond} expression. For example +the @code{cond} expression. For example @lisp (cond ((assoc 'b '((a 1) (b 2))) => cadr) @@ -23479,12 +23479,12 @@ the @t{cond} expression. For example @end lisp @noindent -returns 2. Modify the handling of @t{cond} so that it supports this +returns 2. Modify the handling of @code{cond} so that it supports this extended syntax. @end quotation @quotation -@strong{@anchor{Exercise 4.6}Exercise 4.6:} @t{Let} expressions are derived +@strong{@anchor{Exercise 4.6}Exercise 4.6:} @code{Let} expressions are derived expressions, because @lisp @@ -23503,15 +23503,15 @@ is equivalent to @math{\langle}@math{exp_n}@math{\rangle}) @end lisp -Implement a syntactic transformation @t{let->combi-@/nation} that reduces -evaluating @t{let} expressions to evaluating combinations of the type shown -above, and add the appropriate clause to @t{eval} to handle @t{let} +Implement a syntactic transformation @code{let->combi-@/nation} that reduces +evaluating @code{let} expressions to evaluating combinations of the type shown +above, and add the appropriate clause to @code{eval} to handle @code{let} expressions. @end quotation @quotation -@strong{@anchor{Exercise 4.7}Exercise 4.7:} @t{Let*} is similar to -@t{let}, except that the bindings of the @t{let*} variables are performed +@strong{@anchor{Exercise 4.7}Exercise 4.7:} @code{Let*} is similar to +@code{let}, except that the bindings of the @code{let*} variables are performed sequentially from left to right, and each binding is made in an environment in which all of the preceding bindings are visible. For example @@ -23523,34 +23523,34 @@ which all of the preceding bindings are visible. For example @end lisp @noindent -returns 39. Explain how a @t{let*} expression can be rewritten as a set of -nested @t{let} expressions, and write a procedure @t{let*->nested-lets} -that performs this transformation. If we have already implemented @t{let} -(@ref{Exercise 4.6}) and we want to extend the evaluator to handle @t{let*}, -is it sufficient to add a clause to @t{eval} whose action is +returns 39. Explain how a @code{let*} expression can be rewritten as a set of +nested @code{let} expressions, and write a procedure @code{let*->nested-lets} +that performs this transformation. If we have already implemented @code{let} +(@ref{Exercise 4.6}) and we want to extend the evaluator to handle @code{let*}, +is it sufficient to add a clause to @code{eval} whose action is @lisp (eval (let*->nested-lets exp) env) @end lisp @noindent -or must we explicitly expand @t{let*} in terms of non-derived expressions? +or must we explicitly expand @code{let*} in terms of non-derived expressions? @end quotation @quotation -@strong{@anchor{Exercise 4.8}Exercise 4.8:} ``Named @t{let}'' is a variant -of @t{let} that has the form @t{ (let )} +@strong{@anchor{Exercise 4.8}Exercise 4.8:} ``Named @code{let}'' is a variant +of @code{let} that has the form @code{ (let )} @c @c @lisp @c (let @math{\langle}@var{var}@math{\rangle} @math{\langle}@var{bindings}@math{\rangle} @math{\langle}@var{body}@math{\rangle}) @c @end lisp -The @math{\langle}@var{bindings}@math{\kern0.08em\rangle} and @math{\langle}@var{body}@math{\kern0.08em\rangle} are just as in ordinary @t{let}, +The @math{\langle}@var{bindings}@math{\kern0.08em\rangle} and @math{\langle}@var{body}@math{\kern0.08em\rangle} are just as in ordinary @code{let}, except that @math{\langle}@var{var}@math{\kern0.08em\rangle} is bound within @math{\langle}@var{body}@math{\kern0.08em\rangle} to a procedure whose body is @math{\langle}@var{body}@math{\kern0.08em\rangle} and whose parameters are the variables in the @math{\langle}@var{bindings}@math{\kern0.08em\rangle}. Thus, one can repeatedly execute the @math{\langle}@var{body}@math{\kern0.08em\rangle} by invoking the procedure named @math{\langle}@var{var}@math{\kern0.08em\rangle}. For example, the iterative Fibonacci procedure -(@ref{1.2.2}) can be rewritten using named @t{let} as follows: +(@ref{1.2.2}) can be rewritten using named @code{let} as follows: @lisp (define (fib n) @@ -23562,14 +23562,14 @@ named @math{\langle}@var{var}@math{\kern0.08em\rangle}. For example, the iterat (- count 1))))) @end lisp -Modify @t{let->combination} of @ref{Exercise 4.6} to also support named -@t{let}. +Modify @code{let->combination} of @ref{Exercise 4.6} to also support named +@code{let}. @end quotation @quotation @strong{@anchor{Exercise 4.9}Exercise 4.9:} Many languages support a variety of -iteration constructs, such as @t{do}, @t{for}, @t{while}, and -@t{until}. In Scheme, iterative processes can be expressed in terms of +iteration constructs, such as @code{do}, @code{for}, @code{while}, and +@code{until}. In Scheme, iterative processes can be expressed in terms of ordinary procedure calls, so special iteration constructs provide no essential gain in computational power. On the other hand, such constructs are often convenient. Design some iteration constructs, give examples of their use, and @@ -23578,10 +23578,10 @@ show how to implement them as derived expressions. @quotation @strong{@anchor{Exercise 4.10}Exercise 4.10:} By using data abstraction, we -were able to write an @t{eval} procedure that is independent of the +were able to write an @code{eval} procedure that is independent of the particular syntax of the language to be evaluated. To illustrate this, design and implement a new syntax for Scheme by modifying the procedures in this -section, without changing @t{eval} or @t{apply}. +section, without changing @code{eval} or @code{apply}. @end quotation @node 4.1.3, 4.1.4, 4.1.2, 4.1 @@ -23596,7 +23596,7 @@ and false. @subsubheading Testing of predicates For conditionals, we accept anything to be true that is not the explicit -@t{false} object. +@code{false} object. @lisp (define (true? x) @@ -23613,14 +23613,14 @@ procedures: @itemize @bullet @item -@t{(apply-primitive-procedure <@var{proc}> <@var{args}>)} +@code{(apply-primitive-procedure <@var{proc}> <@var{args}>)} @noindent applies the given primitive procedure to the argument values in the list @math{\langle}@var{args}@math{\kern0.08em\rangle} and returns the result of the application. @item -@t{(primitive-procedure? <@var{proc}>)} +@code{(primitive-procedure? <@var{proc}>)} @noindent tests whether @math{\langle}@var{proc}@math{\kern0.08em\rangle} is a primitive procedure. @@ -23632,7 +23632,7 @@ These mechanisms for handling primitives are further described in @ref{4.1.4}. Compound procedures are constructed from parameters, procedure bodies, and -environments using the constructor @t{make-procedure}: +environments using the constructor @code{make-procedure}: @lisp (define (make-procedure parameters body env) @@ -23654,13 +23654,13 @@ We use the following operations for manipulating environments: @itemize @bullet @item -@t{(lookup-variable-value <@var{var}> <@var{env}>)} +@code{(lookup-variable-value <@var{var}> <@var{env}>)} returns the value that is bound to the symbol @math{\langle}@var{var}@math{\kern0.08em\rangle} in the environment @math{\langle}@var{env}@math{\kern0.08em\rangle}, or signals an error if the variable is unbound. @item -@t{(extend-environment <@var{variables}> <@var{values}> <@var{base-env}>)} +@code{(extend-environment <@var{variables}> <@var{values}> <@var{base-env}>)} returns a new environment, consisting of a new frame in which the symbols in the list @math{\langle}@var{variables}@math{\kern0.08em\rangle} are bound to the corresponding elements in the list @@ -23668,13 +23668,13 @@ the list @math{\langle}@var{variables}@math{\kern0.08em\rangle} are bound to the @math{\langle}@var{base-env}@math{\kern0.08em\rangle}. @item -@t{(define-variable! <@var{var}> <@var{value}> <@var{env}>)} +@code{(define-variable! <@var{var}> <@var{value}> <@var{env}>)} adds to the first frame in the environment @math{\langle}@var{env}@math{\kern0.08em\rangle} a new binding that associates the variable @math{\langle}@var{var}@math{\kern0.08em\rangle} with the value @math{\langle}@var{value}@math{\kern0.08em\rangle}. @item -@t{(set-variable-value! <@var{var}> <@var{value}> <@var{env}>)} +@code{(set-variable-value! <@var{var}> <@var{value}> <@var{env}>)} changes the binding of the variable @math{\langle}@var{var}@math{\kern0.08em\rangle} in the environment @math{\langle}@var{env}@math{\kern0.08em\rangle} so that the variable is now bound to the value @math{\langle}@var{value}@math{\kern0.08em\rangle}, or signals an @@ -23684,7 +23684,7 @@ error if the variable is unbound. @noindent To implement these operations we represent an environment as a list of frames. -The enclosing environment of an environment is the @t{cdr} of the list. The +The enclosing environment of an environment is the @code{cdr} of the list. The empty environment is simply the empty list. @lisp @@ -23697,8 +23697,8 @@ empty environment is simply the empty list. Each frame of an environment is represented as a pair of lists: a list of the variables bound in that frame and a list of the associated values.@footnote{Frames are not really a data abstraction in the following -code: @t{Set-variable-value!} and @t{define-variable!} use -@t{set-car!} to directly modify the values in a frame. The purpose of the +code: @code{Set-variable-value!} and @code{define-variable!} use +@code{set-car!} to directly modify the values in a frame. The purpose of the frame procedures is to make the environment-manipulation procedures easy to read.} @@ -23759,7 +23759,7 @@ environment, we signal an ``unbound variable'' error. @noindent To set a variable to a new value in a specified environment, we scan for the -variable, just as in @t{lookup-@/variable-@/value}, and change the corresponding +variable, just as in @code{lookup-@/variable-@/value}, and change the corresponding value when we find it. @lisp @@ -23783,7 +23783,7 @@ value when we find it. @noindent To define a variable, we search the first frame for a binding for the variable, -and change the binding if it exists (just as in @t{set-variable-value!}). +and change the binding if it exists (just as in @code{set-variable-value!}). If no such binding exists, we adjoin one to the first frame. @lisp @@ -23826,8 +23826,8 @@ alternative representation. @quotation @strong{@anchor{Exercise 4.12}Exercise 4.12:} The procedures -@t{define-@/variable!}, @t{set-@/variable-@/value!} and -@t{lookup-@/variable-@/value} can be expressed in terms of more abstract +@code{define-@/variable!}, @code{set-@/variable-@/value!} and +@code{lookup-@/variable-@/value} can be expressed in terms of more abstract procedures for traversing the environment structure. Define abstractions that capture the common patterns and redefine the three procedures in terms of these abstractions. @@ -23835,10 +23835,10 @@ abstractions. @quotation @strong{@anchor{Exercise 4.13}Exercise 4.13:} Scheme allows us to create new -bindings for variables by means of @t{define}, but provides no way to get +bindings for variables by means of @code{define}, but provides no way to get rid of bindings. Implement for the evaluator a special form -@t{make-unbound!} that removes the binding of a given symbol from the -environment in which the @t{make-unbound!} expression is evaluated. This +@code{make-unbound!} that removes the binding of a given symbol from the +environment in which the @code{make-unbound!} expression is evaluated. This problem is not completely specified. For example, should we remove only the binding in the first frame of the environment? Complete the specification and justify any choices you make. @@ -23860,11 +23860,11 @@ create a mechanism that calls on the underlying Lisp system to model the application of primitive procedures. There must be a binding for each primitive procedure name, so that when -@t{eval} evaluates the operator of an application of a primitive, it will -find an object to pass to @t{apply}. We thus set up a global environment +@code{eval} evaluates the operator of an application of a primitive, it will +find an object to pass to @code{apply}. We thus set up a global environment that associates unique objects with the names of the primitive procedures that can appear in the expressions we will be evaluating. The global environment -also includes bindings for the symbols @t{true} and @t{false}, so that +also includes bindings for the symbols @code{true} and @code{false}, so that they can be used as variables in expressions to be evaluated. @lisp @@ -23884,10 +23884,10 @@ they can be used as variables in expressions to be evaluated. @noindent It does not matter how we represent the primitive procedure objects, so long as -@t{apply} can identify and apply them by using the procedures -@t{primitive-procedure?} and @t{apply-primitive-procedure}. We have +@code{apply} can identify and apply them by using the procedures +@code{primitive-procedure?} and @code{apply-primitive-procedure}. We have chosen to represent a primitive procedure as a list beginning with the symbol -@t{primitive} and containing a procedure in the underlying Lisp that +@code{primitive} and containing a procedure in the underlying Lisp that implements that primitive. @lisp @@ -23899,14 +23899,14 @@ implements that primitive. @end lisp @noindent -@t{Setup-environment} will get the primitive names and implementation +@code{Setup-environment} will get the primitive names and implementation procedures from a list:@footnote{Any procedure defined in the underlying Lisp can be used as a primitive for the metacircular evaluator. The name of a primitive installed in the evaluator need not be the same as the name of its implementation in the underlying Lisp; the names are the same here because the metacircular evaluator implements Scheme itself. Thus, for example, we could -put @t{(list 'first car)} or @t{(list 'square (lambda (x) (* x x)))} in -the list of @t{primitive-procedures}.} +put @code{(list 'first car)} or @code{(list 'square (lambda (x) (* x x)))} in +the list of @code{primitive-procedures}.} @lisp (define primitive-procedures @@ -23926,23 +23926,23 @@ the list of @t{primitive-procedures}.} @noindent To apply a primitive procedure, we simply apply the implementation procedure to the arguments, using the underlying Lisp -system:@footnote{@t{Apply-in-underlying-scheme} is the @t{apply} +system:@footnote{@code{Apply-in-underlying-scheme} is the @code{apply} procedure we have used in earlier chapters. The metacircular evaluator's -@t{apply} procedure (@ref{4.1.1}) models the working of this -primitive. Having two different things called @t{apply} leads to a +@code{apply} procedure (@ref{4.1.1}) models the working of this +primitive. Having two different things called @code{apply} leads to a technical problem in running the metacircular evaluator, because defining the -metacircular evaluator's @t{apply} will mask the definition of the -primitive. One way around this is to rename the metacircular @t{apply} to +metacircular evaluator's @code{apply} will mask the definition of the +primitive. One way around this is to rename the metacircular @code{apply} to avoid conflict with the name of the primitive procedure. We have assumed -instead that we have saved a reference to the underlying @t{apply} by doing +instead that we have saved a reference to the underlying @code{apply} by doing @lisp (define apply-in-underlying-scheme apply) @end lisp @noindent -before defining the metacircular @t{apply}. This allows us to access the -original version of @t{apply} under a different name.} +before defining the metacircular @code{apply}. This allows us to access the +original version of @code{apply} under a different name.} @lisp (define (apply-primitive-procedure proc args) @@ -23957,12 +23957,12 @@ Lisp system. It prints a @newterm{prompt}, reads an input expression, evaluates this expression in the global environment, and prints the result. We precede each printed result by an @newterm{output prompt} so as to distinguish the value of the expression from other output that may be printed.@footnote{The -primitive procedure @t{read} waits for input from the user, and returns the +primitive procedure @code{read} waits for input from the user, and returns the next complete expression that is typed. For example, if the user types -@t{(+ 23 x)}, @t{read} returns a three-element list containing the symbol -@t{+}, the number 23, and the symbol @t{x}. If the user types @t{'x}, -@t{read} returns a two-element list containing the symbol @t{quote} and -the symbol @t{x}.} +@code{(+ 23 x)}, @code{read} returns a three-element list containing the symbol +@code{+}, the number 23, and the symbol @code{x}. If the user types @code{'x}, +@code{read} returns a two-element list containing the symbol @code{quote} and +the symbol @code{x}.} @lisp (define input-prompt ";;; M-Eval input:") @@ -23984,7 +23984,7 @@ the symbol @t{x}.} @end lisp @noindent -We use a special printing procedure, @t{user-print}, to avoid printing the +We use a special printing procedure, @code{user-print}, to avoid printing the environment part of a compound procedure, which may be a very long list (or may even contain cycles). @@ -24024,10 +24024,10 @@ environment and start the driver loop. Here is a sample interaction: @quotation @strong{@anchor{Exercise 4.14}Exercise 4.14:} Eva Lu Ator and Louis Reasoner are each experimenting with the metacircular evaluator. Eva types in the -definition of @t{map}, and runs some test programs that use it. They work -fine. Louis, in contrast, has installed the system version of @t{map} as a +definition of @code{map}, and runs some test programs that use it. They work +fine. Louis, in contrast, has installed the system version of @code{map} as a primitive for the metacircular evaluator. When he tries it, things go terribly -wrong. Explain why Louis's @t{map} fails even though Eva's works. +wrong. Explain why Louis's @code{map} fails even though Eva's works. @end quotation @node 4.1.5, 4.1.6, 4.1.4, 4.1 @@ -24101,7 +24101,7 @@ together. In a similar way, we can regard the evaluator as a very special machine that takes as input a description of a machine. Given this input, the evaluator configures itself to emulate the machine described. For example, if we feed -our evaluator the definition of @t{factorial}, as shown in @ref{Figure 4.3}, +our evaluator the definition of @code{factorial}, as shown in @ref{Figure 4.3}, the evaluator will be able to compute factorials. From this perspective, our evaluator is seen to be a @newterm{universal @@ -24181,25 +24181,25 @@ the data objects that are manipulated by our programming language and the programming language itself. Imagine that the evaluator program (implemented in Lisp) is running, and that a user is typing expressions to the evaluator and observing the results. From the perspective of the user, an input expression -such as @t{(* x x)} is an expression in the programming language, which the +such as @code{(* x x)} is an expression in the programming language, which the evaluator should execute. From the perspective of the evaluator, however, the -expression is simply a list (in this case, a list of three symbols: @t{*}, -@t{x}, and @t{x}) that is to be manipulated according to a well-defined +expression is simply a list (in this case, a list of three symbols: @code{*}, +@code{x}, and @code{x}) that is to be manipulated according to a well-defined set of rules. That the user's programs are the evaluator's data need not be a source of confusion. In fact, it is sometimes convenient to ignore this distinction, and to give the user the ability to explicitly evaluate a data object as a Lisp -expression, by making @t{eval} available for use in programs. Many Lisp -dialects provide a primitive @t{eval} procedure that takes as arguments an +expression, by making @code{eval} available for use in programs. Many Lisp +dialects provide a primitive @code{eval} procedure that takes as arguments an expression and an environment and evaluates the expression relative to the -environment.@footnote{Warning: This @t{eval} primitive is not identical to -the @t{eval} procedure we implemented in @ref{4.1.1}, because it +environment.@footnote{Warning: This @code{eval} primitive is not identical to +the @code{eval} procedure we implemented in @ref{4.1.1}, because it uses @emph{actual} Scheme environments rather than the sample environment structures we built in @ref{4.1.3}. These actual environments cannot be manipulated by the user as ordinary lists; they must be accessed via -@t{eval} or other special operations. Similarly, the @t{apply} primitive -we saw earlier is not identical to the metacircular @t{apply}, because it +@code{eval} or other special operations. Similarly, the @code{apply} primitive +we saw earlier is not identical to the metacircular @code{apply}, because it uses actual Scheme procedures rather than the procedure objects we constructed in @ref{4.1.3} and @ref{4.1.4}.} Thus, @@ -24217,18 +24217,18 @@ and @noindent will both return 25.@footnote{The @acronym{MIT} implementation of Scheme -includes @t{eval}, as well as a symbol @t{user-initial-environment} that +includes @code{eval}, as well as a symbol @code{user-initial-environment} that is bound to the initial environment in which the user's input expressions are evaluated.} @quotation @strong{@anchor{Exercise 4.15}Exercise 4.15:} Given a one-argument procedure -@t{p} and an object @t{a}, @t{p} is said to ``halt'' on @t{a} if -evaluating the expression @t{(p a)} returns a value (as opposed to +@code{p} and an object @code{a}, @code{p} is said to ``halt'' on @code{a} if +evaluating the expression @code{(p a)} returns a value (as opposed to terminating with an error message or running forever). Show that it is -impossible to write a procedure @t{halts?} that correctly determines whether -@t{p} halts on @t{a} for any procedure @t{p} and object @t{a}. Use -the following reasoning: If you had such a procedure @t{halts?}, you could +impossible to write a procedure @code{halts?} that correctly determines whether +@code{p} halts on @code{a} for any procedure @code{p} and object @code{a}. Use +the following reasoning: If you had such a procedure @code{halts?}, you could implement the following program: @lisp @@ -24240,11 +24240,11 @@ implement the following program: 'halted)) @end lisp -Now consider evaluating the expression @t{(try try)} and show that any +Now consider evaluating the expression @code{(try try)} and show that any possible outcome (either halting or running forever) violates the intended -behavior of @t{halts?}.@footnote{Although we stipulated that @t{halts?} +behavior of @code{halts?}.@footnote{Although we stipulated that @code{halts?} is given a procedure object, notice that this reasoning still applies even if -@t{halts?} can gain access to the procedure's text and its environment. +@code{halts?} can gain access to the procedure's text and its environment. This is Turing's celebrated @newterm{Halting Theorem}, which gave the first clear example of a @newterm{non-computable} problem, i.e., a well-posed task that cannot be carried out as a computational procedure.} @@ -24274,27 +24274,27 @@ Consider a procedure with internal definitions, such as (if (= n 0) false (even? (- n 1)))) - @math{\langle}@var{rest of body of @t{f}}@math{\rangle}) + @math{\langle}@var{rest of body of @code{f}}@math{\rangle}) @end lisp @noindent -Our intention here is that the name @t{odd?} in the body of the procedure -@t{even?} should refer to the procedure @t{odd?} that is defined after -@t{even?}. The scope of the name @t{odd?} is the entire body of -@t{f}, not just the portion of the body of @t{f} starting at the point -where the @t{define} for @t{odd?} occurs. Indeed, when we consider that -@t{odd?} is itself defined in terms of @t{even?}---so that @t{even?} -and @t{odd?} are mutually recursive procedures---we see that the only -satisfactory interpretation of the two @t{define}s is to regard them as if -the names @t{even?} and @t{odd?} were being added to the environment +Our intention here is that the name @code{odd?} in the body of the procedure +@code{even?} should refer to the procedure @code{odd?} that is defined after +@code{even?}. The scope of the name @code{odd?} is the entire body of +@code{f}, not just the portion of the body of @code{f} starting at the point +where the @code{define} for @code{odd?} occurs. Indeed, when we consider that +@code{odd?} is itself defined in terms of @code{even?}---so that @code{even?} +and @code{odd?} are mutually recursive procedures---we see that the only +satisfactory interpretation of the two @code{define}s is to regard them as if +the names @code{even?} and @code{odd?} were being added to the environment simultaneously. More generally, in block structure, the scope of a local name -is the entire procedure body in which the @t{define} is evaluated. +is the entire procedure body in which the @code{define} is evaluated. -As it happens, our interpreter will evaluate calls to @t{f} correctly, but +As it happens, our interpreter will evaluate calls to @code{f} correctly, but for an ``accidental'' reason: Since the definitions of the internal procedures come first, no calls to these procedures will be evaluated until all of them -have been defined. Hence, @t{odd?} will have been defined by the time -@t{even?} is executed. In fact, our sequential evaluation mechanism will +have been defined. Hence, @code{odd?} will have been defined by the time +@code{even?} is executed. In fact, our sequential evaluation mechanism will give the same result as a mechanism that directly implements simultaneous definition for any procedure in which the internal definitions come first in a body and evaluation of the value expressions for the defined variables doesn't @@ -24315,10 +24315,10 @@ that would otherwise arise in implementing a compiler.} There is, however, a simple way to treat definitions so that internally defined names have truly simultaneous scope---just create all local variables that will be in the current environment before evaluating any of the value expressions. -One way to do this is by a syntax transformation on @t{lambda} expressions. -Before evaluating the body of a @t{lambda} expression, we ``scan out'' and +One way to do this is by a syntax transformation on @code{lambda} expressions. +Before evaluating the body of a @code{lambda} expression, we ``scan out'' and eliminate all the internal definitions in the body. The internally defined -variables will be created with a @t{let} and then set to their values by +variables will be created with a @code{let} and then set to their values by assignment. For example, the procedure @lisp @@ -24341,7 +24341,7 @@ would be transformed into @end lisp @noindent -where @t{*unassigned*} is a special symbol that causes looking up a variable +where @code{*unassigned*} is a special symbol that causes looking up a variable to signal an error if an attempt is made to use the value of the not-yet-assigned variable. @@ -24358,22 +24358,22 @@ restriction will in fact run in such implementations.} @quotation @strong{@anchor{Exercise 4.16}Exercise 4.16:} In this exercise we implement the method just described for interpreting internal definitions. We assume that -the evaluator supports @t{let} (see @ref{Exercise 4.6}). +the evaluator supports @code{let} (see @ref{Exercise 4.6}). @enumerate a @item -Change @t{lookup-variable-value} (@ref{4.1.3}) to signal an error if -the value it finds is the symbol @t{*unassigned*}. +Change @code{lookup-variable-value} (@ref{4.1.3}) to signal an error if +the value it finds is the symbol @code{*unassigned*}. @item -Write a procedure @t{scan-out-defines} that takes a procedure body and +Write a procedure @code{scan-out-defines} that takes a procedure body and returns an equivalent one that has no internal definitions, by making the transformation described above. @item -Install @t{scan-out-defines} in the interpreter, either in -@t{make-@/procedure} or in @t{procedure-body} (see @ref{4.1.3}). +Install @code{scan-out-defines} in the interpreter, either in +@code{make-@/procedure} or in @code{procedure-body} (see @ref{4.1.3}). Which place is better? Why? @end enumerate @@ -24406,9 +24406,9 @@ for scanning out definitions that translates the example in the text to @math{\langle}@var{e3}@math{\rangle})) @end lisp -Here @t{a} and @t{b} are meant to represent new variable names, created +Here @code{a} and @code{b} are meant to represent new variable names, created by the interpreter, that do not appear in the user's program. Consider the -@t{solve} procedure from @ref{3.5.4}: +@code{solve} procedure from @ref{3.5.4}: @lisp (define (solve f y0 dt) @@ -24436,17 +24436,17 @@ expression @end lisp Ben asserts that the result should be obtained using the sequential rule for -@t{define}: @t{b} is defined to be 11, then @t{a} is defined to be 5, +@code{define}: @code{b} is defined to be 11, then @code{a} is defined to be 5, so the result is 16. Alyssa objects that mutual recursion requires the simultaneous scope rule for internal procedure definitions, and that it is unreasonable to treat procedure names differently from other names. Thus, she argues for the mechanism implemented in @ref{Exercise 4.16}. This would lead -to @t{a} being unassigned at the time that the value for @t{b} is to be +to @code{a} being unassigned at the time that the value for @code{b} is to be computed. Hence, in Alyssa's view the procedure should produce an error. Eva -has a third opinion. She says that if the definitions of @t{a} and @t{b} -are truly meant to be simultaneous, then the value 5 for @t{a} should be -used in evaluating @t{b}. Hence, in Eva's view @t{a} should be 5, -@t{b} should be 15, and the result should be 20. Which (if any) of these +has a third opinion. She says that if the definitions of @code{a} and @code{b} +are truly meant to be simultaneous, then the value 5 for @code{a} should be +used in evaluating @code{b}. Hence, in Eva's view @code{a} should be 5, +@code{b} should be 15, and the result should be 20. Which (if any) of these viewpoints do you support? Can you devise a way to implement internal definitions so that they behave as Eva prefers?@footnote{The @acronym{MIT} implementors of Scheme support Alyssa on the following grounds: Eva is in @@ -24460,10 +24460,10 @@ to produce an incorrect answer (as Ben would have it).} @quotation @strong{@anchor{Exercise 4.20}Exercise 4.20:} Because internal definitions look sequential but are actually simultaneous, some people prefer to avoid them -entirely, and use the special form @t{letrec} instead. @t{Letrec} looks -like @t{let}, so it is not surprising that the variables it binds are bound +entirely, and use the special form @code{letrec} instead. @code{Letrec} looks +like @code{let}, so it is not surprising that the variables it binds are bound simultaneously and have the same scope as each other. The sample procedure -@t{f} above can be written without internal definitions, but with exactly +@code{f} above can be written without internal definitions, but with exactly the same meaning, as @lisp @@ -24476,10 +24476,10 @@ the same meaning, as (if (= n 0) false (even? (- n 1)))))) - @math{\langle}@var{rest of body of @t{f}}@math{\rangle})) + @math{\langle}@var{rest of body of @code{f}}@math{\rangle})) @end lisp -@t{Letrec} expressions, which have the form +@code{Letrec} expressions, which have the form @lisp (letrec ((@math{\langle}@math{var_1}@math{\rangle} @math{\langle}@math{exp_1}@math{\rangle}) @dots{} (@math{\langle}@math{var_n}@math{\rangle} @math{\langle}@math{exp_n}@math{\rangle})) @@ -24487,11 +24487,11 @@ the same meaning, as @end lisp @noindent -are a variation on @t{let} in which the expressions +are a variation on @code{let} in which the expressions @math{\langle}@math{exp_k}@math{\kern0.08em\rangle} that provide the initial values for the variables @math{\langle}@math{var_k}@math{\kern0.08em\rangle} are evaluated in an environment -that includes all the @t{letrec} bindings. This permits recursion in the -bindings, such as the mutual recursion of @t{even?} and @t{odd?} in the +that includes all the @code{letrec} bindings. This permits recursion in the +bindings, such as the mutual recursion of @code{even?} and @code{odd?} in the example above, or the evaluation of 10 factorial with @lisp @@ -24506,21 +24506,21 @@ example above, or the evaluation of 10 factorial with @enumerate a @item -Implement @t{letrec} as a derived expression, by transforming a -@t{letrec} expression into a @t{let} expression as shown in the text -above or in @ref{Exercise 4.18}. That is, the @t{letrec} variables should -be created with a @t{let} and then be assigned their values with -@t{set!}. +Implement @code{letrec} as a derived expression, by transforming a +@code{letrec} expression into a @code{let} expression as shown in the text +above or in @ref{Exercise 4.18}. That is, the @code{letrec} variables should +be created with a @code{let} and then be assigned their values with +@code{set!}. @item Louis Reasoner is confused by all this fuss about internal definitions. The -way he sees it, if you don't like to use @t{define} inside a procedure, you -can just use @t{let}. Illustrate what is loose about his reasoning by +way he sees it, if you don't like to use @code{define} inside a procedure, you +can just use @code{let}. Illustrate what is loose about his reasoning by drawing an environment diagram that shows the environment in which the -@math{\langle}@var{rest of body of @t{f}}@math{\kern0.08em\rangle} is evaluated during evaluation of the -expression @t{(f 5)}, with @t{f} defined as in this exercise. Draw an -environment diagram for the same evaluation, but with @t{let} in place of -@t{letrec} in the definition of @t{f}. +@math{\langle}@var{rest of body of @code{f}}@math{\kern0.08em\rangle} is evaluated during evaluation of the +expression @code{(f 5)}, with @code{f} defined as in this exercise. Draw an +environment diagram for the same evaluation, but with @code{let} in place of +@code{letrec} in the definition of @code{f}. @end enumerate @end quotation @@ -24528,11 +24528,11 @@ environment diagram for the same evaluation, but with @t{let} in place of @quotation @strong{@anchor{Exercise 4.21}Exercise 4.21:} Amazingly, Louis's intuition in @ref{Exercise 4.20} is correct. It is indeed possible to specify recursive -procedures without using @t{letrec} (or even @t{define}), although the +procedures without using @code{letrec} (or even @code{define}), although the method for accomplishing this is much more subtle than Louis imagined. The following expression computes 10 factorial by applying a recursive factorial procedure:@footnote{This example illustrates a programming trick for -formulating recursive procedures without using @t{define}. The most general +formulating recursive procedures without using @code{define}. The most general trick of this sort is the @math{Y} @newterm{operator}, which can be used to give a ``pure @math{\lambda}-calculus'' implementation of recursion. (See @ref{Stoy 1977} for details on the @math{\lambda}-calculus, and @ref{Gabriel 1988} for an exposition of the @@ -24572,7 +24572,7 @@ definitions: @end lisp Fill in the missing expressions to complete an alternative definition of -@t{f}, which uses neither internal definitions nor @t{letrec}: +@code{f}, which uses neither internal definitions nor @code{letrec}: @lisp (define (f x) @@ -24596,8 +24596,8 @@ Fill in the missing expressions to complete an alternative definition of The evaluator implemented above is simple, but it is very inefficient, because the syntactic analysis of expressions is interleaved with their execution. Thus if a program is executed many times, its syntax is analyzed many times. -Consider, for example, evaluating @t{(factorial 4)} using the following -definition of @t{factorial}: +Consider, for example, evaluating @code{(factorial 4)} using the following +definition of @code{factorial}: @lisp (define (factorial n) @@ -24607,12 +24607,12 @@ definition of @t{factorial}: @end lisp @noindent -Each time @t{factorial} is called, the evaluator must determine that the -body is an @t{if} expression and extract the predicate. Only then can it +Each time @code{factorial} is called, the evaluator must determine that the +body is an @code{if} expression and extract the predicate. Only then can it evaluate the predicate and dispatch on its value. Each time it evaluates the -expression @t{(* (factorial (- n 1)) n)}, or the subexpressions -@t{(factorial (- n 1))} and @t{(- n 1)}, the evaluator must perform the -case analysis in @t{eval} to determine that the expression is an +expression @code{(* (factorial (- n 1)) n)}, or the subexpressions +@code{(factorial (- n 1))} and @code{(- n 1)}, the evaluator must perform the +case analysis in @code{eval} to determine that the expression is an application, and must extract its operator and operands. This analysis is expensive. Performing it repeatedly is wasteful. @@ -24622,25 +24622,25 @@ technique is an integral part of the compilation process, which we shall discuss in @ref{Chapter 5}. Jonathan Rees wrote a Scheme interpreter like this in about 1982 for the T project (@ref{Rees and Adams 1982}). Marc @ref{Feeley (1986)} (see also @ref{Feeley and Lapalme 1987}) independently invented this technique in his -master's thesis.} We split @t{eval}, which takes an expression and an -environment, into two parts. The procedure @t{analyze} takes only the +master's thesis.} We split @code{eval}, which takes an expression and an +environment, into two parts. The procedure @code{analyze} takes only the expression. It performs the syntactic analysis and returns a new procedure, the @newterm{execution procedure}, that encapsulates the work to be done in executing the analyzed expression. The execution procedure takes an environment as its argument and completes the evaluation. This saves work -because @t{analyze} will be called only once on an expression, while the +because @code{analyze} will be called only once on an expression, while the execution procedure may be called many times. -With the separation into analysis and execution, @t{eval} now becomes +With the separation into analysis and execution, @code{eval} now becomes @lisp (define (eval exp env) ((analyze exp) env)) @end lisp @noindent -The result of calling @t{analyze} is the execution procedure to be applied -to the environment. The @t{analyze} procedure is the same case analysis as -performed by the original @t{eval} of @ref{4.1.1}, except that the +The result of calling @code{analyze} is the execution procedure to be applied +to the environment. The @code{analyze} procedure is the same case analysis as +performed by the original @code{eval} of @ref{4.1.1}, except that the procedures to which we dispatch perform only analysis, not full evaluation: @lisp @@ -24709,10 +24709,10 @@ matches the variable.} @end lisp @noindent -@t{Analyze-assignment} also must defer actually setting the variable until +@code{Analyze-assignment} also must defer actually setting the variable until the execution, when the environment has been supplied. However, the fact that -the @t{assignment-value} expression can be analyzed (recursively) during -analysis is a major gain in efficiency, because the @t{assignment-value} +the @code{assignment-value} expression can be analyzed (recursively) during +analysis is a major gain in efficiency, because the @code{assignment-value} expression will now be analyzed only once. The same holds true for definitions. @@ -24735,7 +24735,7 @@ definitions. @end lisp @noindent -For @t{if} expressions, we extract and analyze the predicate, consequent, +For @code{if} expressions, we extract and analyze the predicate, consequent, and alternative at analysis time. @lisp @@ -24750,9 +24750,9 @@ and alternative at analysis time. @end lisp @noindent -Analyzing a @t{lambda} expression also achieves a major gain in efficiency: -We analyze the @t{lambda} body only once, even though procedures resulting -from evaluation of the @t{lambda} may be applied many times. +Analyzing a @code{lambda} expression also achieves a major gain in efficiency: +We analyze the @code{lambda} body only once, even though procedures resulting +from evaluation of the @code{lambda} may be applied many times. @lisp (define (analyze-lambda exp) @@ -24764,8 +24764,8 @@ from evaluation of the @t{lambda} may be applied many times. @end lisp @noindent -Analysis of a sequence of expressions (as in a @t{begin} or the body of a -@t{lambda} expression) is more involved.@footnote{See @ref{Exercise 4.23} +Analysis of a sequence of expressions (as in a @code{begin} or the body of a +@code{lambda} expression) is more involved.@footnote{See @ref{Exercise 4.23} for some insight into the processing of sequences.} Each expression in the sequence is analyzed, yielding an execution procedure. These execution procedures are combined to produce an execution procedure that takes an @@ -24793,8 +24793,8 @@ To analyze an application, we analyze the operator and operands and construct an execution procedure that calls the operator execution procedure (to obtain the actual procedure to be applied) and the operand execution procedures (to obtain the actual arguments). We then pass these to -@t{execute-application}, which is the analog of @t{apply} in -@ref{4.1.1}. @t{Execute-application} differs from @t{apply} in that the +@code{execute-application}, which is the analog of @code{apply} in +@ref{4.1.1}. @code{Execute-application} differs from @code{apply} in that the procedure body for a compound procedure has already been analyzed, so there is no need to do further analysis. Instead, we just call the execution procedure for the body on the extended environment. @@ -24829,15 +24829,15 @@ run-time support procedures as in @ref{4.1.2}, @ref{4.1.3}, and @quotation @strong{@anchor{Exercise 4.22}Exercise 4.22:} Extend the evaluator in this -section to support the special form @t{let}. (See @ref{Exercise 4.6}.) +section to support the special form @code{let}. (See @ref{Exercise 4.6}.) @end quotation @quotation @strong{@anchor{Exercise 4.23}Exercise 4.23:} Alyssa P. Hacker doesn't -understand why @t{analyze-@/sequence} needs to be so complicated. All the +understand why @code{analyze-@/sequence} needs to be so complicated. All the other analysis procedures are straightforward transformations of the -corresponding evaluation procedures (or @t{eval} clauses) in -@ref{4.1.1}. She expected @t{analyze-sequence} to look like this: +corresponding evaluation procedures (or @code{eval} clauses) in +@ref{4.1.1}. She expected @code{analyze-sequence} to look like this: @lisp (define (analyze-sequence exps) @@ -24862,7 +24862,7 @@ built in, loops through the procedures in order to call them: In effect, although the individual expressions in the sequence have been analyzed, the sequence itself has not been. -Compare the two versions of @t{analyze-sequence}. For example, consider the +Compare the two versions of @code{analyze-sequence}. For example, consider the common case (typical of procedure bodies) where the sequence has just one expression. What work will the execution procedure produced by Alyssa's program do? What about the execution procedure produced by the program in the @@ -24930,12 +24930,12 @@ used interchangeably.} Consider the procedure @end lisp @noindent -Evaluating @t{(try 0 (/ 1 0))} generates an error in Scheme. With lazy +Evaluating @code{(try 0 (/ 1 0))} generates an error in Scheme. With lazy evaluation, there would be no error. Evaluating the expression would return 1, -because the argument @t{(/ 1 0)} would never be evaluated. +because the argument @code{(/ 1 0)} would never be evaluated. An example that exploits lazy evaluation is the definition of a procedure -@t{unless} +@code{unless} @lisp (define (unless condition @@ -24959,9 +24959,9 @@ that can be used in expressions such as @noindent This won't work in an applicative-order language because both the usual value -and the exceptional value will be evaluated before @t{unless} is called +and the exceptional value will be evaluated before @code{unless} is called (compare @ref{Exercise 1.6}). An advantage of lazy evaluation is that some -procedures, such as @t{unless}, can do useful computation even if evaluation +procedures, such as @code{unless}, can do useful computation even if evaluation of some of their arguments would produce errors or would not terminate. If the body of a procedure is entered before an argument has been evaluated we @@ -24981,18 +24981,18 @@ languages (see @ref{Exercise 4.31}) that give programmers detailed control over the strictness of the procedures they define. A striking example of a procedure that can usefully be made non-strict is -@t{cons} (or, in general, almost any constructor for data structures). One +@code{cons} (or, in general, almost any constructor for data structures). One can do useful computation, combining elements to form data structures and operating on the resulting data structures, even if the values of the elements are not known. It makes perfect sense, for instance, to compute the length of a list without knowing the values of the individual elements in the list. We will exploit this idea in @ref{4.2.3} to implement the streams of -@ref{Chapter 3} as lists formed of non-strict @t{cons} pairs. +@ref{Chapter 3} as lists formed of non-strict @code{cons} pairs. @quotation @strong{@anchor{Exercise 4.25}Exercise 4.25:} Suppose that (in ordinary -applicative-order Scheme) we define @t{unless} as shown above and then -define @t{factorial} in terms of @t{unless} as +applicative-order Scheme) we define @code{unless} as shown above and then +define @code{factorial} in terms of @code{unless} as @lisp (define (factorial n) @@ -25001,20 +25001,20 @@ define @t{factorial} in terms of @t{unless} as 1)) @end lisp -What happens if we attempt to evaluate @t{(factorial 5)}? Will our +What happens if we attempt to evaluate @code{(factorial 5)}? Will our definitions work in a normal-order language? @end quotation @quotation @strong{@anchor{Exercise 4.26}Exercise 4.26:} Ben Bitdiddle and Alyssa P. Hacker disagree over the importance of lazy evaluation for implementing -things such as @t{unless}. Ben points out that it's possible to implement -@t{unless} in applicative order as a special form. Alyssa counters that, if -one did that, @t{unless} would be merely syntax, not a procedure that could +things such as @code{unless}. Ben points out that it's possible to implement +@code{unless} in applicative order as a special form. Alyssa counters that, if +one did that, @code{unless} would be merely syntax, not a procedure that could be used in conjunction with higher-order procedures. Fill in the details on -both sides of the argument. Show how to implement @t{unless} as a derived -expression (like @t{cond} or @t{let}), and give an example of a situation -where it might be useful to have @t{unless} available as a procedure, rather +both sides of the argument. Show how to implement @code{unless} as a derived +expression (like @code{cond} or @code{let}), and give an example of a situation +where it might be useful to have @code{unless} available as a procedure, rather than as a special form. @end quotation @@ -25041,7 +25041,7 @@ the thunk must contain the argument expression and the environment in which the procedure application is being evaluated. The process of evaluating the expression in a thunk is called -@newterm{forcing}.@footnote{This is analogous to the use of @t{force} on the +@newterm{forcing}.@footnote{This is analogous to the use of @code{force} on the delayed objects that were introduced in @ref{Chapter 3} to represent streams. The critical difference between what we are doing here and what we did in @ref{Chapter 3} is that we are building delaying and forcing into the @@ -25069,9 +25069,9 @@ attempts to clarify the multiple dimensions of confusion that arise here.} @subsubheading Modifying the evaluator The main difference between the lazy evaluator and the one in @ref{4.1} -is in the handling of procedure applications in @t{eval} and @t{apply}. +is in the handling of procedure applications in @code{eval} and @code{apply}. -The @t{application?} clause of @t{eval} becomes +The @code{application?} clause of @code{eval} becomes @lisp @@ -25082,12 +25082,12 @@ The @t{application?} clause of @t{eval} becomes @end lisp @noindent -This is almost the same as the @t{application?} clause of @t{eval} in -@ref{4.1.1}. For lazy evaluation, however, we call @t{apply} with +This is almost the same as the @code{application?} clause of @code{eval} in +@ref{4.1.1}. For lazy evaluation, however, we call @code{apply} with the operand expressions, rather than the arguments produced by evaluating them. Since we will need the environment to construct thunks if the arguments are to be delayed, we must pass this as well. We still evaluate the operator, because -@t{apply} needs the actual procedure to be applied in order to dispatch on +@code{apply} needs the actual procedure to be applied in order to dispatch on its type (primitive versus compound) and apply it. Whenever we need the actual value of an expression, we use @@ -25098,11 +25098,11 @@ Whenever we need the actual value of an expression, we use @end lisp @noindent -instead of just @t{eval}, so that if the expression's value is a thunk, it +instead of just @code{eval}, so that if the expression's value is a thunk, it will be forced. -Our new version of @t{apply} is also almost the same as the version in -@ref{4.1.1}. The difference is that @t{eval} has passed in +Our new version of @code{apply} is also almost the same as the version in +@ref{4.1.1}. The difference is that @code{eval} has passed in unevaluated operand expressions: For primitive procedures (which are strict), we evaluate all the arguments before applying the primitive; for compound procedures (which are non-strict) we delay all the arguments before applying @@ -25131,10 +25131,10 @@ the procedure. @end lisp @noindent -The procedures that process the arguments are just like @t{list-of-values} -from @ref{4.1.1}, except that @t{list-of-delayed-args} delays the -arguments instead of evaluating them, and @t{list-of-arg-values} uses -@t{actual-@/value} instead of @t{eval}: +The procedures that process the arguments are just like @code{list-of-values} +from @ref{4.1.1}, except that @code{list-of-delayed-args} delays the +arguments instead of evaluating them, and @code{list-of-arg-values} uses +@code{actual-@/value} instead of @code{eval}: @lisp (define (list-of-arg-values exps env) @@ -25158,8 +25158,8 @@ arguments instead of evaluating them, and @t{list-of-arg-values} uses @end lisp @noindent -The other place we must change the evaluator is in the handling of @t{if}, -where we must use @t{actual-value} instead of @t{eval} to get the value +The other place we must change the evaluator is in the handling of @code{if}, +where we must use @code{actual-value} instead of @code{eval} to get the value of the predicate expression before testing whether it is true or false: @lisp @@ -25171,8 +25171,8 @@ of the predicate expression before testing whether it is true or false: @end lisp @noindent -Finally, we must change the @t{driver-loop} procedure (@ref{4.1.4}) -to use @t{actual-value} instead of @t{eval}, so that if a delayed value +Finally, we must change the @code{driver-loop} procedure (@ref{4.1.4}) +to use @code{actual-value} instead of @code{eval}, so that if a delayed value is propagated back to the read-eval-print loop, it will be forced before being printed. We also change the prompts to indicate that this is the lazy evaluator: @@ -25193,7 +25193,7 @@ evaluator: @noindent With these changes made, we can start the evaluator and test it. The -successful evaluation of the @t{try} expression discussed in +successful evaluation of the @code{try} expression discussed in @ref{4.2.1} indicates that the interpreter is performing lazy evaluation: @lisp @@ -25217,7 +25217,7 @@ arguments and to force these thunks later. A thunk must package an expression together with the environment, so that the argument can be produced later. To force the thunk, we simply extract the expression and environment from the thunk and evaluate the expression in the environment. We use -@t{actual-value} rather than @t{eval} so that in case the value of the +@code{actual-value} rather than @code{eval} so that in case the value of the expression is itself a thunk, we will force that, and so on, until we reach something that is not a thunk: @@ -25246,18 +25246,18 @@ follows: Actually, what we want for our interpreter is not quite this, but rather thunks that have been memoized. When a thunk is forced, we will turn it into an evaluated thunk by replacing the stored expression with its value and changing -the @t{thunk} tag so that it can be recognized as already -evaluated.@footnote{Notice that we also erase the @t{env} from the thunk +the @code{thunk} tag so that it can be recognized as already +evaluated.@footnote{Notice that we also erase the @code{env} from the thunk once the expression's value has been computed. This makes no difference in the values returned by the interpreter. It does help save space, however, because -removing the reference from the thunk to the @t{env} once it is no longer +removing the reference from the thunk to the @code{env} once it is no longer needed allows this structure to be @newterm{garbage-collected} and its space recycled, as we will discuss in @ref{5.3}. Similarly, we could have allowed unneeded environments in the memoized delayed objects of @ref{3.5.1} to be garbage-collected, by having -@t{memo-proc} do something like @t{(set! proc '())} to discard the -procedure @t{proc} (which includes the environment in which the @t{delay} +@code{memo-proc} do something like @code{(set! proc '())} to discard the +procedure @code{proc} (which includes the environment in which the @code{delay} was evaluated) after storing its value.} @lisp @@ -25271,9 +25271,9 @@ was evaluated) after storing its value.} (thunk-exp obj) (thunk-env obj)))) (set-car! obj 'evaluated-thunk) - ;; @r{replace @t{exp} with its value:} + ;; @r{replace @code{exp} with its value:} (set-car! (cdr obj) result) - ;; @r{forget unneeded @t{env}:} + ;; @r{forget unneeded @code{env}:} (set-cdr! (cdr obj) '()) result)) ((evaluated-thunk? obj) @@ -25282,7 +25282,7 @@ was evaluated) after storing its value.} @end lisp @noindent -Notice that the same @t{delay-it} procedure works both with and without +Notice that the same @code{delay-it} procedure works both with and without memoization. @quotation @@ -25317,16 +25317,16 @@ count @end quotation @quotation -@strong{@anchor{Exercise 4.28}Exercise 4.28:} @t{Eval} uses -@t{actual-value} rather than @t{eval} to evaluate the operator before -passing it to @t{apply}, in order to force the value of the operator. Give +@strong{@anchor{Exercise 4.28}Exercise 4.28:} @code{Eval} uses +@code{actual-value} rather than @code{eval} to evaluate the operator before +passing it to @code{apply}, in order to force the value of the operator. Give an example that demonstrates the need for this forcing. @noindent @strong{@anchor{Exercise 4.29}Exercise 4.29:} Exhibit a program that you would expect to run much more slowly without memoization than with memoization. -Also, consider the following interaction, where the @t{id} procedure is -defined as in @ref{Exercise 4.27} and @t{count} starts at 0: +Also, consider the following interaction, where the @code{id} procedure is +defined as in @ref{Exercise 4.27} and @code{count} starts at 0: @lisp (define (square x) (* x x)) @@ -25352,8 +25352,8 @@ is there only for its effect, such as assigning to a variable or printing), there can be no subsequent use of this value (e.g., as an argument to a primitive procedure) that will cause it to be forced. Cy thus thinks that when evaluating sequences, we must force all expressions in the sequence except the -final one. He proposes to modify @t{eval-sequence} from @ref{4.1.1} -to use @t{actual-value} rather than @t{eval}: +final one. He proposes to modify @code{eval-sequence} from @ref{4.1.1} +to use @code{actual-value} rather than @code{eval}: @lisp (define (eval-sequence exps env) @@ -25369,7 +25369,7 @@ to use @t{actual-value} rather than @t{eval}: @enumerate a @item -Ben Bitdiddle thinks Cy is wrong. He shows Cy the @t{for-each} procedure +Ben Bitdiddle thinks Cy is wrong. He shows Cy the @code{for-each} procedure described in @ref{Exercise 2.23}, which gives an important example of a sequence with side effects: @@ -25384,7 +25384,7 @@ sequence with side effects: @end lisp He claims that the evaluator in the text (with the original -@t{eval-@/sequence}) handles this correctly: +@code{eval-@/sequence}) handles this correctly: @lisp @i{;;; L-Eval input:} @@ -25398,12 +25398,12 @@ He claims that the evaluator in the text (with the original @i{done} @end lisp -Explain why Ben is right about the behavior of @t{for-each}. +Explain why Ben is right about the behavior of @code{for-each}. @item -Cy agrees that Ben is right about the @t{for-each} example, but says that +Cy agrees that Ben is right about the @code{for-each} example, but says that that's not the kind of program he was thinking about when he proposed his -change to @t{eval-sequence}. He defines the following two procedures in the +change to @code{eval-sequence}. He defines the following two procedures in the lazy evaluator: @lisp @@ -25414,12 +25414,12 @@ lazy evaluator: (p (set! x (cons x '(2))))) @end lisp -What are the values of @t{(p1 1)} and @t{(p2 1)} with the original -@t{eval-@/sequence}? What would the values be with Cy's proposed change to -@t{eval-@/sequence}? +What are the values of @code{(p1 1)} and @code{(p2 1)} with the original +@code{eval-@/sequence}? What would the values be with Cy's proposed change to +@code{eval-@/sequence}? @item -Cy also points out that changing @t{eval-sequence} as he proposes does not +Cy also points out that changing @code{eval-sequence} as he proposes does not affect the behavior of the example in part a. Explain why this is true. @item @@ -25445,16 +25445,16 @@ between delaying with and without memoization. For example, the definition @end lisp @noindent -would define @t{f} to be a procedure of four arguments, where the first and +would define @code{f} to be a procedure of four arguments, where the first and third arguments are evaluated when the procedure is called, the second argument is delayed, and the fourth argument is both delayed and memoized. Thus, ordinary procedure definitions will produce the same behavior as ordinary -Scheme, while adding the @t{lazy-memo} declaration to each parameter of +Scheme, while adding the @code{lazy-memo} declaration to each parameter of every compound procedure will produce the behavior of the lazy evaluator defined in this section. Design and implement the changes required to produce such an extension to Scheme. You will have to implement new syntax procedures -to handle the new syntax for @t{define}. You must also arrange for -@t{eval} or @t{apply} to determine when arguments are to be delayed, and +to handle the new syntax for @code{define}. You must also arrange for +@code{eval} or @code{apply} to determine when arguments are to be delayed, and to force or delay arguments accordingly, and you must arrange for forcing to memoize or not, as appropriate. @end quotation @@ -25463,30 +25463,30 @@ memoize or not, as appropriate. @subsection Streams as Lazy Lists In @ref{3.5.1}, we showed how to implement streams as delayed lists. -We introduced special forms @t{delay} and @t{cons-stream}, which allowed -us to construct a ``promise'' to compute the @t{cdr} of a stream, without +We introduced special forms @code{delay} and @code{cons-stream}, which allowed +us to construct a ``promise'' to compute the @code{cdr} of a stream, without actually fulfilling that promise until later. We could use this general technique of introducing special forms whenever we need more control over the evaluation process, but this is awkward. For one thing, a special form is not a first-class object like a procedure, so we cannot use it together with higher-order procedures.@footnote{This is precisely the issue with the -@t{unless} procedure, as in @ref{Exercise 4.26}.} Additionally, we were +@code{unless} procedure, as in @ref{Exercise 4.26}.} Additionally, we were forced to create streams as a new kind of data object similar but not identical to lists, and this required us to reimplement many ordinary list operations -(@t{map}, @t{append}, and so on) for use with streams. +(@code{map}, @code{append}, and so on) for use with streams. With lazy evaluation, streams and lists can be identical, so there is no need for special forms or for separate list and stream operations. All we need to -do is to arrange matters so that @t{cons} is non-strict. One way to +do is to arrange matters so that @code{cons} is non-strict. One way to accomplish this is to extend the lazy evaluator to allow for non-strict -primitives, and to implement @t{cons} as one of these. An easier way is to +primitives, and to implement @code{cons} as one of these. An easier way is to recall (@ref{2.1.3}) that there is no fundamental need to implement -@t{cons} as a primitive at all. Instead, we can represent pairs as +@code{cons} as a primitive at all. Instead, we can represent pairs as procedures:@footnote{This is the procedural representation described in @ref{Exercise 2.4}. Essentially any procedural representation (e.g., a message-passing implementation) would do as well. Notice that we can install these definitions in the lazy evaluator simply by typing them at the driver -loop. If we had originally included @t{cons}, @t{car}, and @t{cdr} as +loop. If we had originally included @code{cons}, @code{car}, and @code{cdr} as primitives in the global environment, they will be redefined. (Also see @ref{Exercise 4.33} and @ref{Exercise 4.34}.)} @@ -25533,18 +25533,18 @@ examples: @noindent Note that these lazy lists are even lazier than the streams of @ref{Chapter 3}: -The @t{car} of the list, as well as the @t{cdr}, is +The @code{car} of the list, as well as the @code{cdr}, is delayed.@footnote{This permits us to create delayed versions of more general kinds of list structures, not just sequences. @ref{Hughes 1990} discusses some -applications of ``lazy trees.''} In fact, even accessing the @t{car} or -@t{cdr} of a lazy pair need not force the value of a list element. The +applications of ``lazy trees.''} In fact, even accessing the @code{car} or +@code{cdr} of a lazy pair need not force the value of a list element. The value will be forced only when it is really needed---e.g., for use as the argument of a primitive, or to be printed as an answer. Lazy pairs also help with the problem that arose with streams in @ref{3.5.4}, where we found that formulating stream models of systems with -loops may require us to sprinkle our programs with explicit @t{delay} -operations, beyond the ones supplied by @t{cons-stream}. With lazy +loops may require us to sprinkle our programs with explicit @code{delay} +operations, beyond the ones supplied by @code{cons-stream}. With lazy evaluation, all arguments to procedures are delayed uniformly. For instance, we can implement procedures to integrate lists and solve differential equations as we originally intended in @ref{3.5.4}: @@ -25583,8 +25583,8 @@ implementation given above by evaluating the expression To his surprise, this produces an error. After some thought, he realizes that the ``lists'' obtained by reading in quoted expressions are different from the -lists manipulated by the new definitions of @t{cons}, @t{car}, and -@t{cdr}. Modify the evaluator's treatment of quoted expressions so that +lists manipulated by the new definitions of @code{cons}, @code{car}, and +@code{cdr}. Modify the evaluator's treatment of quoted expressions so that quoted lists typed at the driver loop will produce true lazy lists. @end quotation @@ -25633,8 +25633,8 @@ expressed by following procedure: It might seem as if this procedure merely restates the problem, rather than specifying a way to solve it. Nevertheless, this is a legitimate nondeterministic program.@footnote{We assume that we have previously defined a -procedure @t{prime?} that tests whether numbers are prime. Even with -@t{prime?} defined, the @t{prime-sum-pair} procedure may look +procedure @code{prime?} that tests whether numbers are prime. Even with +@code{prime?} defined, the @code{prime-sum-pair} procedure may look suspiciously like the unhelpful ``pseudo-Lisp'' attempt to define the square-root function, which we described at the beginning of @ref{1.1.7}. In fact, a square-root procedure along those lines can actually @@ -25644,7 +25644,7 @@ declarative descriptions and imperative specifications of how to compute answers. We'll go even farther in this direction in @ref{4.4}.} The key idea here is that expressions in a nondeterministic language can have -more than one possible value. For instance, @t{an-element-of} might return +more than one possible value. For instance, @code{an-element-of} might return any element of the given list. Our nondeterministic program evaluator will work by automatically choosing a possible value and keeping track of the choice. If a subsequent requirement is not met, the evaluator will try a @@ -25668,10 +25668,10 @@ possible execution histories. When we reach a dead end, we can revisit a previous choice point and proceed along a different branch. The nondeterministic program evaluator implemented below is called the -@t{amb} evaluator because it is based on a new special form called -@t{amb}. We can type the above definition of @t{prime-sum-pair} at the -@t{amb} evaluator driver loop (along with definitions of @t{prime?}, -@t{an-element-of}, and @t{require}) and run the procedure as follows: +@code{amb} evaluator because it is based on a new special form called +@code{amb}. We can type the above definition of @code{prime-sum-pair} at the +@code{amb} evaluator driver loop (along with definitions of @code{prime?}, +@code{an-element-of}, and @code{require}) and run the procedure as follows: @lisp @i{;;; Amb-Eval input:} @@ -25685,23 +25685,23 @@ The nondeterministic program evaluator implemented below is called the The value returned was obtained after the evaluator repeatedly chose elements from each of the lists, until a successful choice was made. -@ref{4.3.1} introduces @t{amb} and explains how it supports +@ref{4.3.1} introduces @code{amb} and explains how it supports nondeterminism through the evaluator's automatic search mechanism. @ref{4.3.2} presents examples of nondeterministic programs, and -@ref{4.3.3} gives the details of how to implement the @t{amb} evaluator by +@ref{4.3.3} gives the details of how to implement the @code{amb} evaluator by modifying the ordinary Scheme evaluator. @menu * 4-3-1:: Amb and Search * 4-3-2:: Examples of Nondeterministic Programs -* 4-3-3:: Implementing the @t{Amb} Evaluator +* 4-3-3:: Implementing the @code{Amb} Evaluator @end menu @node 4.3.1, 4.3.2, 4.3, 4.3 @subsection Amb and Search To extend Scheme to support nondeterminism, we introduce a new special form -called @t{amb}.@footnote{The idea of @t{amb} for nondeterministic +called @code{amb}.@footnote{The idea of @code{amb} for nondeterministic programming was first described in 1961 by John McCarthy (see @ref{McCarthy 1967}).} The expression @@ -25721,17 +25721,17 @@ returns the value of one of the @math{n} expressions @math{\langle}@math{e_i}@ma can have six possible values: @example -@t{(1 a)} @t{(1 b)} @t{(2 a)} @t{(2 b)} @t{(3 a)} @t{(3 b)} +@code{(1 a)} @code{(1 b)} @code{(2 a)} @code{(2 b)} @code{(3 a)} @code{(3 b)} @end example @noindent -@t{Amb} with a single choice produces an ordinary (single) value. +@code{Amb} with a single choice produces an ordinary (single) value. -@t{Amb} with no choices---the expression @t{(amb)}---is an expression -with no acceptable values. Operationally, we can think of @t{(amb)} as an +@code{Amb} with no choices---the expression @code{(amb)}---is an expression +with no acceptable values. Operationally, we can think of @code{(amb)} as an expression that when evaluated causes the computation to ``fail'': The computation aborts and no value is produced. Using this idea, we can express -the requirement that a particular predicate expression @t{p} must be true as +the requirement that a particular predicate expression @code{p} must be true as follows: @lisp @@ -25740,7 +25740,7 @@ follows: @end lisp @noindent -With @t{amb} and @t{require}, we can implement the @t{an-@/element-@/of} +With @code{amb} and @code{require}, we can implement the @code{an-@/element-@/of} procedure used above: @lisp @@ -25751,7 +25751,7 @@ procedure used above: @end lisp @noindent -@t{An-element-of} fails if the list is empty. Otherwise it ambiguously +@code{An-element-of} fails if the list is empty. Otherwise it ambiguously returns either the first element of the list or an element chosen from the rest of the list. @@ -25764,10 +25764,10 @@ potentially returns any integer greater than or equal to some given @math{n}: @end lisp @noindent -This is like the stream procedure @t{integers-starting-from} described in +This is like the stream procedure @code{integers-starting-from} described in @ref{3.5.2}, but with an important difference: The stream procedure returns an object that represents the sequence of all integers beginning with -@math{n}, whereas the @t{amb} procedure returns a single integer.@footnote{In +@math{n}, whereas the @code{amb} procedure returns a single integer.@footnote{In actuality, the distinction between nondeterministically returning a single choice and returning all choices depends somewhat on our point of view. From the perspective of the code that uses the value, the nondeterministic choice @@ -25775,13 +25775,13 @@ returns a single value. From the perspective of the programmer designing the code, the nondeterministic choice potentially returns all possible values, and the computation branches so that each value is investigated separately.} -Abstractly, we can imagine that evaluating an @t{amb} expression causes time +Abstractly, we can imagine that evaluating an @code{amb} expression causes time to split into branches, where the computation continues on each branch with one -of the possible values of the expression. We say that @t{amb} represents a +of the possible values of the expression. We say that @code{amb} represents a @newterm{nondeterministic choice point}. If we had a machine with a sufficient number of processors that could be dynamically allocated, we could implement the search in a straightforward way. Execution would proceed as in a -sequential machine, until an @t{amb} expression is encountered. At this +sequential machine, until an @code{amb} expression is encountered. At this point, more processors would be allocated and initialized to continue all of the parallel executions implied by the choice. Each processor would proceed sequentially as if it were the only choice, until it either terminates by @@ -25801,10 +25801,10 @@ could imagine modifying an evaluator to pick at random a branch to follow whenever it encounters a choice point. Random choice, however, can easily lead to failing values. We might try running the evaluator over and over, making random choices and hoping to find a non-failing value, but it is better to -@newterm{systematically search} all possible execution paths. The @t{amb} +@newterm{systematically search} all possible execution paths. The @code{amb} evaluator that we will develop and work with in this section implements a systematic search as follows: When the evaluator encounters an application of -@t{amb}, it initially selects the first alternative. This selection may +@code{amb}, it initially selects the first alternative. This selection may itself lead to a further choice. The evaluator will always initially choose the first alternative at each choice point. If a choice results in a failure, then the evaluator automagically@footnote{Automagically: ``Automatically, but @@ -25844,19 +25844,19 @@ systems all use some form of truth-maintenance system as a substrate. See @ref{Forbus and deKleer 1993} for a discussion of elegant ways to build truth-maintenance systems and applications using truth maintenance. @ref{Zabih et al. 1987} describes a nondeterministic extension to Scheme -that is based on @t{amb}; it is similar to the interpreter described in this +that is based on @code{amb}; it is similar to the interpreter described in this section, but more sophisticated, because it uses dependency-directed backtracking rather than chronological backtracking. @ref{Winston 1992} gives an introduction to both kinds of backtracking.} @subsubheading Driver loop -The driver loop for the @t{amb} evaluator has some unusual properties. It +The driver loop for the @code{amb} evaluator has some unusual properties. It reads an expression and prints the value of the first non-failing execution, as -in the @t{prime-sum-pair} example shown above. If we want to see the value +in the @code{prime-sum-pair} example shown above. If we want to see the value of the next successful execution, we can ask the interpreter to backtrack and attempt to generate a second non-failing execution. This is signaled by typing -the symbol @t{try-again}. If any expression except @t{try-again} is +the symbol @code{try-again}. If any expression except @code{try-again} is given, the interpreter will start a new problem, discarding the unexplored alternatives in the previous problem. Here is a sample interaction: @@ -25889,7 +25889,7 @@ try-again @quotation @strong{@anchor{Exercise 4.35}Exercise 4.35:} Write a procedure -@t{an-integer-between} that returns an integer between two given bounds. +@code{an-integer-between} that returns an integer between two given bounds. This can be used to implement a procedure that finds Pythagorean triples, i.e., triples of integers @math{(i, j, k)} between the given bounds such that @math{i \le j} and @math{i^2 + j^2 = k^2}, as follows: @@ -25912,10 +25912,10 @@ triples of integers @math{(i, j, k)} between the given bounds such that @strong{@anchor{Exercise 4.36}Exercise 4.36:} @ref{Exercise 3.69} discussed how to generate the stream of @emph{all} Pythagorean triples, with no upper bound on the size of the integers to be searched. Explain why simply replacing -@t{an-@/inte-@/ger-@/between} by @t{an-integer-starting-from} in the procedure +@code{an-@/inte-@/ger-@/between} by @code{an-integer-starting-from} in the procedure in @ref{Exercise 4.35} is not an adequate way to generate arbit@-rary Py@-tha@-go@-rean triples. Write a procedure that actually will accomplish this. (That is, -write a procedure for which repeatedly typing @t{try-@/again} would in +write a procedure for which repeatedly typing @code{try-@/again} would in principle eventually generate all Py@-tha@-go@-rean triples.) @end quotation @@ -25945,7 +25945,7 @@ possibilities that must be explored.) @node 4.3.2, 4.3.3, 4.3.1, 4.3 @subsection Examples of Nondeterministic Programs -@ref{4.3.3} describes the implementation of the @t{amb} evaluator. +@ref{4.3.3} describes the implementation of the @code{amb} evaluator. First, however, we give some examples of how it can be used. The advantage of nondeterministic programming is that we can suppress the details of how search is carried out, thereby expressing our programs at a higher level of @@ -25979,8 +25979,8 @@ the elements of a list are distinct: (else (distinct? (cdr items))))) @end lisp -@t{Member} is like @t{memq} except that it uses @t{equal?} instead -of @t{eq?} to test for equality.} +@code{Member} is like @code{memq} except that it uses @code{equal?} instead +of @code{eq?} to test for equality.} @lisp (define (multiple-dwelling) @@ -26009,7 +26009,7 @@ of @t{eq?} to test for equality.} @end lisp @noindent -Evaluating the expression @t{(multiple-dwelling)} produces the result +Evaluating the expression @code{(multiple-dwelling)} produces the result @lisp ((baker 3) (cooper 2) (fletcher 4) @@ -26045,7 +26045,7 @@ thus be imposed before floors have been selected for all the people. Write and demonstrate a much more efficient nondeterministic procedure that solves this problem based upon generating only those possibilities that are not already ruled out by previous restrictions. (Hint: This will require a nest of -@t{let} expressions.) +@code{let} expressions.) @end quotation @quotation @@ -26086,7 +26086,7 @@ What in fact was the order in which the five girls were placed? @end quotation @quotation -@strong{@anchor{Exercise 4.43}Exercise 4.43:} Use the @t{amb} evaluator to +@strong{@anchor{Exercise 4.43}Exercise 4.43:} Use the @code{amb} evaluator to solve the following puzzle:@footnote{This is taken from a booklet called ``Problematical Recreations,'' published in the 1960s by Litton Industries, where it is attributed to the @cite{Kansas State Engineer}.} @@ -26149,7 +26149,7 @@ a noun. With this grammar, the sentence ``The cat eats'' is parsed as follows: We can generate such a parse with a simple program that has separate procedures for each of the grammatical rules. To parse a sentence, we identify its two constituent pieces and return a list of these two elements, tagged with the -symbol @t{sentence}: +symbol @code{sentence}: @lisp (define (parse-sentence) @@ -26172,14 +26172,14 @@ noun: @noindent At the lowest level, parsing boils down to repeatedly checking that the next unparsed word is a member of the list of words for the required part of speech. -To implement this, we maintain a global variable @t{*unparsed*}, which is +To implement this, we maintain a global variable @code{*unparsed*}, which is the input that has not yet been parsed. Each time we check a word, we require -that @t{*unparsed*} must be non-empty and that it should begin with a word -from the designated list. If so, we remove that word from @t{*unparsed*} +that @code{*unparsed*} must be non-empty and that it should begin with a word +from the designated list. If so, we remove that word from @code{*unparsed*} and return the word together with its part of speech (which is found at the -head of the list):@footnote{Notice that @t{parse-word} uses @t{set!} to -modify the unparsed input list. For this to work, our @t{amb} evaluator -must undo the effects of @t{set!} operations when it backtracks.} +head of the list):@footnote{Notice that @code{parse-word} uses @code{set!} to +modify the unparsed input list. For this to work, our @code{amb} evaluator +must undo the effects of @code{set!} operations when it backtracks.} @lisp (define (parse-word word-list) @@ -26192,7 +26192,7 @@ must undo the effects of @t{set!} operations when it backtracks.} @end lisp @noindent -To start the parsing, all we need to do is set @t{*unparsed*} to be the +To start the parsing, all we need to do is set @code{*unparsed*} to be the entire input, try to parse a sentence, and check that nothing is left over: @lisp @@ -26219,8 +26219,8 @@ sentence: @end lisp @noindent -The @t{amb} evaluator is useful here because it is convenient to express the -parsing constraints with the aid of @t{require}. Automatic search and +The @code{amb} evaluator is useful here because it is convenient to express the +parsing constraints with the aid of @code{require}. Automatic search and backtracking really pay off, however, when we consider more complex grammars where there are choices for how the units can be decomposed. @@ -26378,7 +26378,7 @@ explain the differences in shades of meaning among them. @quotation @strong{@anchor{Exercise 4.46}Exercise 4.46:} The evaluators in @ref{4.1} and @ref{4.2} do not determine what order operands are evaluated in. -We will see that the @t{amb} evaluator evaluates them from left to right. +We will see that the @code{amb} evaluator evaluates them from left to right. Explain why our parsing program wouldn't work if the operands were evaluated in some other order. @end quotation @@ -26387,7 +26387,7 @@ some other order. @strong{@anchor{Exercise 4.47}Exercise 4.47:} Louis Reasoner suggests that, since a verb phrase is either a verb or a verb phrase followed by a prepositional phrase, it would be much more straightforward to define the -procedure @t{parse-verb-phrase} as follows (and similarly for noun phrases): +procedure @code{parse-verb-phrase} as follows (and similarly for noun phrases): @lisp (define (parse-verb-phrase) @@ -26399,7 +26399,7 @@ procedure @t{parse-verb-phrase} as follows (and similarly for noun phrases): @end lisp Does this work? Does the program's behavior change if we interchange the order -of expressions in the @t{amb}? +of expressions in the @code{amb}? @end quotation @quotation @@ -26419,7 +26419,7 @@ grammars to command languages.} @quotation @strong{@anchor{Exercise 4.49}Exercise 4.49:} Alyssa P. Hacker is more interested in generating interesting sentences than in parsing them. She -reasons that by simply changing the procedure @t{parse-word} so that it +reasons that by simply changing the procedure @code{parse-word} so that it ignores the ``input sentence'' and instead always succeeds and generates an appropriate word, we can use the programs we had built for parsing to do generation instead. Implement Alyssa's idea, and show the first half-dozen or @@ -26432,7 +26432,7 @@ for a way to deal with this.} @end quotation @node 4.3.3, , 4.3.2, 4.3 -@subsection Implementing the @t{Amb} Evaluator +@subsection Implementing the @code{Amb} Evaluator The evaluation of an ordinary Scheme expression may return a value, may never terminate, or may signal an error. In nondeterministic Scheme the evaluation @@ -26440,11 +26440,11 @@ of an expression may in addition result in the discovery of a dead end, in which case evaluation must backtrack to a previous choice point. The interpretation of nondeterministic Scheme is complicated by this extra case. -We will construct the @t{amb} evaluator for nondeterministic Scheme by +We will construct the @code{amb} evaluator for nondeterministic Scheme by modifying the analyzing evaluator of @ref{4.1.7}.@footnote{We chose to implement the lazy evaluator in @ref{4.2} as a modification of the ordinary metacircular evaluator of @ref{4.1.1}. In contrast, we will -base the @t{amb} evaluator on the analyzing evaluator of +base the @code{amb} evaluator on the analyzing evaluator of @ref{4.1.7}, because the execution procedures in that evaluator provide a convenient framework for implementing backtracking.} As in the analyzing evaluator, evaluation of an expression is accomplished by calling an execution @@ -26456,7 +26456,7 @@ Scheme will be entirely in the execution procedures. Recall that the execution procedures for the ordinary evaluator take one argument: the environment of execution. In contrast, the execution procedures -in the @t{amb} evaluator take three arguments: the environment, and two +in the @code{amb} evaluator take three arguments: the environment, and two procedures called @newterm{continuation procedures}. The evaluation of an expression will finish by calling one of these two continuations: If the evaluation results in a value, the @newterm{success continuation} is called @@ -26482,13 +26482,13 @@ that can be called later to choose a different alternative. A failure is triggered during evaluation (that is, a failure continuation is called) when a user program explicitly rejects the current line of attack (for -example, a call to @t{require} may result in execution of @t{(amb)}, an +example, a call to @code{require} may result in execution of @code{(amb)}, an expression that always fails---see @ref{4.3.1}). The failure continuation in hand at that point will cause the most recent choice point to choose another alternative. If there are no more alternatives to be considered at that choice point, a failure at an earlier choice point is triggered, and so on. Failure continuations are also invoked by the driver loop in response to a -@t{try-again} request, to find another value of the expression. +@code{try-again} request, to find another value of the expression. In addition, if a side-effect operation (such as assignment to a variable) occurs on a branch of the process resulting from a choice, it may be necessary, @@ -26501,8 +26501,8 @@ In summary, failure continuations are constructed by @itemize @bullet @item -@t{amb} expressions---to provide a mechanism to make alternative choices if -the current choice made by the @t{amb} expression leads to a dead end; +@code{amb} expressions---to provide a mechanism to make alternative choices if +the current choice made by the @code{amb} expression leads to a dead end; @item the top-level driver---to provide a mechanism to report failure when the @@ -26519,10 +26519,10 @@ Failures are initiated only when a dead end is encountered. This occurs @itemize @bullet @item -if the user program executes @t{(amb)}; +if the user program executes @code{(amb)}; @item -if the user types @t{try-again} at the top-level driver. +if the user types @code{try-again} at the top-level driver. @end itemize @@ -26538,19 +26538,19 @@ the failure back to the choice point that led to this assignment or to the top level. @item -When the failure continuation for an @t{amb} runs out of choices, it calls -the failure continuation that was originally given to the @t{amb}, in order +When the failure continuation for an @code{amb} runs out of choices, it calls +the failure continuation that was originally given to the @code{amb}, in order to propagate the failure back to the previous choice point or to the top level. @end itemize @subsubheading Structure of the evaluator -The syntax- and data-representation procedures for the @t{amb} evaluator, -and also the basic @t{analyze} procedure, are identical to those in the +The syntax- and data-representation procedures for the @code{amb} evaluator, +and also the basic @code{analyze} procedure, are identical to those in the evaluator of @ref{4.1.7}, except for the fact that we need additional -syntax procedures to recognize the @t{amb} special form:@footnote{We assume -that the evaluator supports @t{let} (see @ref{Exercise 4.22}), which we have +syntax procedures to recognize the @code{amb} special form:@footnote{We assume +that the evaluator supports @code{let} (see @ref{Exercise 4.22}), which we have used in our nondeterministic programs.} @lisp @@ -26559,7 +26559,7 @@ used in our nondeterministic programs.} @end lisp @noindent -We must also add to the dispatch in @t{analyze} a clause that will recognize +We must also add to the dispatch in @code{analyze} a clause that will recognize this special form and generate an appropriate execution procedure: @lisp @@ -26567,7 +26567,7 @@ this special form and generate an appropriate execution procedure: @end lisp @noindent -The top-level procedure @t{ambeval} (similar to the version of @t{eval} +The top-level procedure @code{ambeval} (similar to the version of @code{eval} given in @ref{4.1.7}) analyzes the given expression and applies the resulting execution procedure to the given environment, together with two given continuations: @@ -26585,8 +26585,8 @@ form of an execution procedure is @lisp (lambda (env succeed fail) - @r{;; @t{succeed} is @t{(lambda (value fail) @dots{})}} - @r{;; @t{fail} is @t{(lambda () @dots{})}} + @r{;; @code{succeed} is @code{(lambda (value fail) @dots{})}} + @r{;; @code{fail} is @code{(lambda () @dots{})}} @dots{}) @end lisp @@ -26602,12 +26602,12 @@ For example, executing @noindent will attempt to evaluate the given expression and will return either the -expression's value (if the evaluation succeeds) or the symbol @t{failed} (if -the evaluation fails). The call to @t{ambeval} in the driver loop shown +expression's value (if the evaluation succeeds) or the symbol @code{failed} (if +the evaluation fails). The call to @code{ambeval} in the driver loop shown below uses much more complicated continuation procedures, which continue the -loop and support the @t{try-again} request. +loop and support the @code{try-again} request. -Most of the complexity of the @t{amb} evaluator results from the mechanics +Most of the complexity of the @code{amb} evaluator results from the mechanics of passing the continuations around as the execution procedures call each other. In going through the following code, you should compare each of the execution procedures with the corresponding procedure for the ordinary @@ -26643,7 +26643,7 @@ expression, passing along the failure continuation that was passed to them. @noindent Notice that looking up a variable always `succeeds.' If -@t{lookup-@/variable-@/value} fails to find the variable, it signals an error, +@code{lookup-@/variable-@/value} fails to find the variable, it signals an error, as usual. Such a ``failure'' indicates a program bug---a reference to an unbound variable; it is not an indication that we should try another nondeterministic choice instead of the one that is currently being tried. @@ -26651,11 +26651,11 @@ nondeterministic choice instead of the one that is currently being tried. @subsubheading Conditionals and sequences Conditionals are also handled in a similar way as in the ordinary evaluator. -The execution procedure generated by @t{analyze-if} invokes the predicate -execution procedure @t{pproc} with a success continuation that checks +The execution procedure generated by @code{analyze-if} invokes the predicate +execution procedure @code{pproc} with a success continuation that checks whether the predicate value is true and goes on to execute either the -consequent or the alternative. If the execution of @t{pproc} fails, the -original failure continuation for the @t{if} expression is called. +consequent or the alternative. If the execution of @code{pproc} fails, the +original failure continuation for the @code{if} expression is called. @lisp (define (analyze-if exp) @@ -26665,7 +26665,7 @@ original failure continuation for the @t{if} expression is called. (lambda (env succeed fail) (pproc env @r{;; success continuation for evaluating} - @r{;; the predicate to obtain @t{pred-value}} + @r{;; the predicate to obtain @code{pred-value}} (lambda (pred-value fail2) (if (true? pred-value) (cproc env succeed fail2) @@ -26677,20 +26677,20 @@ original failure continuation for the @t{if} expression is called. @noindent Sequences are also handled in the same way as in the previous evaluator, except -for the machinations in the subprocedure @t{sequentially} that are required -for passing the continuations. Namely, to sequentially execute @t{a} and -then @t{b}, we call @t{a} with a success continuation that calls -@t{b}. +for the machinations in the subprocedure @code{sequentially} that are required +for passing the continuations. Namely, to sequentially execute @code{a} and +then @code{b}, we call @code{a} with a success continuation that calls +@code{b}. @lisp (define (analyze-sequence exps) (define (sequentially a b) (lambda (env succeed fail) (a env - @r{;; success continuation for calling @t{a}} + @r{;; success continuation for calling @code{a}} (lambda (a-value fail2) (b env succeed fail2)) - @r{;; failure continuation for calling @t{a}} + @r{;; failure continuation for calling @code{a}} fail))) (define (loop first-proc rest-procs) (if (null? rest-procs) @@ -26709,9 +26709,9 @@ then @t{b}, we call @t{a} with a success continuation that calls Definitions are another case where we must go to some trouble to manage the continuations, because it is necessary to evaluate the definition-value expression before actually defining the new variable. To accomplish this, the -definition-value execution procedure @t{vproc} is called with the +definition-value execution procedure @code{vproc} is called with the environment, a success continuation, and the failure continuation. If the -execution of @t{vproc} succeeds, obtaining a value @t{val} for the +execution of @code{vproc} succeeds, obtaining a value @code{val} for the defined variable, the variable is defined and the success is propagated: @lisp @@ -26732,24 +26732,24 @@ Assignments are more interesting. This is the first place where we really use the continuations, rather than just passing them around. The execution procedure for assignments starts out like the one for definitions. It first attempts to obtain the new value to be assigned to the variable. If this -evaluation of @t{vproc} fails, the assignment fails. +evaluation of @code{vproc} fails, the assignment fails. -If @t{vproc} succeeds, however, and we go on to make the assignment, we must +If @code{vproc} succeeds, however, and we go on to make the assignment, we must consider the possibility that this branch of the computation might later fail, which will require us to backtrack out of the assignment. Thus, we must arrange to undo the assignment as part of the backtracking process.@footnote{We didn't worry about undoing definitions, since we can assume that internal definitions are scanned out (@ref{4.1.6}).} -This is accomplished by giving @t{vproc} a success continuation (marked with +This is accomplished by giving @code{vproc} a success continuation (marked with the comment ``*1*'' below) that saves the old value of the variable before assigning the new value to the variable and proceeding from the assignment. The failure continuation that is passed along with the value of the assignment (marked with the comment ``*2*'' below) restores the old value of the variable before continuing the failure. That is, a successful assignment provides a failure continuation that will intercept a subsequent failure; whatever failure -would otherwise have called @t{fail2} calls this procedure instead, to undo -the assignment before actually calling @t{fail2}. +would otherwise have called @code{fail2} calls this procedure instead, to undo +the assignment before actually calling @code{fail2}. @lisp (define (analyze-assignment exp) @@ -26781,10 +26781,10 @@ the assignment before actually calling @t{fail2}. The execution procedure for applications contains no new ideas except for the technical complexity of managing the continuations. This complexity arises in -@t{analyze-application}, due to the need to keep track of the success and +@code{analyze-application}, due to the need to keep track of the success and failure continuations as we evaluate the operands. We use a procedure -@t{get-args} to evaluate the list of operands, rather than a simple -@t{map} as in the ordinary evaluator. +@code{get-args} to evaluate the list of operands, rather than a simple +@code{map} as in the ordinary evaluator. @lisp (define (analyze-application exp) @@ -26804,12 +26804,12 @@ failure continuations as we evaluate the operands. We use a procedure @end lisp @noindent -In @t{get-args}, notice how @t{cdr}-ing down the list of @t{aproc} -execution procedures and @t{cons}ing up the resulting list of @t{args} is -accomplished by calling each @t{aproc} in the list with a success -continuation that recursively calls @t{get-args}. Each of these recursive -calls to @t{get-args} has a success continuation whose value is the -@t{cons} of the newly obtained argument onto the list of accumulated +In @code{get-args}, notice how @code{cdr}-ing down the list of @code{aproc} +execution procedures and @code{cons}ing up the resulting list of @code{args} is +accomplished by calling each @code{aproc} in the list with a success +continuation that recursively calls @code{get-args}. Each of these recursive +calls to @code{get-args} has a success continuation whose value is the +@code{cons} of the newly obtained argument onto the list of accumulated arguments: @lisp @@ -26818,13 +26818,13 @@ arguments: (succeed '() fail) ((car aprocs) env - ;; @r{success continuation for this @t{aproc}} + ;; @r{success continuation for this @code{aproc}} (lambda (arg fail2) (get-args (cdr aprocs) env ;; @r{success continuation for} - ;; @r{recursive call to @t{get-args}} + ;; @r{recursive call to @code{get-args}} (lambda (args fail3) (succeed (cons arg args) fail3)) @@ -26834,7 +26834,7 @@ arguments: @noindent The actual procedure application, which is performed by -@t{exe@-cute-@/application}, is accomplished in the same way as for the ordinary +@code{exe@-cute-@/application}, is accomplished in the same way as for the ordinary evaluator, except for the need to manage the continuations. @lisp @@ -26858,15 +26858,15 @@ evaluator, except for the need to manage the continuations. proc)))) @end lisp -@subsubheading Evaluating @t{amb} expressions +@subsubheading Evaluating @code{amb} expressions -The @t{amb} special form is the key element in the nondeterministic +The @code{amb} special form is the key element in the nondeterministic language. Here we see the essence of the interpretation process and the reason -for keeping track of the continuations. The execution procedure for @t{amb} -defines a loop @t{try-next} that cycles through the execution procedures for -all the possible values of the @t{amb} expression. Each execution procedure +for keeping track of the continuations. The execution procedure for @code{amb} +defines a loop @code{try-next} that cycles through the execution procedures for +all the possible values of the @code{amb} expression. Each execution procedure is called with a failure continuation that will try the next one. When there -are no more alternatives to try, the entire @t{amb} expression fails. +are no more alternatives to try, the entire @code{amb} expression fails. @lisp (define (analyze-amb exp) @@ -26886,22 +26886,22 @@ are no more alternatives to try, the entire @t{amb} expression fails. @subsubheading Driver loop -The driver loop for the @t{amb} evaluator is complex, due to the mechanism +The driver loop for the @code{amb} evaluator is complex, due to the mechanism that permits the user to try again in evaluating an expression. The driver -uses a procedure called @t{internal-loop}, which takes as argument a -procedure @t{try-again}. The intent is that calling @t{try-again} should +uses a procedure called @code{internal-loop}, which takes as argument a +procedure @code{try-again}. The intent is that calling @code{try-again} should go on to the next untried alternative in the nondeterministic evaluation. -@t{Internal-loop} either calls @t{try-again} in response to the user -typing @t{try-again} at the driver loop, or else starts a new evaluation by -calling @t{ambeval}. +@code{Internal-loop} either calls @code{try-again} in response to the user +typing @code{try-again} at the driver loop, or else starts a new evaluation by +calling @code{ambeval}. -The failure continuation for this call to @t{ambeval} informs the user that +The failure continuation for this call to @code{ambeval} informs the user that there are no more values and re-invokes the driver loop. -The success continuation for the call to @t{ambeval} is more subtle. We +The success continuation for the call to @code{ambeval} is more subtle. We print the obtained value and then invoke the internal loop again with a -@t{try-again} procedure that will be able to try the next alternative. This -@t{next-alternative} procedure is the second argument that was passed to the +@code{try-again} procedure that will be able to try the next alternative. This +@code{next-alternative} procedure is the second argument that was passed to the success continuation. Ordinarily, we think of this second argument as a failure continuation to be used if the current evaluation branch later fails. In this case, however, we have completed a successful evaluation, so we can @@ -26925,14 +26925,14 @@ successful evaluations. (ambeval input the-global-environment - @r{;; @t{ambeval} success} + @r{;; @code{ambeval} success} (lambda (val next-alternative) (announce-output output-prompt) (user-print val) (internal-loop next-alternative)) - @r{;; @t{ambeval} failure} + @r{;; @code{ambeval} failure} (lambda () (announce-output ";;; There are no @@ -26948,21 +26948,21 @@ successful evaluations. @end lisp @noindent -The initial call to @t{internal-loop} uses a @t{try-again} procedure that +The initial call to @code{internal-loop} uses a @code{try-again} procedure that complains that there is no current problem and restarts the driver loop. This -is the behavior that will happen if the user types @t{try-again} when there +is the behavior that will happen if the user types @code{try-again} when there is no evaluation in progress. @quotation @strong{@anchor{Exercise 4.50}Exercise 4.50:} Implement a new special form -@t{ramb} that is like @t{amb} except that it searches alternatives in a +@code{ramb} that is like @code{amb} except that it searches alternatives in a random order, rather than from left to right. Show how this can help with Alyssa's problem in @ref{Exercise 4.49,,Ex. 4.49}. @end quotation @quotation @strong{@anchor{Exercise 4.51}Exercise 4.51:} Implement a new kind of -assignment called @t{permanent-set!} that is not undone upon failure. For +assignment called @code{permanent-set!} that is not undone upon failure. For example, we can choose two distinct elements from a list and count the number of trials required to make a successful choice as follows: @@ -26982,14 +26982,14 @@ try-again @i{(a c 3)} @end lisp -What values would have been displayed if we had used @t{set!} here -rather than @t{permanent-set!}? +What values would have been displayed if we had used @code{set!} here +rather than @code{permanent-set!}? @end quotation @quotation @strong{@anchor{Exercise 4.52}Exercise 4.52:} Implement a new construct called -@t{if-fail} that permits the user to catch the failure of an expression. -@t{If-fail} takes two expressions. It evaluates the first expression as +@code{if-fail} that permits the user to catch the failure of an expression. +@code{If-fail} takes two expressions. It evaluates the first expression as usual and returns as usual if the evaluation succeeds. If the evaluation fails, however, the value of the second expression is returned, as in the following example: @@ -27017,8 +27017,8 @@ following example: @end quotation @quotation -@strong{@anchor{Exercise 4.53}Exercise 4.53:} With @t{permanent-set!} as -described in @ref{Exercise 4.51} and @t{if-fail} as in @ref{Exercise 4.52}, +@strong{@anchor{Exercise 4.53}Exercise 4.53:} With @code{permanent-set!} as +described in @ref{Exercise 4.51} and @code{if-fail} as in @ref{Exercise 4.52}, what will be the result of evaluating @lisp @@ -27036,8 +27036,8 @@ what will be the result of evaluating @quotation @strong{@anchor{Exercise 4.54}Exercise 4.54:} If we had not realized that -@t{require} could be implemented as an ordinary procedure that uses -@t{amb}, to be defined by the user as part of a nondeterministic program, we +@code{require} could be implemented as an ordinary procedure that uses +@code{amb}, to be defined by the user as part of a nondeterministic program, we would have had to implement it as a special form. This would require syntax procedures @@ -27050,15 +27050,15 @@ procedures @end lisp @noindent -and a new clause in the dispatch in @t{analyze} +and a new clause in the dispatch in @code{analyze} @lisp ((require? exp) (analyze-require exp)) @end lisp @noindent -as well the procedure @t{analyze-require} that handles @t{require} -expressions. Complete the following definition of @t{analyze-require}. +as well the procedure @code{analyze-require} that handles @code{require} +expressions. Complete the following definition of @code{analyze-require}. @lisp (define (analyze-require exp) @@ -27142,10 +27142,10 @@ impenetrable Ph.D. thesis. For a history of logic programming, see This approach, when it works, can be a very powerful way to write programs. Part of the power comes from the fact that a single ``what is'' fact can be used to solve a number of different problems that would have different ``how -to'' components. As an example, consider the @t{append} operation, which +to'' components. As an example, consider the @code{append} operation, which takes two lists as arguments and combines their elements to form a single list. -In a procedural language such as Lisp, we could define @t{append} in terms -of the basic list constructor @t{cons}, as we did in @ref{2.2.1}: +In a procedural language such as Lisp, we could define @code{append} in terms +of the basic list constructor @code{cons}, as we did in @ref{2.2.1}: @lisp (define (append x y) @@ -27157,30 +27157,30 @@ of the basic list constructor @t{cons}, as we did in @ref{2.2.1}: @noindent This procedure can be regarded as a translation into Lisp of the following two rules, the first of which covers the case where the first list is empty and the -second of which handles the case of a nonempty list, which is a @t{cons} of +second of which handles the case of a nonempty list, which is a @code{cons} of two parts: @itemize @bullet @item -For any list @t{y}, the empty list and @t{y} @t{append} to form -@t{y}. +For any list @code{y}, the empty list and @code{y} @code{append} to form +@code{y}. @item -For any @t{u}, @t{v}, @t{y}, and @t{z}, @t{(cons u v)} and -@t{y} @t{append} to form @t{(cons u z)} if @t{v} and @t{y} -@t{append} to form @t{z}.@footnote{To see the correspondence between the -rules and the procedure, let @t{x} in the procedure (where @t{x} is -nonempty) correspond to @t{(cons u v)} in the rule. Then @t{z} in the -rule corresponds to the @t{append} of @t{(cdr x)} and @t{y}.} +For any @code{u}, @code{v}, @code{y}, and @code{z}, @code{(cons u v)} and +@code{y} @code{append} to form @code{(cons u z)} if @code{v} and @code{y} +@code{append} to form @code{z}.@footnote{To see the correspondence between the +rules and the procedure, let @code{x} in the procedure (where @code{x} is +nonempty) correspond to @code{(cons u v)} in the rule. Then @code{z} in the +rule corresponds to the @code{append} of @code{(cdr x)} and @code{y}.} @end itemize @noindent -Using the @t{append} procedure, we can answer questions such as +Using the @code{append} procedure, we can answer questions such as @quotation -Find the @t{append} of @t{(a b)} and @t{(c d)}. +Find the @code{append} of @code{(a b)} and @code{(c d)}. @end quotation @noindent @@ -27188,20 +27188,20 @@ But the same two rules are also sufficient for answering the following sorts of questions, which the procedure can't answer: @quotation -Find a list @t{y} that @t{append}s with @t{(a b)} to produce @t{(a +Find a list @code{y} that @code{append}s with @code{(a b)} to produce @code{(a b c d)}. -Find all @t{x} and @t{y} that @t{append} to form @t{(a b c d)}. +Find all @code{x} and @code{y} that @code{append} to form @code{(a b c d)}. @end quotation @noindent -In a logic programming language, the programmer writes an @t{append} -``procedure'' by stating the two rules about @t{append} given above. ``How +In a logic programming language, the programmer writes an @code{append} +``procedure'' by stating the two rules about @code{append} given above. ``How to'' knowledge is provided automatically by the interpreter to allow this single pair of rules to be used to answer all three types of questions about -@t{append}.@footnote{This certainly does not relieve the user of the entire +@code{append}.@footnote{This certainly does not relieve the user of the entire problem of how to compute the answer. There are many different mathematically -equivalent sets of rules for formulating the @t{append} relation, only some +equivalent sets of rules for formulating the @code{append} relation, only some of which can be turned into effective devices for computing in any direction. In addition, sometimes ``what is'' information gives no clue ``how to'' compute an answer. For example, consider the problem of computing the @math{y} such that @@ -27325,7 +27325,7 @@ There is also a programmer trainee, who is supervised by Alyssa: @noindent All of these people are in the computer division, as indicated by the word -@t{computer} as the first item in their job descriptions. +@code{computer} as the first item in their job descriptions. Ben is a high-level employee. His supervisor is the company's big wheel himself: @@ -27422,12 +27422,12 @@ The system will respond with the following items: The input query specifies that we are looking for entries in the data base that match a certain @newterm{pattern}. In this example, the pattern specifies entries consisting of three items, of which the first is the literal symbol -@t{job}, the second can be anything, and the third is the literal list -@t{(computer programmer)}. The ``anything'' that can be the second item in -the matching list is specified by a @newterm{pattern variable}, @t{?x}. The +@code{job}, the second can be anything, and the third is the literal list +@code{(computer programmer)}. The ``anything'' that can be the second item in +the matching list is specified by a @newterm{pattern variable}, @code{?x}. The general form of a pattern variable is a symbol, taken to be the name of the variable, preceded by a question mark. We will see below why it is useful to -specify names for pattern variables rather than just putting @t{?} into +specify names for pattern variables rather than just putting @code{?} into patterns to represent ``anything.'' The system responds to a simple query by showing all entries in the data base that match the specified pattern. @@ -27464,7 +27464,7 @@ The query @noindent matches all job entries whose third item is a two-element list whose first item -is @t{computer}: +is @code{computer}: @lisp (job (Bitdiddle Ben) (computer wizard)) @@ -27485,7 +27485,7 @@ This same pattern does @emph{not} match because the third item in the entry is a list of three elements, and the pattern's third item specifies that there should be two elements. If we wanted to change the pattern so that the third item could be any list beginning with -@t{computer}, we could specify@footnote{This uses the dotted-tail notation +@code{computer}, we could specify@footnote{This uses the dotted-tail notation introduced in @ref{Exercise 2.20}.} @lisp @@ -27507,7 +27507,7 @@ matches the data @end lisp @noindent -with @t{?type} as the list @t{(programmer trainee)}. It also +with @code{?type} as the list @code{(programmer trainee)}. It also matches the data @lisp @@ -27515,14 +27515,14 @@ matches the data @end lisp @noindent -with @t{?type} as the list @t{(programmer)}, and matches the data +with @code{?type} as the list @code{(programmer)}, and matches the data @lisp (computer) @end lisp @noindent -with @t{?type} as the empty list @t{()}. +with @code{?type} as the empty list @code{()}. We can describe the query language's processing of simple queries as follows: @@ -27570,11 +27570,11 @@ Simple queries form the primitive operations of the query language. In order to form compound operations, the query language provides means of combination. One thing that makes the query language a logic programming language is that the means of combination mirror the means of combination used in forming -logical expressions: @t{and}, @t{or}, and @t{not}. (Here @t{and}, -@t{or}, and @t{not} are not the Lisp primitives, but rather operations +logical expressions: @code{and}, @code{or}, and @code{not}. (Here @code{and}, +@code{or}, and @code{not} are not the Lisp primitives, but rather operations built into the query language.) -We can use @t{and} as follows to find the addresses of all the computer +We can use @code{and} as follows to find the addresses of all the computer programmers: @lisp @@ -27610,7 +27610,7 @@ As for simple queries, the system processes a compound query by finding all assignments to the pattern variables that satisfy the query, then displaying instantiations of the query with those values. -Another means of constructing compound queries is through @t{or}. For +Another means of constructing compound queries is through @code{or}. For example, @lisp @@ -27653,7 +27653,7 @@ In general, is satisfied by all sets of values for the pattern variables that satisfy at least one of @math{\langle}@math{quer\!y_1}@math{\rangle} @dots{} @math{\langle}@math{quer\!y_n}@math{\rangle}. -Compound queries can also be formed with @t{not}. For example, +Compound queries can also be formed with @code{not}. For example, @lisp (and (supervisor ?x (Bitdiddle Ben)) @@ -27670,12 +27670,12 @@ In general, @noindent is satisfied by all assignments to the pattern variables that do not satisfy -@math{\langle}@math{quer\!y_1}@math{\rangle}.@footnote{Actually, this description of @t{not} is valid -only for simple cases. The real behavior of @t{not} is more complex. We -will examine @t{not}'s peculiarities in @ref{4.4.2} and +@math{\langle}@math{quer\!y_1}@math{\rangle}.@footnote{Actually, this description of @code{not} is valid +only for simple cases. The real behavior of @code{not} is more complex. We +will examine @code{not}'s peculiarities in @ref{4.4.2} and @ref{4.4.3}.} -The final combining form is called @t{lisp-value}. When @t{lisp-value} +The final combining form is called @code{lisp-value}. When @code{lisp-value} is the first element of a pattern, it specifies that the next element is a Lisp predicate to be applied to the rest of the (instantiated) elements as arguments. In general, @@ -27688,11 +27688,11 @@ arguments. In general, will be satisfied by assignments to the pattern variables for which the @math{\langle}@var{predicate}@math{\rangle} applied to the instantiated @math{\langle}@math{arg_1}@math{\rangle} @dots{} @math{\langle}@math{arg_n}@math{\rangle} is true. For example, to find all people whose salary is -greater than $30,000 we could write@footnote{@t{Lisp-value} should be used +greater than $30,000 we could write@footnote{@code{Lisp-value} should be used only to perform an operation not provided in the query language. In particular, it should not be used to test equality (since that is what the matching in the query language is designed to do) or inequality (since that can -be done with the @t{same} rule shown below).} +be done with the @code{same} rule shown below).} @lisp (and (salary ?person ?amount) @@ -27738,15 +27738,15 @@ The rule @noindent specifies that two people live near each other if they live in the same town. -The final @t{not} clause prevents the rule from saying that all people live -near themselves. The @t{same} relation is defined by a very simple -rule:@footnote{Notice that we do not need @t{same} in order to make two +The final @code{not} clause prevents the rule from saying that all people live +near themselves. The @code{same} relation is defined by a very simple +rule:@footnote{Notice that we do not need @code{same} in order to make two things be the same: We just use the same pattern variable for each---in effect, we have one thing instead of two things in the first place. For example, see -@t{?town} in the @t{lives-near} rule and @t{?middle-manager} in the -@t{wheel} rule below. @t{Same} is useful when we want to force two -things to be different, such as @t{?person-1} and @t{?person-2} in the -@t{lives-near} rule. Although using the same pattern variable in two parts +@code{?town} in the @code{lives-near} rule and @code{?middle-manager} in the +@code{wheel} rule below. @code{Same} is useful when we want to force two +things to be different, such as @code{?person-1} and @code{?person-2} in the +@code{lives-near} rule. Although using the same pattern variable in two parts of a query forces the same value to appear in both places, using different pattern variables does not force different values to appear. (The values assigned to different pattern variables may be the same or different.)} @@ -27775,7 +27775,7 @@ The general form of a rule is @noindent where @math{\langle}@var{conclusion}@math{\rangle} is a pattern and @math{\langle}@var{body}@math{\rangle} is any -query.@footnote{We will also allow rules without bodies, as in @t{same}, and +query.@footnote{We will also allow rules without bodies, as in @code{same}, and we will interpret such a rule to mean that the rule conclusion is satisfied by any values of the variables.} We can think of a rule as representing a large (even infinite) set of assertions, namely all instantiations of the rule @@ -27807,7 +27807,7 @@ To find all computer programmers who live near Ben Bitdiddle, we can ask @noindent As in the case of compound procedures, rules can be used as parts of other -rules (as we saw with the @t{lives-near} rule above) or even be defined +rules (as we saw with the @code{lives-near} rule above) or even be defined recursively. For instance, the rule @lisp @@ -27879,7 +27879,7 @@ occur that day. What query should he use? @item Alyssa P. Hacker is unimpressed. She thinks it would be much more useful to be able to ask for her meetings by specifying her name. So she designs a rule -that says that a person's meetings include all @t{whole-company} meetings +that says that a person's meetings include all @code{whole-company} meetings plus all meetings of that person's division. Fill in the body of Alyssa's rule. @@ -27931,20 +27931,20 @@ We can regard a rule as a kind of logical implication: @emph{If} an assignment of values to pattern variables satisfies the body, @emph{then} it satisfies the conclusion. Consequently, we can regard the query language as having the ability to perform @newterm{logical deductions} based upon the rules. As an -example, consider the @t{append} operation described at the beginning of -@ref{4.4}. As we said, @t{append} can be characterized by the +example, consider the @code{append} operation described at the beginning of +@ref{4.4}. As we said, @code{append} can be characterized by the following two rules: @itemize @bullet @item -For any list @t{y}, the empty list and @t{y} @t{append} to form -@t{y}. +For any list @code{y}, the empty list and @code{y} @code{append} to form +@code{y}. @item -For any @t{u}, @t{v}, @t{y}, and @t{z}, @t{(cons u v)} and -@t{y} @t{append} to form @t{(cons u z)} if @t{v} and @t{y} -@t{append} to form @t{z}. +For any @code{u}, @code{v}, @code{y}, and @code{z}, @code{(cons u v)} and +@code{y} @code{append} to form @code{(cons u z)} if @code{v} and @code{y} +@code{append} to form @code{z}. @end itemize @@ -27956,8 +27956,8 @@ To express this in our query language, we define two rules for a relation @end lisp @noindent -which we can interpret to mean ``@t{x} and @t{y} @t{append} to form -@t{z}'': +which we can interpret to mean ``@code{x} and @code{y} @code{append} to form +@code{z}'': @lisp (rule (append-to-form () ?y ?y)) @@ -27967,10 +27967,10 @@ which we can interpret to mean ``@t{x} and @t{y} @t{append} to form @noindent The first rule has no body, which means that the conclusion holds for any value -of @t{?y}. Note how the second rule makes use of dotted-tail notation to -name the @t{car} and @t{cdr} of a list. +of @code{?y}. Note how the second rule makes use of dotted-tail notation to +name the @code{car} and @code{cdr} of a list. -Given these two rules, we can formulate queries that compute the @t{append} +Given these two rules, we can formulate queries that compute the @code{append} of two lists: @lisp @@ -27982,7 +27982,7 @@ of two lists: @noindent What is more striking, we can use the same rules to ask the question ``Which -list, when @t{append}ed to @t{(a b)}, yields @t{(a b c d)}?'' This is +list, when @code{append}ed to @code{(a b)}, yields @code{(a b c d)}?'' This is done as follows: @lisp @@ -27993,7 +27993,7 @@ done as follows: @end lisp @noindent -We can also ask for all pairs of lists that @t{append} to form @t{(a b c +We can also ask for all pairs of lists that @code{append} to form @code{(a b c d)}: @lisp @@ -28012,12 +28012,12 @@ The query system may seem to exhibit quite a bit of intelligence in using the rules to deduce the answers to the queries above. Actually, as we will see in the next section, the system is following a well-determined algorithm in unraveling the rules. Unfortunately, although the system works impressively in -the @t{append} case, the general methods may break down in more complex +the @code{append} case, the general methods may break down in more complex cases, as we will see in @ref{4.4.3}. @quotation @strong{@anchor{Exercise 4.61}Exercise 4.61:} The following rules implement a -@t{next-to} relation that finds adjacent elements of a list: +@code{next-to} relation that finds adjacent elements of a list: @lisp (rule (?x next-to ?y in (?x ?y . ?u))) @@ -28035,11 +28035,11 @@ What will the response be to the following queries? @quotation @strong{@anchor{Exercise 4.62}Exercise 4.62:} Define rules to implement the -@t{last-@/pair} operation of @ref{Exercise 2.17}, which returns a list +@code{last-@/pair} operation of @ref{Exercise 2.17}, which returns a list containing the last element of a nonempty list. Check your rules on queries -such as @t{(last-pair (3) ?x)}, @t{(last-pair (1 2 3) ?x)} and -@t{(last-pair (2 ?x) (3))}. Do your rules work correctly on queries such as -@t{(last-pair ?x (3))} ? +such as @code{(last-pair (3) ?x)}, @code{(last-pair (1 2 3) ?x)} and +@code{(last-pair (2 ?x) (3))}. Do your rules work correctly on queries such as +@code{(last-pair ?x (3))} ? @end quotation @quotation @@ -28079,7 +28079,7 @@ from the operations of mathematical logic. It should be apparent that the query evaluator must perform some kind of search in order to match queries against facts and rules in the data base. One way to do this would be to implement the query system as a nondeterministic program, -using the @t{amb} evaluator of @ref{4.3} (see @ref{Exercise 4.78}). +using the @code{amb} evaluator of @ref{4.3} (see @ref{Exercise 4.78}). Another possibility is to manage the search with the aid of streams. Our implementation follows this second approach. @@ -28090,21 +28090,21 @@ of information in terms of streams of frames, enables us to implement both simple and compound queries. We next discuss unification, a generalization of pattern matching needed to implement rules. Finally, we show how the entire query interpreter fits together through a procedure that classifies expressions -in a manner analogous to the way @t{eval} classifies expressions for the +in a manner analogous to the way @code{eval} classifies expressions for the interpreter described in @ref{4.1}. @c @noindent @subsubheading Pattern matching A @newterm{pattern matcher} is a program that tests whether some datum fits a -specified pattern. For example, the data list @t{((a b) c (a b))} matches -the pattern @t{(?x c ?x)} with the pattern variable @t{?x} bound to -@t{(a b)}. The same data list matches the pattern @t{(?x ?y ?z)} with -@t{?x} and @t{?z} both bound to @t{(a b)} and @t{?y} bound to -@t{c}. It also matches the pattern @t{((?x ?y) c (?x ?y))} with -@t{?x} bound to @t{a} and @t{?y} bound to @t{b}. However, it does -not match the pattern @t{(?x a ?y)}, since that pattern specifies a list -whose second element is the symbol @t{a}. +specified pattern. For example, the data list @code{((a b) c (a b))} matches +the pattern @code{(?x c ?x)} with the pattern variable @code{?x} bound to +@code{(a b)}. The same data list matches the pattern @code{(?x ?y ?z)} with +@code{?x} and @code{?z} both bound to @code{(a b)} and @code{?y} bound to +@code{c}. It also matches the pattern @code{((?x ?y) c (?x ?y))} with +@code{?x} bound to @code{a} and @code{?y} bound to @code{b}. However, it does +not match the pattern @code{(?x a ?y)}, since that pattern specifies a list +whose second element is the symbol @code{a}. The pattern matcher used by the query system takes as inputs a pattern, a datum, and a @newterm{frame} that specifies bindings for various pattern @@ -28113,13 +28113,13 @@ consistent with the bindings already in the frame. If so, it returns the given frame augmented by any bindings that may have been determined by the match. Otherwise, it indicates that the match has failed. -For example, using the pattern @t{(?x ?y ?x)} to match @t{(a b a)} given -an empty frame will return a frame specifying that @t{?x} is bound to -@t{a} and @t{?y} is bound to @t{b}. Trying the match with the same -pattern, the same datum, and a frame specifying that @t{?y} is bound to -@t{a} will fail. Trying the match with the same pattern, the same datum, -and a frame in which @t{?y} is bound to @t{b} and @t{?x} is unbound -will return the given frame augmented by a binding of @t{?x} to @t{a}. +For example, using the pattern @code{(?x ?y ?x)} to match @code{(a b a)} given +an empty frame will return a frame specifying that @code{?x} is bound to +@code{a} and @code{?y} is bound to @code{b}. Trying the match with the same +pattern, the same datum, and a frame specifying that @code{?y} is bound to +@code{a} will fail. Trying the match with the same pattern, the same datum, +and a frame in which @code{?y} is bound to @code{b} and @code{?x} is unbound +will return the given frame augmented by a binding of @code{?x} to @code{a}. The pattern matcher is all the mechanism that is needed to process simple queries that don't involve rules. For instance, to process the query @@ -28132,7 +28132,7 @@ queries that don't involve rules. For instance, to process the query we scan through all assertions in the data base and select those that match the pattern with respect to an initially empty frame. For each match we find, we use the frame returned by the match to instantiate the pattern with a value for -@t{?x}. +@code{?x}. @subsubheading Streams of frames @@ -28204,7 +28204,7 @@ is finally printed. The real elegance of the stream-of-frames implementation is evident when we deal with compound queries. The processing of compound queries makes use of the ability of our matcher to demand that a match be consistent with a -specified frame. For example, to handle the @t{and} of two queries, such as +specified frame. For example, to handle the @code{and} of two queries, such as @lisp (and (can-do-job @@ -28223,16 +28223,16 @@ trainee''), we first find all entries that match the pattern @noindent This produces a stream of frames, each of which contains a binding for -@t{?x}. Then for each frame in the stream we find all entries that match +@code{?x}. Then for each frame in the stream we find all entries that match @lisp (job ?person ?x) @end lisp @noindent -in a way that is consistent with the given binding for @t{?x}. Each such -match will produce a frame containing bindings for @t{?x} and -@t{?person}. The @t{and} of two queries can be viewed as a series +in a way that is consistent with the given binding for @code{?x}. Each such +match will produce a frame containing bindings for @code{?x} and +@code{?person}. The @code{and} of two queries can be viewed as a series combination of the two component queries, as shown in @ref{Figure 4.5}. The frames that pass through the first query filter are filtered and further extended by the second query. @@ -28241,7 +28241,7 @@ extended by the second query. @c @quotation @anchor{Figure 4.5} @ifinfo -@strong{Figure 4.5:} The @t{and} combination of two queries is produced +@strong{Figure 4.5:} The @code{and} combination of two queries is produced by operating on the stream of frames in series. @example @@ -28265,7 +28265,7 @@ by operating on the stream of frames in series. @sp 0.6 @quotation @c @noindent -@strong{Figure 4.5:} The @t{and} combination of two queries is produced +@strong{Figure 4.5:} The @code{and} combination of two queries is produced by operating on the stream of frames in series. @end quotation @sp 0.8 @@ -28274,18 +28274,18 @@ by operating on the stream of frames in series. @end float @noindent -@ref{Figure 4.6} shows the analogous method for computing the @t{or} of two +@ref{Figure 4.6} shows the analogous method for computing the @code{or} of two queries as a parallel combination of the two component queries. The input stream of frames is extended separately by each query. The two resulting streams are then merged to produce the final output stream. Even from this high-level description, it is apparent that the processing of compound queries can be slow. For example, since a query may produce more than -one output frame for each input frame, and each query in an @t{and} gets its -input frames from the previous query, an @t{and} query could, in the worst +one output frame for each input frame, and each query in an @code{and} gets its +input frames from the previous query, an @code{and} query could, in the worst case, have to perform a number of matches that is exponential in the number of queries (see @ref{Exercise 4.76}).@footnote{But this kind of exponential -explosion is not common in @t{and} queries because the added conditions tend +explosion is not common in @code{and} queries because the added conditions tend to reduce rather than expand the number of frames produced.} Though systems for handling only simple queries are quite practical, dealing with complex queries is extremely difficult.@footnote{There is a large literature on @@ -28296,7 +28296,7 @@ queries efficiently.} @c @quotation @anchor{Figure 4.6} @ifinfo -@strong{Figure 4.6:} The @t{or} combination of two queries is produced +@strong{Figure 4.6:} The @code{or} combination of two queries is produced by operating on the stream of frames in parallel and merging the results. @example @@ -28325,7 +28325,7 @@ frames | | ^ +-------+ | frames @center @image{fig/chap4/Fig4.6a,147mm,,,.pdf} @sp 0.6 @quotation -@strong{Figure 4.6:} The @t{or} combination of two queries is produced +@strong{Figure 4.6:} The @code{or} combination of two queries is produced by operating on the stream of frames in parallel and merging the results. @end quotation @sp 0.0 @@ -28334,7 +28334,7 @@ by operating on the stream of frames in parallel and merging the results. @end float @noindent -From the stream-of-frames viewpoint, the @t{not} of some query acts as a +From the stream-of-frames viewpoint, the @code{not} of some query acts as a filter that removes all frames for which the query can be satisfied. For instance, given the pattern @@ -28344,10 +28344,10 @@ instance, given the pattern @noindent we attempt, for each frame in the input stream, to produce extension frames -that satisfy @t{(job ?x (computer programmer))}. We remove from the input +that satisfy @code{(job ?x (computer programmer))}. We remove from the input stream all frames for which such extensions exist. The result is a stream -consisting of only those frames in which the binding for @t{?x} does not -satisfy @t{(job ?x (computer programmer))}. For example, in processing the +consisting of only those frames in which the binding for @code{?x} does not +satisfy @code{(job ?x (computer programmer))}. For example, in processing the query @lisp @@ -28356,14 +28356,14 @@ query @end lisp @noindent -the first clause will generate frames with bindings for @t{?x} and -@t{?y}. The @t{not} clause will then filter these by removing all frames -in which the binding for @t{?x} satisfies the restriction that @t{?x} is +the first clause will generate frames with bindings for @code{?x} and +@code{?y}. The @code{not} clause will then filter these by removing all frames +in which the binding for @code{?x} satisfies the restriction that @code{?x} is a computer programmer.@footnote{There is a subtle difference between this -filter implementation of @t{not} and the usual meaning of @t{not} in +filter implementation of @code{not} and the usual meaning of @code{not} in mathematical logic. See @ref{4.4.3}.} -The @t{lisp-value} special form is implemented as a similar filter on frame +The @code{lisp-value} special form is implemented as a similar filter on frame streams. We use each frame in the stream to instantiate any variables in the pattern, then apply the Lisp predicate. We remove from the input stream all frames for which the predicate fails. @@ -28379,27 +28379,27 @@ both the ``pattern'' and the ``datum'' may contain variables. A unifier takes two patterns, each containing constants and variables, and determines whether it is possible to assign values to the variables that will make the two patterns equal. If so, it returns a frame containing these -bindings. For example, unifying @t{(?x a ?y)} and @t{(?y ?z a)} will -specify a frame in which @t{?x}, @t{?y}, and @t{?z} must all be bound -to @t{a}. On the other hand, unifying @t{(?x ?y a)} and @t{(?x b ?y)} -will fail, because there is no value for @t{?y} that can make the two +bindings. For example, unifying @code{(?x a ?y)} and @code{(?y ?z a)} will +specify a frame in which @code{?x}, @code{?y}, and @code{?z} must all be bound +to @code{a}. On the other hand, unifying @code{(?x ?y a)} and @code{(?x b ?y)} +will fail, because there is no value for @code{?y} that can make the two patterns equal. (For the second elements of the patterns to be equal, -@t{?y} would have to be @t{b}; however, for the third elements to be -equal, @t{?y} would have to be @t{a}.) The unifier used in the query +@code{?y} would have to be @code{b}; however, for the third elements to be +equal, @code{?y} would have to be @code{a}.) The unifier used in the query system, like the pattern matcher, takes a frame as input and performs unifications that are consistent with this frame. The unification algorithm is the most technically difficult part of the query system. With complex patterns, performing unification may seem to require -deduction. To unify @t{(?x ?x)} and @t{((a ?y c) (a b ?z))}, for -example, the algorithm must infer that @t{?x} should be @t{(a b c)}, -@t{?y} should be @t{b}, and @t{?z} should be @t{c}. We may think +deduction. To unify @code{(?x ?x)} and @code{((a ?y c) (a b ?z))}, for +example, the algorithm must infer that @code{?x} should be @code{(a b c)}, +@code{?y} should be @code{b}, and @code{?z} should be @code{c}. We may think of this process as solving a set of equations among the pattern components. In general, these are simultaneous equations, which may require substantial manipulation to solve.@footnote{In one-sided pattern matching, all the equations that contain pattern variables are explicit and already solved for -the unknown (the pattern variable).} For example, unifying @t{(?x ?x)} and -@t{((a ?y c) (a b ?z))} may be thought of as specifying the simultaneous +the unknown (the pattern variable).} For example, unifying @code{(?x ?x)} and +@code{((a ?y c) (a b ?z))} may be thought of as specifying the simultaneous equations @lisp @@ -28436,22 +28436,22 @@ successful unification may not completely determine the variable values; some variables may remain unbound and others may be bound to values that contain variables. -Consider the unification of @t{(?x a)} and @t{((b ?y) ?z)}. We can -deduce that @t{?x = (b ?y)} and @t{a = ?z}, but we cannot further solve -for @t{?x} or @t{?y}. The unification doesn't fail, since it is +Consider the unification of @code{(?x a)} and @code{((b ?y) ?z)}. We can +deduce that @code{?x = (b ?y)} and @code{a = ?z}, but we cannot further solve +for @code{?x} or @code{?y}. The unification doesn't fail, since it is certainly possible to make the two patterns equal by assigning values to -@t{?x} and @t{?y}. Since this match in no way restricts the values -@t{?y} can take on, no binding for @t{?y} is put into the result frame. -The match does, however, restrict the value of @t{?x}. Whatever value -@t{?y} has, @t{?x} must be @t{(b ?y)}. A binding of @t{?x} to the -pattern @t{(b ?y)} is thus put into the frame. If a value for @t{?y} is +@code{?x} and @code{?y}. Since this match in no way restricts the values +@code{?y} can take on, no binding for @code{?y} is put into the result frame. +The match does, however, restrict the value of @code{?x}. Whatever value +@code{?y} has, @code{?x} must be @code{(b ?y)}. A binding of @code{?x} to the +pattern @code{(b ?y)} is thus put into the frame. If a value for @code{?y} is later determined and added to the frame (by a pattern match or unification that -is required to be consistent with this frame), the previously bound @t{?x} +is required to be consistent with this frame), the previously bound @code{?x} will refer to this value.@footnote{Another way to think of unification is that it generates the most general pattern that is a specialization of the two input -patterns. That is, the unification of @t{(?x a)} and @t{((b ?y) ?z)} is -@t{((b ?y) a)}, and the unification of @t{(?x a ?y)} and @t{(?y ?z -a)}, discussed above, is @t{(a a a)}. For our implementation, it is more +patterns. That is, the unification of @code{(?x a)} and @code{((b ?y) ?z)} is +@code{((b ?y) a)}, and the unification of @code{(?x a ?y)} and @code{(?y ?z +a)}, discussed above, is @code{(a a a)}. For our implementation, it is more convenient to think of the result of unification as a frame rather than a pattern.} @@ -28483,12 +28483,12 @@ that the pattern unifies with the conclusion of the rule @end lisp @noindent -resulting in a frame specifying that @t{?person-2} is bound to @t{(Hacker -Alyssa P)} and that @t{?x} should be bound to (have the same value as) -@t{?person-1}. Now, relative to this frame, we evaluate the compound query +resulting in a frame specifying that @code{?person-2} is bound to @code{(Hacker +Alyssa P)} and that @code{?x} should be bound to (have the same value as) +@code{?person-1}. Now, relative to this frame, we evaluate the compound query given by the body of the rule. Successful matches will extend this frame by -providing a binding for @t{?person-1}, and consequently a value for -@t{?x}, which we can use to instantiate the original query pattern. +providing a binding for @code{?person-1}, and consequently a value for +@code{?x}, which we can use to instantiate the original query pattern. In general, the query evaluator uses the following method to apply a rule when trying to establish a query pattern in a frame that specifies bindings for some @@ -28508,7 +28508,7 @@ rule. @noindent Notice how similar this is to the method for applying a procedure in the -@t{eval}/@t{apply} evaluator for Lisp: +@code{eval}/@code{apply} evaluator for Lisp: @itemize @bullet @@ -28565,19 +28565,19 @@ given pattern. Despite the complexity of the underlying matching operations, the system is organized much like an evaluator for any language. The procedure that -coordinates the matching operations is called @t{qeval}, and it plays a role -analogous to that of the @t{eval} procedure for Lisp. @t{Qeval} takes as +coordinates the matching operations is called @code{qeval}, and it plays a role +analogous to that of the @code{eval} procedure for Lisp. @code{Qeval} takes as inputs a query and a stream of frames. Its output is a stream of frames, corresponding to successful matches to the query pattern, that extend some -frame in the input stream, as indicated in @ref{Figure 4.4}. Like @t{eval}, -@t{qeval} classifies the different types of expressions (queries) and +frame in the input stream, as indicated in @ref{Figure 4.4}. Like @code{eval}, +@code{qeval} classifies the different types of expressions (queries) and dispatches to an appropriate procedure for each. There is a procedure for each -special form (@t{and}, @t{or}, @t{not}, and @t{lisp-value}) and one +special form (@code{and}, @code{or}, @code{not}, and @code{lisp-value}) and one for simple queries. -The driver loop, which is analogous to the @t{driver-loop} procedure for the +The driver loop, which is analogous to the @code{driver-loop} procedure for the other evaluators in this chapter, reads queries from the terminal. For each -query, it calls @t{qeval} with the query and a stream that consists of a +query, it calls @code{qeval} with the query and a stream that consists of a single empty frame. This will produce the stream of all possible matches (all possible extensions to the empty frame). For each frame in the resulting stream, it instantiates the original query using the values of the variables @@ -28588,7 +28588,7 @@ that satisfy a query. The delayed evaluation embodied in streams is crucial here: The system will print responses one by one as they are generated, regardless of whether there are a finite or infinite number of responses.} -The driver also checks for the special command @t{assert!}, which signals +The driver also checks for the special command @code{assert!}, which signals that the input is not a query but rather an assertion or rule to be added to the data base. For instance, @@ -28606,7 +28606,7 @@ the data base. For instance, @subsection Is Logic Programming Mathematical Logic? The means of combination used in the query language may at first seem identical -to the operations @t{and}, @t{or}, and @t{not} of mathematical logic, +to the operations @code{and}, @code{or}, and @code{not} of mathematical logic, and the application of query-language rules is in fact accomplished through a legitimate method of inference.@footnote{That a particular method of inference is legitimate is not a trivial assertion. One must prove that if one starts @@ -28638,7 +28638,7 @@ or If a company has many more supervisors than programmers (the usual case), it is better to use the first form rather than the second because the data base must be scanned for each intermediate result (frame) produced by the first clause of -the @t{and}. +the @code{and}. The aim of logic programming is to provide the programmer with techniques for decomposing a computational problem into two separate problems: ``what'' is to @@ -28668,13 +28668,13 @@ must qualify this statement by agreeing that, in speaking of the ``inference'' accomplished by a logic program, we assume that the computation terminates. Unfortunately, even this qualified statement is false for our implementation of the query language (and also false for programs in Prolog and most other -current logic programming languages) because of our use of @t{not} and -@t{lisp-value}. As we will describe below, the @t{not} implemented in -the query language is not always consistent with the @t{not} of mathematical -logic, and @t{lisp-value} introduces additional complications. We could +current logic programming languages) because of our use of @code{not} and +@code{lisp-value}. As we will describe below, the @code{not} implemented in +the query language is not always consistent with the @code{not} of mathematical +logic, and @code{lisp-value} introduces additional complications. We could implement a language consistent with mathematical logic by simply removing -@t{not} and @t{lisp-value} from the language and agreeing to write -programs using only simple queries, @t{and}, and @t{or}. However, this +@code{not} and @code{lisp-value} from the language and agreeing to write +programs using only simple queries, @code{and}, and @code{or}. However, this would greatly restrict the expressive power of the language. One of the major concerns of research in logic programming is to find ways to achieve more consistency with mathematical logic without unduly sacrificing expressive @@ -28720,31 +28720,31 @@ Unfortunately, this will drive the system into an infinite loop, as follows: @itemize @bullet @item -The system finds that the @t{married} rule is applicable; that is, the rule -conclusion @t{(married ?x ?y)} successfully unifies with the query pattern -@t{(married Mickey ?who)} to produce a frame in which @t{?x} is bound to -@t{Mickey} and @t{?y} is bound to @t{?who}. So the interpreter -proceeds to evaluate the rule body @t{(married ?y ?x)} in this frame---in -effect, to process the query @t{(married ?who Mickey)}. +The system finds that the @code{married} rule is applicable; that is, the rule +conclusion @code{(married ?x ?y)} successfully unifies with the query pattern +@code{(married Mickey ?who)} to produce a frame in which @code{?x} is bound to +@code{Mickey} and @code{?y} is bound to @code{?who}. So the interpreter +proceeds to evaluate the rule body @code{(married ?y ?x)} in this frame---in +effect, to process the query @code{(married ?who Mickey)}. @item -One answer appears directly as an assertion in the data base: @t{(married +One answer appears directly as an assertion in the data base: @code{(married Minnie Mickey)}. @item -The @t{married} rule is also applicable, so the interpreter again evaluates -the rule body, which this time is equivalent to @t{(married Mickey ?who)}. +The @code{married} rule is also applicable, so the interpreter again evaluates +the rule body, which this time is equivalent to @code{(married Mickey ?who)}. @end itemize @noindent The system is now in an infinite loop. Indeed, whether the system will find -the simple answer @t{(married Minnie Mickey)} before it goes into the loop +the simple answer @code{(married Minnie Mickey)} before it goes into the loop depends on implementation details concerning the order in which the system checks the items in the data base. This is a very simple example of the kinds of loops that can occur. Collections of interrelated rules can lead to loops that are much harder to anticipate, and the appearance of a loop can depend on -the order of clauses in an @t{and} (see @ref{Exercise 4.64}) or on low-level +the order of clauses in an @code{and} (see @ref{Exercise 4.64}) or on low-level details concerning the order in which the system processes queries.@footnote{This is not a problem of the logic but one of the procedural interpretation of the logic provided by our interpreter. We could write an @@ -28761,9 +28761,9 @@ in performing deductions. Imagine a diabolical rule of the form ``To show @math{P(x)} is true, show that @math{P(f(x))} is true,'' for some suitably chosen function @math{f}.} -@subsubheading Problems with @t{not} +@subsubheading Problems with @code{not} -Another quirk in the query system concerns @t{not}. Given the data base of +Another quirk in the query system concerns @code{not}. Given the data base of @ref{4.4.1}, consider the following two queries: @lisp @@ -28776,46 +28776,46 @@ Another quirk in the query system concerns @t{not}. Given the data base of @noindent These two queries do not produce the same result. The first query begins by -finding all entries in the data base that match @t{(supervisor ?x ?y)}, and +finding all entries in the data base that match @code{(supervisor ?x ?y)}, and then filters the resulting frames by removing the ones in which the value of -@t{?x} satisfies @t{(job ?x (computer programmer))}. The second query +@code{?x} satisfies @code{(job ?x (computer programmer))}. The second query begins by filtering the incoming frames to remove those that can satisfy -@t{(job ?x (computer programmer))}. Since the only incoming frame is empty, +@code{(job ?x (computer programmer))}. Since the only incoming frame is empty, it checks the data base to see if there are any patterns that satisfy -@t{(job ?x (computer programmer))}. Since there generally are entries of -this form, the @t{not} clause filters out the empty frame and returns an +@code{(job ?x (computer programmer))}. Since there generally are entries of +this form, the @code{not} clause filters out the empty frame and returns an empty stream of frames. Consequently, the entire compound query returns an empty stream. -The trouble is that our implementation of @t{not} really is meant to serve -as a filter on values for the variables. If a @t{not} clause is processed -with a frame in which some of the variables remain unbound (as does @t{?x} +The trouble is that our implementation of @code{not} really is meant to serve +as a filter on values for the variables. If a @code{not} clause is processed +with a frame in which some of the variables remain unbound (as does @code{?x} in the example above), the system will produce unexpected results. Similar -problems occur with the use of @t{lisp-value}---the Lisp predicate can't +problems occur with the use of @code{lisp-value}---the Lisp predicate can't work if some of its arguments are unbound. See @ref{Exercise 4.77}. -There is also a much more serious way in which the @t{not} of the query -language differs from the @t{not} of mathematical logic. In logic, we +There is also a much more serious way in which the @code{not} of the query +language differs from the @code{not} of mathematical logic. In logic, we interpret the statement ``not @math{P}'' to mean that @math{P} is not true. In the query system, however, ``not @math{P}'' means that @math{P} is not deducible from the knowledge in the data base. For example, given the personnel data base of -@ref{4.4.1}, the system would happily deduce all sorts of @t{not} +@ref{4.4.1}, the system would happily deduce all sorts of @code{not} statements, such as that Ben Bitdiddle is not a baseball fan, that it is not raining outside, and that 2 + 2 is not 4.@footnote{Consider the query -@t{(not (baseball-fan (Bitdiddle Ben)))}. The system finds that -@t{(baseball-fan (Bitdiddle Ben))} is not in the data base, so the empty +@code{(not (baseball-fan (Bitdiddle Ben)))}. The system finds that +@code{(baseball-fan (Bitdiddle Ben))} is not in the data base, so the empty frame does not satisfy the pattern and is not filtered out of the initial stream of frames. The result of the query is thus the empty frame, which is -used to instantiate the input query to produce @t{(not (baseball-fan -(Bitdiddle Ben)))}.} In other words, the @t{not} of logic programming +used to instantiate the input query to produce @code{(not (baseball-fan +(Bitdiddle Ben)))}.} In other words, the @code{not} of logic programming languages reflects the so-called @newterm{closed world assumption} that all relevant information has been included in the data base.@footnote{A discussion -and justification of this treatment of @t{not} can be found in the article +and justification of this treatment of @code{not} can be found in the article by @ref{Clark (1978)}.} @quotation @strong{@anchor{Exercise 4.64}Exercise 4.64:} Louis Reasoner mistakenly deletes -the @t{outranked-@/by} rule (@ref{4.4.1}) from the data base. When he +the @code{outranked-@/by} rule (@ref{4.4.1}) from the data base. When he realizes this, he quickly reinstalls it. Unfortunately, he makes a slight change in the rule, and types it in as @@ -28841,7 +28841,7 @@ After answering, the system goes into an infinite loop. Explain why. @quotation @strong{@anchor{Exercise 4.65}Exercise 4.65:} Cy D. Fect, looking forward to the day when he will rise in the organization, gives a query to find all the -wheels (using the @t{wheel} rule of @ref{4.4.1}): +wheels (using the @code{wheel} rule of @ref{4.4.1}): @lisp (wheel ?who) @@ -28880,14 +28880,14 @@ In general, Ben's new system allows expressions of the form @end lisp @noindent -where @t{accumulation-function} can be things like @t{sum}, -@t{average}, or @t{maximum}. Ben reasons that it should be a cinch to -implement this. He will simply feed the query pattern to @t{qeval}. This +where @code{accumulation-function} can be things like @code{sum}, +@code{average}, or @code{maximum}. Ben reasons that it should be a cinch to +implement this. He will simply feed the query pattern to @code{qeval}. This will produce a stream of frames. He will then pass this stream through a mapping function that extracts the value of the designated variable from each frame in the stream and feed the resulting stream of values to the accumulation function. Just as Ben completes the implementation and is about to try it out, -Cy walks by, still puzzling over the @t{wheel} query result in +Cy walks by, still puzzling over the @code{wheel} query result in @ref{Exercise 4.65}. When Cy shows Ben the system's response, Ben groans, ``Oh, no, my simple accumulation scheme won't work!'' @@ -28909,10 +28909,10 @@ modify the system to include your loop detector.) @quotation @strong{@anchor{Exercise 4.68}Exercise 4.68:} Define rules to implement the -@t{reverse} operation of @ref{Exercise 2.18}, which returns a list +@code{reverse} operation of @ref{Exercise 2.18}, which returns a list containing the same elements as a given list in reverse order. (Hint: Use -@t{append-to-form}.) Can your rules answer both @t{(reverse (1 2 3) ?x)} -and @t{(reverse ?x (1 2 3))} ? +@code{append-to-form}.) Can your rules answer both @code{(reverse (1 2 3) ?x)} +and @code{(reverse ?x (1 2 3))} ? @end quotation @quotation @@ -28921,11 +28921,11 @@ the rules you formulated in @ref{Exercise 4.63}, devise a rule for adding ``greats'' to a grandson relationship. This should enable the system to deduce that Irad is the great-grandson of Adam, or that Jabal and Jubal are the great-great-great-great-great-grandsons of Adam. (Hint: Represent the fact -about Irad, for example, as @t{((great grandson) Adam Irad)}. Write rules -that determine if a list ends in the word @t{grandson}. Use this to express -a rule that allows one to derive the relationship @t{((great . ?rel) ?x -?y)}, where @t{?rel} is a list ending in @t{grandson}.) Check your rules -on queries such as @t{((great grandson) ?g ?ggs)} and @t{(?relationship +about Irad, for example, as @code{((great grandson) Adam Irad)}. Write rules +that determine if a list ends in the word @code{grandson}. Use this to express +a rule that allows one to derive the relationship @code{((great . ?rel) ?x +?y)}, where @code{?rel} is a list ending in @code{grandson}.) Check your rules +on queries such as @code{((great grandson) ?g ?ggs)} and @code{(?relationship Adam Irad)}. @end quotation @@ -28952,7 +28952,7 @@ details by presenting a complete implementation of the system. The driver loop for the query system repeatedly reads input expressions. If the expression is a rule or assertion to be added to the data base, then the information is added. Otherwise the expression is assumed to be a query. The -driver passes this query to the evaluator @t{qeval} together with an initial +driver passes this query to the evaluator @code{qeval} together with an initial frame stream consisting of a single empty frame. The result of the evaluation is a stream of frames generated by satisfying the query with variable values found in the data base. These frames are used to form a new stream consisting @@ -28992,24 +28992,24 @@ the terminal: @noindent Here, as in the other evaluators in this chapter, we use an abstract syntax for the expressions of the query language. The implementation of the expression -syntax, including the predicate @t{assertion-to-be-added?} and the selector -@t{add-assertion-body}, is given in @ref{4.4.4.7}. -@t{Add-rule-or-assertion!} is defined in @ref{4.4.4.5}. +syntax, including the predicate @code{assertion-to-be-added?} and the selector +@code{add-assertion-body}, is given in @ref{4.4.4.7}. +@code{Add-rule-or-assertion!} is defined in @ref{4.4.4.5}. Before doing any processing on an input expression, the driver loop transforms it syntactically into a form that makes the processing more efficient. This involves changing the representation of pattern variables. When the query is instantiated, any variables that remain unbound are transformed back to the input representation before being printed. These transformations are performed -by the two procedures @t{query-syntax-process} and -@t{contract-question-mark} (@ref{4.4.4.7}). +by the two procedures @code{query-syntax-process} and +@code{contract-question-mark} (@ref{4.4.4.7}). To instantiate an expression, we copy it, replacing any variables in the expression by their values in a given frame. The values are themselves -instantiated, since they could contain variables (for example, if @t{?x} in -@t{exp} is bound to @t{?y} as the result of unification and @t{?y} is +instantiated, since they could contain variables (for example, if @code{?x} in +@code{exp} is bound to @code{?y} as the result of unification and @code{?y} is in turn bound to 5). The action to take if a variable cannot be instantiated -is given by a procedural argument to @t{instantiate}. +is given by a procedural argument to @code{instantiate}. @lisp (define (instantiate @@ -29037,13 +29037,13 @@ The procedures that manipulate bindings are defined in @ref{4.4.4.8}. @node 4.4.4.2, 4.4.4.3, 4.4.4.1, 4.4.4 @subsubsection The Evaluator -The @t{qeval} procedure, called by the @t{query-driver-loop}, is the +The @code{qeval} procedure, called by the @code{query-driver-loop}, is the basic evaluator of the query system. It takes as inputs a query and a stream of frames, and it returns a stream of extended frames. It identifies special -forms by a data-directed dispatch using @t{get} and @t{put}, just as we +forms by a data-directed dispatch using @code{get} and @code{put}, just as we did in implementing generic operations in @ref{Chapter 2}. Any query that is not identified as a special form is assumed to be a simple query, to be -processed by @t{simple-query}. +processed by @code{simple-query}. @lisp (define (qeval query frame-stream) @@ -29054,12 +29054,12 @@ processed by @t{simple-query}. @end lisp @noindent -@t{Type} and @t{contents}, defined in @ref{4.4.4.7}, implement +@code{Type} and @code{contents}, defined in @ref{4.4.4.7}, implement the abstract syntax of the special forms. @subsubheading Simple queries -The @t{simple-query} procedure handles simple queries. It takes as +The @code{simple-query} procedure handles simple queries. It takes as arguments a simple query (a pattern) together with a stream of frames, and it returns the stream formed by extending each frame by all data-base matches of the query. @@ -29077,26 +29077,26 @@ the query. @end lisp @noindent -For each frame in the input stream, we use @t{find-@/assertions} +For each frame in the input stream, we use @code{find-@/assertions} (@ref{4.4.4.3}) to match the pattern against all assertions in the data base, -producing a stream of extended frames, and we use @t{apply-rules} +producing a stream of extended frames, and we use @code{apply-rules} (@ref{4.4.4.4}) to apply all possible rules, producing another stream of extended frames. These two streams are combined (using -@t{stream-append-delayed}, @ref{4.4.4.6}) to make a stream of all +@code{stream-append-delayed}, @ref{4.4.4.6}) to make a stream of all the ways that the given pattern can be satisfied consistent with the original frame (see @ref{Exercise 4.71}). The streams for the individual input frames -are combined using @t{stream-flatmap} (@ref{4.4.4.6}) to form one +are combined using @code{stream-flatmap} (@ref{4.4.4.6}) to form one large stream of all the ways that any of the frames in the original input stream can be extended to produce a match with the given pattern. @subsubheading Compound queries -@t{And} queries are handled as illustrated in @ref{Figure 4.5} by the -@t{conjoin} procedure. @t{Conjoin} takes as inputs the conjuncts and the -frame stream and returns the stream of extended frames. First, @t{conjoin} +@code{And} queries are handled as illustrated in @ref{Figure 4.5} by the +@code{conjoin} procedure. @code{Conjoin} takes as inputs the conjuncts and the +frame stream and returns the stream of extended frames. First, @code{conjoin} processes the stream of frames to find the stream of all possible frame extensions that satisfy the first query in the conjunction. Then, using this -as the new frame stream, it recursively applies @t{conjoin} to the rest of +as the new frame stream, it recursively applies @code{conjoin} to the rest of the queries. @lisp @@ -29117,12 +29117,12 @@ The expression @end lisp @noindent -sets up @t{qeval} to dispatch to @t{conjoin} when an @t{and} form is +sets up @code{qeval} to dispatch to @code{conjoin} when an @code{and} form is encountered. -@t{Or} queries are handled similarly, as shown in @ref{Figure 4.6}. The -output streams for the various disjuncts of the @t{or} are computed -separately and merged using the @t{interleave-@/delayed} procedure from +@code{Or} queries are handled similarly, as shown in @ref{Figure 4.6}. The +output streams for the various disjuncts of the @code{or} are computed +separately and merged using the @code{interleave-@/delayed} procedure from @ref{4.4.4.6}. (See @ref{Exercise 4.71} and @ref{Exercise 4.72}.) @lisp @@ -29144,7 +29144,7 @@ given in @ref{4.4.4.7}. @subsubheading Filters -@t{Not} is handled by the method outlined in @ref{4.4.2}. We +@code{Not} is handled by the method outlined in @ref{4.4.2}. We attempt to extend each frame in the input stream to satisfy the query being negated, and we include a given frame in the output stream only if it cannot be extended. @@ -29163,7 +29163,7 @@ extended. @end lisp @noindent -@t{Lisp-value} is a filter similar to @t{not}. Each frame in the stream +@code{Lisp-value} is a filter similar to @code{not}. Each frame in the stream is used to instantiate the variables in the pattern, the indicated predicate is applied, and the frames for which the predicate returns false are filtered out of the input stream. An error results if there are unbound pattern variables. @@ -29186,11 +29186,11 @@ of the input stream. An error results if there are unbound pattern variables. @end lisp @noindent -@t{Execute}, which applies the predicate to the arguments, must @t{eval} +@code{Execute}, which applies the predicate to the arguments, must @code{eval} the predicate expression to get the procedure to apply. However, it must not evaluate the arguments, since they are already the actual arguments, not expressions whose evaluation (in Lisp) will produce the arguments. Note that -@t{execute} is implemented using @t{eval} and @t{apply} from the +@code{execute} is implemented using @code{eval} and @code{apply} from the underlying Lisp system. @lisp @@ -29201,10 +29201,10 @@ underlying Lisp system. @end lisp @noindent -The @t{always-true} special form provides for a query that is always +The @code{always-true} special form provides for a query that is always satisfied. It ignores its contents (normally empty) and simply passes through -all the frames in the input stream. @t{Always-true} is used by the -@t{rule-body} selector (@ref{4.4.4.7}) to provide bodies for rules +all the frames in the input stream. @code{Always-true} is used by the +@code{rule-body} selector (@ref{4.4.4.7}) to provide bodies for rules that were defined without bodies (that is, rules whose conclusions are always satisfied). @@ -29215,21 +29215,21 @@ satisfied). @end lisp @noindent -The selectors that define the syntax of @t{not} and @t{lisp-value} are +The selectors that define the syntax of @code{not} and @code{lisp-value} are given in @ref{4.4.4.7}. @node 4.4.4.3, 4.4.4.4, 4.4.4.2, 4.4.4 @subsubsection Finding Assertions by Pattern Matching -@t{Find-assertions}, called by @t{simple-query} (@ref{4.4.4.2}), +@code{Find-assertions}, called by @code{simple-query} (@ref{4.4.4.2}), takes as input a pattern and a frame. It returns a stream of frames, each extending the given one by a data-base match of the given pattern. It uses -@t{fetch-@/assertions} (@ref{4.4.4.5}) to get a stream of all the +@code{fetch-@/assertions} (@ref{4.4.4.5}) to get a stream of all the assertions in the data base that should be checked for a match against the -pattern and the frame. The reason for @t{fetch-assertions} here is that we +pattern and the frame. The reason for @code{fetch-assertions} here is that we can often apply simple tests that will eliminate many of the entries in the data base from the pool of candidates for a successful match. The system would -still work if we eliminated @t{fetch-assertions} and simply checked a stream +still work if we eliminated @code{fetch-assertions} and simply checked a stream of all assertions in the data base, but the computation would be less efficient because we would need to make many more calls to the matcher. @@ -29242,9 +29242,9 @@ because we would need to make many more calls to the matcher. @end lisp @noindent -@t{Check-an-assertion} takes as arguments a pattern, a data object +@code{Check-an-assertion} takes as arguments a pattern, a data object (assertion), and a frame and returns either a one-element stream containing the -extended frame or @t{the-empty-stream} if the match fails. +extended frame or @code{the-empty-stream} if the match fails. @lisp (define (check-an-assertion @@ -29258,7 +29258,7 @@ extended frame or @t{the-empty-stream} if the match fails. @end lisp @noindent -The basic pattern matcher returns either the symbol @t{failed} or an +The basic pattern matcher returns either the symbol @code{failed} or an extension of the given frame. The basic idea of the matcher is to check the pattern against the data, element by element, accumulating bindings for the pattern variables. If the pattern and the data object are the same, the match @@ -29266,10 +29266,10 @@ succeeds and we return the frame of bindings accumulated so far. Otherwise, if the pattern is a variable we extend the current frame by binding the variable to the data, so long as this is consistent with the bindings already in the frame. If the pattern and the data are both pairs, we (recursively) match the -@t{car} of the pattern against the @t{car} of the data to produce a -frame; in this frame we then match the @t{cdr} of the pattern against the -@t{cdr} of the data. If none of these cases are applicable, the match fails -and we return the symbol @t{failed}. +@code{car} of the pattern against the @code{car} of the data to produce a +frame; in this frame we then match the @code{cdr} of the pattern against the +@code{cdr} of the data. If none of these cases are applicable, the match fails +and we return the symbol @code{failed}. @lisp (define (pattern-match pat dat frame) @@ -29305,22 +29305,22 @@ If there is no binding for the variable in the frame, we simply add the binding of the variable to the data. Otherwise we match, in the frame, the data against the value of the variable in the frame. If the stored value contains only constants, as it must if it was stored during pattern matching by -@t{extend-if-consistent}, then the match simply tests whether the stored and +@code{extend-if-consistent}, then the match simply tests whether the stored and new values are the same. If so, it returns the unmodified frame; if not, it returns a failure indication. The stored value may, however, contain pattern variables if it was stored during unification (see @ref{4.4.4.4}). The recursive match of the stored pattern against the new data will add or check bindings for the variables in this pattern. For example, suppose we have a -frame in which @t{?x} is bound to @t{(f ?y)} and @t{?y} is unbound, -and we wish to augment this frame by a binding of @t{?x} to @t{(f b)}. -We look up @t{?x} and find that it is bound to @t{(f ?y)}. This leads us -to match @t{(f ?y)} against the proposed new value @t{(f b)} in the same +frame in which @code{?x} is bound to @code{(f ?y)} and @code{?y} is unbound, +and we wish to augment this frame by a binding of @code{?x} to @code{(f b)}. +We look up @code{?x} and find that it is bound to @code{(f ?y)}. This leads us +to match @code{(f ?y)} against the proposed new value @code{(f b)} in the same frame. Eventually this match extends the frame by adding a binding of -@t{?y} to @t{b}. @t{?X} remains bound to @t{(f ?y)}. We never +@code{?y} to @code{b}. @code{?X} remains bound to @code{(f ?y)}. We never modify a stored binding and we never store more than one binding for a given variable. -The procedures used by @t{extend-if-consistent} to manipulate bindings are +The procedures used by @code{extend-if-consistent} to manipulate bindings are defined in @ref{4.4.4.8}. @subsubheading Patterns with dotted tails @@ -29330,33 +29330,33 @@ variable matches the rest of the data list (rather than the next element of the data list), just as one would expect with the dotted-tail notation described in @ref{Exercise 2.20}. Although the pattern matcher we have just implemented doesn't look for dots, it does behave as we want. This is because the Lisp -@t{read} primitive, which is used by @t{query-driver-loop} to read the +@code{read} primitive, which is used by @code{query-driver-loop} to read the query and represent it as a list structure, treats dots in a special way. -When @t{read} sees a dot, instead of making the next item be the next -element of a list (the @t{car} of a @t{cons} whose @t{cdr} will be the -rest of the list) it makes the next item be the @t{cdr} of the list -structure. For example, the list structure produced by @t{read} for the -pattern @t{(computer ?type)} could be constructed by evaluating the -expression @t{(cons 'computer (cons '?type '()))}, and that for -@t{(computer . ?type)} could be constructed by evaluating the expression -@t{(cons 'computer '?type)}. +When @code{read} sees a dot, instead of making the next item be the next +element of a list (the @code{car} of a @code{cons} whose @code{cdr} will be the +rest of the list) it makes the next item be the @code{cdr} of the list +structure. For example, the list structure produced by @code{read} for the +pattern @code{(computer ?type)} could be constructed by evaluating the +expression @code{(cons 'computer (cons '?type '()))}, and that for +@code{(computer . ?type)} could be constructed by evaluating the expression +@code{(cons 'computer '?type)}. -Thus, as @t{pattern-match} recursively compares @t{car}s and @t{cdr}s +Thus, as @code{pattern-match} recursively compares @code{car}s and @code{cdr}s of a data list and a pattern that had a dot, it eventually matches the variable -after the dot (which is a @t{cdr} of the pattern) against a sublist of the +after the dot (which is a @code{cdr} of the pattern) against a sublist of the data list, binding the variable to that list. For example, matching the -pattern @t{(computer . ?type)} against @t{(computer programmer trainee)} -will match @t{?type} against the list @t{(programmer trainee)}. +pattern @code{(computer . ?type)} against @code{(computer programmer trainee)} +will match @code{?type} against the list @code{(programmer trainee)}. @node 4.4.4.4, 4.4.4.5, 4.4.4.3, 4.4.4 @subsubsection Rules and Unification -@t{Apply-rules} is the rule analog of @t{find-assertions} +@code{Apply-rules} is the rule analog of @code{find-assertions} (@ref{4.4.4.3}). It takes as input a pattern and a frame, and it forms a stream of extension frames by applying rules from the data base. -@t{Stream-flatmap} maps @t{apply-a-rule} down the stream of possibly -applicable rules (selected by @t{fetch-rules}, @ref{4.4.4.5}) and +@code{Stream-flatmap} maps @code{apply-a-rule} down the stream of possibly +applicable rules (selected by @code{fetch-rules}, @ref{4.4.4.5}) and combines the resulting streams of frames. @lisp @@ -29368,7 +29368,7 @@ combines the resulting streams of frames. @end lisp @noindent -@t{Apply-a-rule} applies rules using the method outlined in +@code{Apply-a-rule} applies rules using the method outlined in @ref{4.4.2}. It first augments its argument frame by unifying the rule conclusion with the pattern in the given frame. If this succeeds, it evaluates the rule body in this new frame. @@ -29376,14 +29376,14 @@ the rule body in this new frame. Before any of this happens, however, the program renames all the variables in the rule with unique new names. The reason for this is to prevent the variables for different rule applications from becoming confused with each -other. For instance, if two rules both use a variable named @t{?x}, then -each one may add a binding for @t{?x} to the frame when it is applied. -These two @t{?x}'s have nothing to do with each other, and we should not be +other. For instance, if two rules both use a variable named @code{?x}, then +each one may add a binding for @code{?x} to the frame when it is applied. +These two @code{?x}'s have nothing to do with each other, and we should not be fooled into thinking that the two bindings must be consistent. Rather than rename variables, we could devise a more clever environment structure; however, the renaming approach we have chosen here is the most straightforward, even if not the most efficient. (See @ref{Exercise 4.79}.) Here is the -@t{apply-a-rule} procedure: +@code{apply-a-rule} procedure: @lisp (define (apply-a-rule rule @@ -29403,15 +29403,15 @@ not the most efficient. (See @ref{Exercise 4.79}.) Here is the @end lisp @noindent -The selectors @t{rule-body} and @t{conclusion} that extract parts of a +The selectors @code{rule-body} and @code{conclusion} that extract parts of a rule are defined in @ref{4.4.4.7}. We generate unique variable names by associating a unique identifier (such as a number) with each rule application and combining this identifier with the original variable names. For example, if the rule-application identifier is 7, -we might change each @t{?x} in the rule to @t{?x-7} and each @t{?y} in -the rule to @t{?y-7}. (@t{Make-new-variable} and -@t{new-rule-application-id} are included with the syntax procedures in +we might change each @code{?x} in the rule to @code{?x-7} and each @code{?y} in +the rule to @code{?y-7}. (@code{Make-new-variable} and +@code{new-rule-application-id} are included with the syntax procedures in @ref{4.4.4.7}.) @lisp @@ -29433,10 +29433,10 @@ the rule to @t{?y-7}. (@t{Make-new-variable} and @noindent The unification algorithm is implemented as a procedure that takes as inputs two patterns and a frame and returns either the extended frame or the symbol -@t{failed}. The unifier is like the pattern matcher except that it is +@code{failed}. The unifier is like the pattern matcher except that it is symmetrical---variables are allowed on both sides of the match. -@t{Unify-match} is basically the same as @t{pattern-match}, except that -there is extra code (marked ``@t{***}'' below) to handle the case where the +@code{Unify-match} is basically the same as @code{pattern-match}, except that +there is extra code (marked ``@code{***}'' below) to handle the case where the object on the right side of the match is a variable. @lisp @@ -29465,9 +29465,9 @@ object on the right side of the match is a variable. @noindent In unification, as in one-sided pattern matching, we want to accept a proposed extension of the frame only if it is consistent with existing bindings. The -procedure @t{extend-if-possible} used in unification is the same as the -@t{extend-if-consistent} used in pattern matching except for two special -checks, marked ``@t{***}'' in the program below. In the first case, if the +procedure @code{extend-if-possible} used in unification is the same as the +@code{extend-if-consistent} used in pattern matching except for two special +checks, marked ``@code{***}'' in the program below. In the first case, if the variable we are trying to match is not bound, but the value we are trying to match it with is itself a (different) variable, it is necessary to check to see if the value is bound, and if so, to match its value. If both parties to the @@ -29476,24 +29476,24 @@ match are unbound, we may bind either to the other. The second check deals with attempts to bind a variable to a pattern that includes that variable. Such a situation can occur whenever a variable is repeated in both patterns. Consider, for example, unifying the two patterns -@t{(?x ?x)} and @t{(?y <@var{expression involving @t{?y}}>)} in a -frame where both @t{?x} and @t{?y} are unbound. First @t{?x} is -matched against @t{?y}, making a binding of @t{?x} to @t{?y}. Next, -the same @t{?x} is matched against the given expression involving @t{?y}. -Since @t{?x} is already bound to @t{?y}, this results in matching -@t{?y} against the expression. If we think of the unifier as finding a set +@code{(?x ?x)} and @code{(?y <@var{expression involving @code{?y}}>)} in a +frame where both @code{?x} and @code{?y} are unbound. First @code{?x} is +matched against @code{?y}, making a binding of @code{?x} to @code{?y}. Next, +the same @code{?x} is matched against the given expression involving @code{?y}. +Since @code{?x} is already bound to @code{?y}, this results in matching +@code{?y} against the expression. If we think of the unifier as finding a set of values for the pattern variables that make the patterns the same, then these -patterns imply instructions to find a @t{?y} such that @t{?y} is equal to -the expression involving @t{?y}. There is no general method for solving +patterns imply instructions to find a @code{?y} such that @code{?y} is equal to +the expression involving @code{?y}. There is no general method for solving such equations, so we reject such bindings; these cases are recognized by the -predicate @t{depends-on?}.@footnote{In general, unifying @t{?y} with an -expression involving @t{?y} would require our being able to find a fixed -point of the equation @t{?y} = <@var{expression involving @t{?y}}>. It +predicate @code{depends-on?}.@footnote{In general, unifying @code{?y} with an +expression involving @code{?y} would require our being able to find a fixed +point of the equation @code{?y} = <@var{expression involving @code{?y}}>. It is sometimes possible to syntactically form an expression that appears to be -the solution. For example, @t{?y} = @t{(f ?y)} seems to have the fixed -point @t{(f (f (f @dots{} )))}, which we can produce by beginning with the -expression @t{(f ?y)} and repeatedly substituting @t{(f ?y)} for -@t{?y}. Unfortunately, not every such equation has a meaningful fixed +the solution. For example, @code{?y} = @code{(f ?y)} seems to have the fixed +point @code{(f (f (f @dots{} )))}, which we can produce by beginning with the +expression @code{(f ?y)} and repeatedly substituting @code{(f ?y)} for +@code{?y}. Unfortunately, not every such equation has a meaningful fixed point. The issues that arise here are similar to the issues of manipulating infinite series in mathematics. For example, we know that 2 is the solution to the equation @math{y = 1 + y \big/ 2}. Beginning with the expression @math{1 + y \big/ 2} @@ -29552,10 +29552,10 @@ identical, the first result is a valid assertion about infinite series but the second is not. Similarly, for our unification results, reasoning with an arbitrary syntactically constructed expression may lead to errors.} On the other hand, we do not want to reject attempts to bind a variable to itself. -For example, consider unifying @t{(?x ?x)} and @t{(?y ?y)}. The second -attempt to bind @t{?x} to @t{?y} matches @t{?y} (the stored value of -@t{?x}) against @t{?y} (the new value of @t{?x}). This is taken care -of by the @t{equal?} clause of @t{unify-match}. +For example, consider unifying @code{(?x ?x)} and @code{(?y ?y)}. The second +attempt to bind @code{?x} to @code{?y} matches @code{?y} (the stored value of +@code{?x}) against @code{?y} (the new value of @code{?x}). This is taken care +of by the @code{equal?} clause of @code{unify-match}. @lisp (define (extend-if-possible var val frame) @@ -29580,11 +29580,11 @@ of by the @t{equal?} clause of @t{unify-match}. @end lisp @noindent -@t{Depends-on?} is a predicate that tests whether an expression proposed to +@code{Depends-on?} is a predicate that tests whether an expression proposed to be the value of a pattern variable depends on the variable. This must be done relative to the current frame because the expression may contain occurrences of a variable that already has a value that depends on our test variable. The -structure of @t{depends-on?} is a simple recursive tree walk in which we +structure of @code{depends-on?} is a simple recursive tree walk in which we substitute for the values of variables whenever necessary. @lisp @@ -29613,16 +29613,16 @@ substitute for the values of variables whenever necessary. One important problem in designing logic programming languages is that of arranging things so that as few irrelevant data-base entries as possible will be examined in checking a given pattern. In our system, in addition to storing -all assertions in one big stream, we store all assertions whose @t{car}s are +all assertions in one big stream, we store all assertions whose @code{car}s are constant symbols in separate streams, in a table indexed by the symbol. To fetch an assertion that may match a pattern, we first check to see if the -@t{car} of the pattern is a constant symbol. If so, we return (to be tested -using the matcher) all the stored assertions that have the same @t{car}. If -the pattern's @t{car} is not a constant symbol, we return all the stored +@code{car} of the pattern is a constant symbol. If so, we return (to be tested +using the matcher) all the stored assertions that have the same @code{car}. If +the pattern's @code{car} is not a constant symbol, we return all the stored assertions. Cleverer methods could also take advantage of information in the -frame, or try also to optimize the case where the @t{car} of the pattern is +frame, or try also to optimize the case where the @code{car} of the pattern is not a constant symbol. We avoid building our criteria for indexing (using the -@t{car}, handling only the case of constant symbols) into the program; +@code{car}, handling only the case of constant symbols) into the program; instead we call on predicates and selectors that embody our criteria. @lisp @@ -29638,7 +29638,7 @@ instead we call on predicates and selectors that embody our criteria. @end lisp @noindent -@t{Get-stream} looks up a stream in the table and returns an empty stream if +@code{Get-stream} looks up a stream in the table and returns an empty stream if nothing is stored there. @lisp @@ -29648,16 +29648,16 @@ nothing is stored there. @end lisp @noindent -Rules are stored similarly, using the @t{car} of the rule conclusion. Rule +Rules are stored similarly, using the @code{car} of the rule conclusion. Rule conclusions are arbitrary patterns, however, so they differ from assertions in -that they can contain variables. A pattern whose @t{car} is a constant +that they can contain variables. A pattern whose @code{car} is a constant symbol can match rules whose conclusions start with a variable as well as rules -whose conclusions have the same @t{car}. Thus, when fetching rules that -might match a pattern whose @t{car} is a constant symbol we fetch all rules +whose conclusions have the same @code{car}. Thus, when fetching rules that +might match a pattern whose @code{car} is a constant symbol we fetch all rules whose conclusions start with a variable as well as those whose conclusions have -the same @t{car} as the pattern. For this purpose we store all rules whose +the same @code{car} as the pattern. For this purpose we store all rules whose conclusions start with a variable in a separate stream in our table, indexed by -the symbol @t{?}. +the symbol @code{?}. @lisp (define THE-RULES the-empty-stream) @@ -29674,7 +29674,7 @@ the symbol @t{?}. @end lisp @noindent -@t{Add-rule-or-assertion!} is used by @t{query-driver-loop} to add +@code{Add-rule-or-assertion!} is used by @code{query-driver-loop} to add assertions and rules to the data base. Each item is stored in the index, if appropriate, and in a stream of all assertions or rules in the data base. @@ -29740,7 +29740,7 @@ variable or a constant symbol. @end lisp @noindent -The key under which a pattern is stored in the table is either @t{?} (if it +The key under which a pattern is stored in the table is either @code{?} (if it starts with a variable) or the constant symbol with which it starts. @lisp @@ -29760,10 +29760,10 @@ pattern starts with a constant symbol. @quotation @strong{@anchor{Exercise 4.70}Exercise 4.70:} What is the purpose of the -@t{let} bindings in the procedures @t{add-assertion!} and -@t{add-rule!} ? What would be wrong with the following implementation of -@t{add-assertion!} ? Hint: Recall the definition of the infinite stream of -ones in @ref{3.5.2}: @t{(define ones (cons-stream 1 ones))}. +@code{let} bindings in the procedures @code{add-assertion!} and +@code{add-rule!} ? What would be wrong with the following implementation of +@code{add-assertion!} ? Hint: Recall the definition of the infinite stream of +ones in @ref{3.5.2}: @code{(define ones (cons-stream 1 ones))}. @lisp (define (add-assertion! assertion) @@ -29781,9 +29781,9 @@ ones in @ref{3.5.2}: @t{(define ones (cons-stream 1 ones))}. The query system uses a few stream operations that were not presented in @ref{Chapter 3}. -@t{Stream-append-delayed} and @t{interleave-delayed} are just like -@t{stream-@/append} and @t{interleave} (@ref{3.5.3}), except that -they take a delayed argument (like the @t{integral} procedure in +@code{Stream-append-delayed} and @code{interleave-delayed} are just like +@code{stream-@/append} and @code{interleave} (@ref{3.5.3}), except that +they take a delayed argument (like the @code{integral} procedure in @ref{3.5.4}). This postpones looping in some cases (see @ref{Exercise 4.71}). @lisp @@ -29805,10 +29805,10 @@ they take a delayed argument (like the @t{integral} procedure in @end lisp @noindent -@t{Stream-flatmap}, which is used throughout the query evaluator to map a +@code{Stream-flatmap}, which is used throughout the query evaluator to map a procedure over a stream of frames and combine the resulting streams of frames, -is the stream analog of the @t{flatmap} procedure introduced for ordinary -lists in @ref{2.2.3}. Unlike ordinary @t{flatmap}, however, we +is the stream analog of the @code{flatmap} procedure introduced for ordinary +lists in @ref{2.2.3}. Unlike ordinary @code{flatmap}, however, we accumulate the streams with an interleaving process, rather than simply appending them (see @ref{Exercise 4.72} and @ref{Exercise 4.73}). @@ -29836,9 +29836,9 @@ consisting of a single element: @node 4.4.4.7, 4.4.4.8, 4.4.4.6, 4.4.4 @subsubsection Query Syntax Procedures -@t{Type} and @t{contents}, used by @t{qeval} (@ref{4.4.4.2}), -specify that a special form is identified by the symbol in its @t{car}. -They are the same as the @t{type-tag} and @t{contents} procedures in +@code{Type} and @code{contents}, used by @code{qeval} (@ref{4.4.4.2}), +specify that a special form is identified by the symbol in its @code{car}. +They are the same as the @code{type-tag} and @code{contents} procedures in @ref{2.4.2}, except for the error message. @lisp @@ -29855,9 +29855,9 @@ They are the same as the @t{type-tag} and @t{contents} procedures in @end lisp @noindent -The following procedures, used by @t{query-driver-loop} (in +The following procedures, used by @code{query-driver-loop} (in @ref{4.4.4.1}), specify that rules and assertions are added to the data base by -expressions of the form @t{(assert! <@var{rule-or-assertion}>)}: +expressions of the form @code{(assert! <@var{rule-or-assertion}>)}: @lisp (define (assertion-to-be-added? exp) @@ -29867,8 +29867,8 @@ expressions of the form @t{(assert! <@var{rule-or-assertion}>)}: @end lisp @noindent -Here are the syntax definitions for the @t{and}, @t{or}, @t{not}, and -@t{lisp-@/value} special forms (@ref{4.4.4.2}): +Here are the syntax definitions for the @code{and}, @code{or}, @code{not}, and +@code{lisp-@/value} special forms (@ref{4.4.4.2}): @lisp (define (empty-conjunction? exps) (null? exps)) @@ -29896,26 +29896,26 @@ The following three procedures define the syntax of rules: @end lisp @noindent -@t{Query-driver-loop} (@ref{4.4.4.1}) calls -@t{query-@/syntax-@/process} to transform pattern variables in the expression, -which have the form @t{?symbol}, into the internal format @t{(? symbol)}. -That is to say, a pattern such as @t{(job ?x ?y)} is actually represented -internally by the system as @t{(job (? x) (? y))}. This increases the +@code{Query-driver-loop} (@ref{4.4.4.1}) calls +@code{query-@/syntax-@/process} to transform pattern variables in the expression, +which have the form @code{?symbol}, into the internal format @code{(? symbol)}. +That is to say, a pattern such as @code{(job ?x ?y)} is actually represented +internally by the system as @code{(job (? x) (? y))}. This increases the efficiency of query processing, since it means that the system can check to see -if an expression is a pattern variable by checking whether the @t{car} of -the expression is the symbol @t{?}, rather than having to extract characters +if an expression is a pattern variable by checking whether the @code{car} of +the expression is the symbol @code{?}, rather than having to extract characters from the symbol. The syntax transformation is accomplished by the following procedure:@footnote{Most Lisp systems give the user the ability to modify the -ordinary @t{read} procedure to perform such transformations by defining +ordinary @code{read} procedure to perform such transformations by defining @newterm{reader macro characters}. Quoted expressions are already handled in -this way: The reader automatically translates @t{'expression} into -@t{(quote expression)} before the evaluator sees it. We could arrange for -@t{?expression} to be transformed into @t{(? expression)} in the same +this way: The reader automatically translates @code{'expression} into +@code{(quote expression)} before the evaluator sees it. We could arrange for +@code{?expression} to be transformed into @code{(? expression)} in the same way; however, for the sake of clarity we have included the transformation procedure here explicitly. -@t{Expand-question-mark} and @t{contract-question-mark} use several -procedures with @t{string} in their names. These are Scheme primitives.} +@code{Expand-question-mark} and @code{contract-question-mark} use several +procedures with @code{string} in their names. These are Scheme primitives.} @lisp (define (query-syntax-process exp) @@ -29941,7 +29941,7 @@ procedures with @t{string} in their names. These are Scheme primitives.} @noindent Once the variables are transformed in this way, the variables in a pattern are -lists starting with @t{?}, and the constant symbols (which need to be +lists starting with @code{?}, and the constant symbols (which need to be recognized for data-base indexing, @ref{4.4.4.5}) are just the symbols. @lisp @@ -29967,7 +29967,7 @@ applied. @end lisp @noindent -When @t{query-driver-loop} instantiates the query to print the answer, it +When @code{query-driver-loop} instantiates the query to print the answer, it converts any unbound pattern variables back to the right form for printing, using @@ -30003,8 +30003,8 @@ Frames are represented as lists of bindings, which are variable-value pairs: @quotation @strong{@anchor{Exercise 4.71}Exercise 4.71:} Louis Reasoner wonders why the -@t{simple-query} and @t{disjoin} procedures (@ref{4.4.4.2}) are -implemented using explicit @t{delay} operations, rather than being defined +@code{simple-query} and @code{disjoin} procedures (@ref{4.4.4.2}) are +implemented using explicit @code{delay} operations, rather than being defined as follows: @lisp @@ -30031,15 +30031,15 @@ undesirable behavior? @end quotation @quotation -@strong{@anchor{Exercise 4.72}Exercise 4.72:} Why do @t{disjoin} and -@t{stream-flatmap} interleave the streams rather than simply append them? +@strong{@anchor{Exercise 4.72}Exercise 4.72:} Why do @code{disjoin} and +@code{stream-flatmap} interleave the streams rather than simply append them? Give examples that illustrate why interleaving works better. (Hint: Why did we -use @t{interleave} in @ref{3.5.3}?) +use @code{interleave} in @ref{3.5.3}?) @end quotation @quotation -@strong{@anchor{Exercise 4.73}Exercise 4.73:} Why does @t{flatten-stream} -use @t{delay} explicitly? What would be wrong with defining it as follows: +@strong{@anchor{Exercise 4.73}Exercise 4.73:} Why does @code{flatten-stream} +use @code{delay} explicitly? What would be wrong with defining it as follows: @lisp (define (flatten-stream stream) @@ -30053,8 +30053,8 @@ use @t{delay} explicitly? What would be wrong with defining it as follows: @quotation @strong{@anchor{Exercise 4.74}Exercise 4.74:} Alyssa P. Hacker proposes to use -a simpler version of @t{stream-@/flatmap} in @t{negate}, @t{lisp-@/value}, -and @t{find-@/assertions}. She observes that the procedure that is mapped +a simpler version of @code{stream-@/flatmap} in @code{negate}, @code{lisp-@/value}, +and @code{find-@/assertions}. She observes that the procedure that is mapped over the frame stream in these cases always produces either the empty stream or a singleton stream, so no interleaving is needed when combining these streams. @@ -30080,7 +30080,7 @@ Does the query system's behavior change if we change it in this way? @quotation @strong{@anchor{Exercise 4.75}Exercise 4.75:} Implement for the query language -a new special form called @t{unique}. @t{Unique} should succeed if there +a new special form called @code{unique}. @code{Unique} should succeed if there is precisely one item in the data base satisfying a specified query. For example, @@ -30116,48 +30116,48 @@ programmer. Moreover, should list all the jobs that are filled by only one person, and the people who fill them. -There are two parts to implementing @t{unique}. The first is to write a +There are two parts to implementing @code{unique}. The first is to write a procedure that handles this special form, and the second is to make -@t{qeval} dispatch to that procedure. The second part is trivial, since -@t{qeval} does its dispatching in a data-directed way. If your procedure is -called @t{uniquely-asserted}, all you need to do is +@code{qeval} dispatch to that procedure. The second part is trivial, since +@code{qeval} does its dispatching in a data-directed way. If your procedure is +called @code{uniquely-asserted}, all you need to do is @lisp (put 'unique 'qeval uniquely-asserted) @end lisp @noindent -and @t{qeval} will dispatch to this procedure for every query whose -@t{type} (@t{car}) is the symbol @t{unique}. +and @code{qeval} will dispatch to this procedure for every query whose +@code{type} (@code{car}) is the symbol @code{unique}. -The real problem is to write the procedure @t{uniquely-@/asserted}. This -should take as input the @t{contents} (@t{cdr}) of the @t{unique} +The real problem is to write the procedure @code{uniquely-@/asserted}. This +should take as input the @code{contents} (@code{cdr}) of the @code{unique} query, together with a stream of frames. For each frame in the stream, it -should use @t{qeval} to find the stream of all extensions to the frame that +should use @code{qeval} to find the stream of all extensions to the frame that satisfy the given query. Any stream that does not have exactly one item in it should be eliminated. The remaining streams should be passed back to be -accumulated into one big stream that is the result of the @t{unique} query. -This is similar to the implementation of the @t{not} special form. +accumulated into one big stream that is the result of the @code{unique} query. +This is similar to the implementation of the @code{not} special form. Test your implementation by forming a query that lists all people who supervise precisely one person. @end quotation @quotation -@strong{@anchor{Exercise 4.76}Exercise 4.76:} Our implementation of @t{and} +@strong{@anchor{Exercise 4.76}Exercise 4.76:} Our implementation of @code{and} as a series combination of queries (@ref{Figure 4.5}) is elegant, but it is -inefficient because in processing the second query of the @t{and} we must +inefficient because in processing the second query of the @code{and} we must scan the data base for each frame produced by the first query. If the data base has @math{n} elements, and a typical query produces a number of output frames proportional to @math{n} (say @math{n \big/ k}), then scanning the data base for each frame produced by the first query will require @math{n^2\! \big/ k} calls to the pattern matcher. Another approach would be to process the two clauses of the -@t{and} separately, then look for all pairs of output frames that are +@code{and} separately, then look for all pairs of output frames that are compatible. If each query produces @math{n \big/ k} output frames, then this means that we must perform @math{n^2\! \big/ k^2} compatibility checks---a factor of @math{k} fewer than the number of matches required in our current method. -Devise an implementation of @t{and} that uses this strategy. You must +Devise an implementation of @code{and} that uses this strategy. You must implement a procedure that takes two frames as inputs, checks whether the bindings in the frames are compatible, and, if so, produces a frame that merges the two sets of bindings. This operation is similar to unification. @@ -30165,7 +30165,7 @@ the two sets of bindings. This operation is similar to unification. @quotation @strong{@anchor{Exercise 4.77}Exercise 4.77:} In @ref{4.4.3} we saw -that @t{not} and @t{lisp-value} can cause the query language to give +that @code{not} and @code{lisp-value} can cause the query language to give ``wrong'' answers if these filtering operations are applied to frames in which variables are unbound. Devise a way to fix this shortcoming. One idea is to perform the filtering in a ``delayed'' manner by appending to the frame a @@ -30181,7 +30181,7 @@ number of intermediate frames generated. nondeterministic program to be implemented using the evaluator of @ref{4.3}, rather than as a stream process. In this approach, each query will produce a single answer (rather than the stream of all answers) and the user -can type @t{try-again} to see more answers. You should find that much of +can type @code{try-again} to see more answers. You should find that much of the mechanism we built in this section is subsumed by nondeterministic search and backtracking. You will probably also find, however, that your new query language has subtle differences in behavior from the one implemented here. Can @@ -30203,8 +30203,8 @@ evaluating @end lisp @noindent -there is no confusion between the @t{x} in @t{square} and the @t{x} in -@t{sum-of-squares}, because we evaluate the body of each procedure in an +there is no confusion between the @code{x} in @code{square} and the @code{x} in +@code{sum-of-squares}, because we evaluate the body of each procedure in an environment that is specially constructed to contain bindings for the local variables. In the query system, we used a different strategy to avoid name conflicts in applying rules. Each time we apply a rule we rename the variables @@ -30279,8 +30279,8 @@ Most of the primitive operations of our register machines are very simple. For example, an operation might add the numbers fetched from two registers, producing a result to be stored into a third register. Such an operation can be performed by easily described hardware. In order to deal with list -structure, however, we will also use the memory operations @t{car}, -@t{cdr}, and @t{cons}, which require an elaborate storage-allocation +structure, however, we will also use the memory operations @code{car}, +@code{cdr}, and @code{cons}, which require an elaborate storage-allocation mechanism. In @ref{5.3} we study their implementation in terms of more elementary operations. @@ -30324,20 +30324,20 @@ the following procedure: A machine to carry out this algorithm must keep track of two numbers, @math{a} and @math{b}, so let us assume that these numbers are stored in two registers with those names. The basic operations required are testing whether the contents of -register @t{b} is zero and computing the remainder of the contents of -register @t{a} divided by the contents of register @t{b}. The remainder +register @code{b} is zero and computing the remainder of the contents of +register @code{a} divided by the contents of register @code{b}. The remainder operation is a complex process, but assume for the moment that we have a primitive device that computes remainders. On each cycle of the @acronym{GCD} -algorithm, the contents of register @t{a} must be replaced by the contents -of register @t{b}, and the contents of @t{b} must be replaced by the -remainder of the old contents of @t{a} divided by the old contents of -@t{b}. It would be convenient if these replacements could be done +algorithm, the contents of register @code{a} must be replaced by the contents +of register @code{b}, and the contents of @code{b} must be replaced by the +remainder of the old contents of @code{a} divided by the old contents of +@code{b}. It would be convenient if these replacements could be done simultaneously, but in our model of register machines we will assume that only one register can be assigned a new value at each step. To accomplish the replacements, our machine will use a third ``temporary'' register, which we -call @t{t}. (First the remainder will be placed in @t{t}, then the -contents of @t{b} will be placed in @t{a}, and finally the remainder -stored in @t{t} will be placed in @t{b}.) +call @code{t}. (First the remainder will be placed in @code{t}, then the +contents of @code{b} will be placed in @code{a}, and finally the remainder +stored in @code{t} will be placed in @code{b}.) @float @quotation @@ -30378,33 +30378,33 @@ stored in @t{t} will be placed in @t{b}.) @noindent We can illustrate the registers and operations required for this machine by using the data-path diagram shown in @ref{Figure 5.1}. In this diagram, the -registers (@t{a}, @t{b}, and @t{t}) are represented by rectangles. +registers (@code{a}, @code{b}, and @code{t}) are represented by rectangles. Each way to assign a value to a register is indicated by an arrow with an -@t{X} behind the head, pointing from the source of data to the register. We -can think of the @t{X} as a button that, when pushed, allows the value at +@code{X} behind the head, pointing from the source of data to the register. We +can think of the @code{X} as a button that, when pushed, allows the value at the source to ``flow'' into the designated register. The label next to each button is the name we will use to refer to the button. The names are -arbitrary, and can be chosen to have mnemonic value (for example, @t{a<-b} -denotes pushing the button that assigns the contents of register @t{b} to -register @t{a}). The source of data for a register can be another register -(as in the @t{a<-b} assignment), an operation result (as in the @t{t<-r} +arbitrary, and can be chosen to have mnemonic value (for example, @code{a<-b} +denotes pushing the button that assigns the contents of register @code{b} to +register @code{a}). The source of data for a register can be another register +(as in the @code{a<-b} assignment), an operation result (as in the @code{t<-r} assignment), or a constant (a built-in value that cannot be changed, represented in a data-path diagram by a triangle containing the constant). An operation that computes a value from constants and the contents of registers is represented in a data-path diagram by a trapezoid containing a name for the -operation. For example, the box marked @t{rem} in @ref{Figure 5.1} +operation. For example, the box marked @code{rem} in @ref{Figure 5.1} represents an operation that computes the remainder of the contents of the -registers @t{a} and @t{b} to which it is attached. Arrows (without +registers @code{a} and @code{b} to which it is attached. Arrows (without buttons) point from the input registers and constants to the box, and arrows connect the operation's output value to registers. A test is represented by a circle containing a name for the test. For example, our @acronym{GCD} machine -has an operation that tests whether the contents of register @t{b} is zero. +has an operation that tests whether the contents of register @code{b} is zero. A test also has arrows from its input registers and constants, but it has no output arrows; its value is used by the controller rather than by the data paths. Overall, the data-path diagram shows the registers and operations that are required for the machine and how they must be connected. If we view the -arrows as wires and the @t{X} buttons as switches, the data-path diagram is +arrows as wires and the @code{X} buttons as switches, the data-path diagram is very like the wiring diagram for a machine that could be constructed from electrical components. @@ -30461,13 +30461,13 @@ data-path test identified in the diamond. We can interpret the controller in terms of a physical analogy: Think of the diagram as a maze in which a marble is rolling. When the marble rolls into a box, it pushes the data-path button that is named by the box. When the marble rolls into a decision node (such as -the test for @t{b} = 0), it leaves the node on the path determined by the +the test for @code{b} = 0), it leaves the node on the path determined by the result of the indicated test. Taken together, the data paths and the controller completely describe a machine for computing @acronym{GCD}s. We -start the controller (the rolling marble) at the place marked @t{start}, -after placing numbers in registers @t{a} and @t{b}. When the controller -reaches @t{done}, we will find the value of the @acronym{GCD} in register -@t{a}. +start the controller (the rolling marble) at the place marked @code{start}, +after placing numbers in registers @code{a} and @code{b}. When the controller +reaches @code{done}, we will find the value of the @acronym{GCD} in register +@code{a}. @quotation @strong{@anchor{Exercise 5.1}Exercise 5.1:} Design a register machine to @@ -30523,10 +30523,10 @@ The name of a data-path button to push to assign a value to a register. (This corresponds to a box in the controller diagram.) @item -A @t{test} instruction, that performs a specified test. +A @code{test} instruction, that performs a specified test. @item -A conditional branch (@t{branch} instruction) to a location indicated by a +A conditional branch (@code{branch} instruction) to a location indicated by a controller label, based on the result of the previous test. (The test and branch together correspond to a diamond in the controller diagram.) If the test is false, the controller should continue with the next instruction in the @@ -30534,7 +30534,7 @@ sequence. Otherwise, the controller should continue with the instruction after the label. @item -An unconditional branch (@t{goto} instruction) naming a controller label at +An unconditional branch (@code{goto} instruction) naming a controller label at which to continue execution. @end itemize @@ -30597,16 +30597,16 @@ data-path and controller descriptions so that we see it all together. To obtain this form of description, we will replace the arbitrary button and operation names by the definitions of their behavior. That is, instead of -saying (in the controller) ``Push button @t{t<-r}'' and separately saying -(in the data paths) ``Button @t{t<-r} assigns the value of the @t{rem} -operation to register @t{t}'' and ``The @t{rem} operation's inputs are -the contents of registers @t{a} and @t{b},'' we will say (in the -controller) ``Push the button that assigns to register @t{t} the value of -the @t{rem} operation on the contents of registers @t{a} and @t{b}.'' -Similarly, instead of saying (in the controller) ``Perform the @t{=} test'' -and separately saying (in the data paths) ``The @t{=} test operates on the -contents of register @t{b} and the constant 0,'' we will say ``Perform the -@t{=} test on the contents of register @t{b} and the constant 0.'' We +saying (in the controller) ``Push button @code{t<-r}'' and separately saying +(in the data paths) ``Button @code{t<-r} assigns the value of the @code{rem} +operation to register @code{t}'' and ``The @code{rem} operation's inputs are +the contents of registers @code{a} and @code{b},'' we will say (in the +controller) ``Push the button that assigns to register @code{t} the value of +the @code{rem} operation on the contents of registers @code{a} and @code{b}.'' +Similarly, instead of saying (in the controller) ``Perform the @code{=} test'' +and separately saying (in the data paths) ``The @code{=} test operates on the +contents of register @code{b} and the constant 0,'' we will say ``Perform the +@code{=} test on the contents of register @code{b} and the constant 0.'' We will omit the data-path description, leaving only the controller sequence. Thus, the @acronym{GCD} machine is described as follows: @@ -30728,19 +30728,19 @@ to describe the iterative factorial machine of @ref{Exercise 5.1,,Ex. 5.1}. Let us modify the @acronym{GCD} machine so that we can type in the numbers whose @acronym{GCD} we want and get the answer printed at our terminal. We will not discuss how to make a machine that can read and print, but will assume -(as we do when we use @t{read} and @t{display} in Scheme) that they are +(as we do when we use @code{read} and @code{display} in Scheme) that they are available as primitive operations.@footnote{This assumption glosses over a great deal of complexity. Usually a large portion of the implementation of a Lisp system is dedicated to making reading and printing work.} -@t{Read} is like the operations we have been using in that it produces a -value that can be stored in a register. But @t{read} does not take inputs +@code{Read} is like the operations we have been using in that it produces a +value that can be stored in a register. But @code{read} does not take inputs from any registers; its value depends on something that happens outside the parts of the machine we are designing. We will allow our machine's operations -to have such behavior, and thus will draw and notate the use of @t{read} +to have such behavior, and thus will draw and notate the use of @code{read} just as we do any other operation that computes a value. -@t{Print}, on the other hand, differs from the operations we have been using +@code{Print}, on the other hand, differs from the operations we have been using in a fundamental way: It does not produce an output value to be stored in a register. Though it has an effect, this effect is not on a part of the machine we are designing. We will refer to this kind of operation as an @@ -30749,8 +30749,8 @@ we represent an operation that computes a value---as a trapezoid that contains the name of the action. Arrows point to the action box from any inputs (registers or constants). We also associate a button with the action. Pushing the button makes the action happen. To make a controller push an action button -we use a new kind of instruction called @t{perform}. Thus, the action of -printing the contents of register @t{a} is represented in a controller +we use a new kind of instruction called @code{perform}. Thus, the action of +printing the contents of register @code{a} is represented in a controller sequence by the instruction @lisp @@ -30838,8 +30838,8 @@ simpler primitive operations. @noindent Consider the @acronym{GCD} machine. The machine has an instruction that -computes the remainder of the contents of registers @t{a} and @t{b} and -assigns the result to register @t{t}. If we want to construct the +computes the remainder of the contents of registers @code{a} and @code{b} and +assigns the result to register @code{t}. If we want to construct the @acronym{GCD} machine without using a primitive remainder operation, we must specify how to compute remainders in terms of simpler operations, such as subtraction. Indeed, we can write a Scheme procedure that finds remainders in @@ -30904,9 +30904,9 @@ roots using Newton's method, as described in @ref{Sec.1.1.7,,1.1.7}: (sqrt-iter 1.0)) @end lisp -Begin by assuming that @t{good-enough?} and @t{improve} operations are +Begin by assuming that @code{good-enough?} and @code{improve} operations are available as primitives. Then show how to expand these in terms of arithmetic -operations. Describe each version of the @t{sqrt} machine design by drawing +operations. Describe each version of the @code{sqrt} machine design by drawing a data-path diagram and writing a controller definition in the register-machine language. @end quotation @@ -30978,10 +30978,10 @@ When designing a machine to perform a computation, we would often prefer to arrange for components to be shared by different parts of the computation rather than duplicate the components. Consider a machine that includes two @acronym{GCD} computations---one that finds the @acronym{GCD} of the contents -of registers @t{a} and @t{b} and one that finds the @acronym{GCD} of the -contents of registers @t{c} and @t{d}. We might start by assuming we -have a primitive @t{gcd} operation, then expand the two instances of -@t{gcd} in terms of more primitive operations. @ref{Figure 5.7} shows just +of registers @code{a} and @code{b} and one that finds the @acronym{GCD} of the +contents of registers @code{c} and @code{d}. We might start by assuming we +have a primitive @code{gcd} operation, then expand the two instances of +@code{gcd} in terms of more primitive operations. @ref{Figure 5.7} shows just the @acronym{GCD} portions of the resulting machine's data paths, without showing how they connect to the rest of the machine. The figure also shows the corresponding portions of the machine's controller sequence. @@ -30991,11 +30991,11 @@ equality. If the duplicated components are complicated, as is the remainder box, this will not be an economical way to build the machine. We can avoid duplicating the data-path components by using the same components for both @acronym{GCD} computations, provided that doing so will not affect the rest of -the larger machine's computation. If the values in registers @t{a} and -@t{b} are not needed by the time the controller gets to @t{gcd-2} (or if +the larger machine's computation. If the values in registers @code{a} and +@code{b} are not needed by the time the controller gets to @code{gcd-2} (or if these values can be moved to other registers for safekeeping), we can change -the machine so that it uses registers @t{a} and @t{b}, rather than -registers @t{c} and @t{d}, in computing the second @acronym{GCD} as well +the machine so that it uses registers @code{a} and @code{b}, rather than +registers @code{c} and @code{d}, in computing the second @acronym{GCD} as well as the first. If we do this, we obtain the controller sequence shown in @ref{Figure 5.8}. @@ -31030,18 +31030,18 @@ after-gcd-2 We have removed the duplicate data-path components (so that the data paths are again as in @ref{Figure 5.1}), but the controller now has two @acronym{GCD} sequences that differ only in their entry-point labels. It would be better to -replace these two sequences by branches to a single sequence---a @t{gcd} +replace these two sequences by branches to a single sequence---a @code{gcd} @newterm{subroutine}---at the end of which we branch back to the correct place in the main instruction sequence. We can accomplish this as follows: Before -branching to @t{gcd}, we place a distinguishing value (such as 0 or 1) into -a special register, @t{continue}. At the end of the @t{gcd} subroutine -we return either to @t{after-gcd-1} or to @t{after-gcd-2}, depending on -the value of the @t{continue} register. @ref{Figure 5.9} shows the relevant +branching to @code{gcd}, we place a distinguishing value (such as 0 or 1) into +a special register, @code{continue}. At the end of the @code{gcd} subroutine +we return either to @code{after-gcd-1} or to @code{after-gcd-2}, depending on +the value of the @code{continue} register. @ref{Figure 5.9} shows the relevant portion of the resulting controller sequence, which includes only a single copy -of the @t{gcd} instructions. +of the @code{gcd} instructions. @quotation -@strong{@anchor{Figure 5.9}Figure 5.9:} @math{\downarrow} Using a @t{continue} register to +@strong{@anchor{Figure 5.9}Figure 5.9:} @math{\downarrow} Using a @code{continue} register to avoid the duplicate controller sequence in @ref{Figure 5.8}. @lisp @@ -31057,15 +31057,15 @@ gcd-done (branch (label after-gcd-1)) (goto (label after-gcd-2)) @dots{} -@r{;; Before branching to @t{gcd} from} +@r{;; Before branching to @code{gcd} from} @r{;; the first place where it is needed,} -@r{;; we place 0 in the @t{continue} register} +@r{;; we place 0 in the @code{continue} register} (assign continue (const 0)) (goto (label gcd)) after-gcd-1 @dots{} -@r{;; Before the second use of @t{gcd},} -@r{;; we place 1 in the @t{continue} register} +@r{;; Before the second use of @code{gcd},} +@r{;; we place 1 in the @code{continue} register} (assign continue (const 1)) (goto (label gcd)) after-gcd-2 @@ -31077,9 +31077,9 @@ after-gcd-2 This is a reasonable approach for handling small problems, but it would be awkward if there were many instances of @acronym{GCD} computations in the controller sequence. To decide where to continue executing after the -@t{gcd} subroutine, we would need tests in the data paths and branch -instructions in the controller for all the places that use @t{gcd}. A more -powerful method for implementing subroutines is to have the @t{continue} +@code{gcd} subroutine, we would need tests in the data paths and branch +instructions in the controller for all the places that use @code{gcd}. A more +powerful method for implementing subroutines is to have the @code{continue} register hold the label of the entry point in the controller sequence at which execution should continue when the subroutine is finished. Implementing this strategy requires a new kind of connection between the data paths and the @@ -31087,19 +31087,19 @@ controller of a register machine: There must be a way to assign to a register a label in the controller sequence in such a way that this value can be fetched from the register and used to continue execution at the designated entry point. -To reflect this ability, we will extend the @t{assign} instruction of the +To reflect this ability, we will extend the @code{assign} instruction of the register-machine language to allow a register to be assigned as value a label from the controller sequence (as a special kind of constant). We will also -extend the @t{goto} instruction to allow execution to continue at the entry +extend the @code{goto} instruction to allow execution to continue at the entry point described by the contents of a register rather than only at an entry point described by a constant label. Using these new constructs we can -terminate the @t{gcd} subroutine with a branch to the location stored in the -@t{continue} register. This leads to the controller sequence shown in +terminate the @code{gcd} subroutine with a branch to the location stored in the +@code{continue} register. This leads to the controller sequence shown in @ref{Figure 5.10,,Fig.5.10}. @quotation @strong{@anchor{Figure 5.10}Figure 5.10:} @math{\downarrow} Assigning labels to the -@t{continue} register simplifies and generalizes the strategy shown in +@code{continue} register simplifies and generalizes the strategy shown in @ref{Figure 5.9}. @lisp @@ -31113,14 +31113,14 @@ gcd gcd-done (goto (reg continue)) @dots{} -@r{;; Before calling @t{gcd},} -@r{;; we assign to @t{continue} the label} -@r{;; to which @t{gcd} should return.} +@r{;; Before calling @code{gcd},} +@r{;; we assign to @code{continue} the label} +@r{;; to which @code{gcd} should return.} (assign continue (label after-gcd-1)) (goto (label gcd)) after-gcd-1 @dots{} -@r{;; Here is the second call to @t{gcd},} +@r{;; Here is the second call to @code{gcd},} @r{;; with a different continuation.} (assign continue (label after-gcd-2)) (goto (label gcd)) @@ -31131,12 +31131,12 @@ after-gcd-2 @noindent A machine with more than one subroutine could use multiple continuation -registers (e.g., @t{gcd-continue}, @t{factorial-@/continue}) or we could -have all subroutines share a single @t{continue} register. Sharing is more -economical, but we must be careful if we have a subroutine (@t{sub1}) that -calls another subroutine (@t{sub2}). Unless @t{sub1} saves the contents -of @t{continue} in some other register before setting up @t{continue} for -the call to @t{sub2}, @t{sub1} will not know where to go when it is +registers (e.g., @code{gcd-continue}, @code{factorial-@/continue}) or we could +have all subroutines share a single @code{continue} register. Sharing is more +economical, but we must be careful if we have a subroutine (@code{sub1}) that +calls another subroutine (@code{sub2}). Unless @code{sub1} saves the contents +of @code{continue} in some other register before setting up @code{continue} for +the call to @code{sub2}, @code{sub1} will not know where to go when it is finished. The mechanism developed in the next section to handle recursion also provides a better solution to this problem of nested subroutine calls. @@ -31175,8 +31175,8 @@ Our @acronym{GCD} machine, modeled on the procedure @noindent similarly had to compute another @acronym{GCD}. But there is an important -difference between the @t{gcd} procedure, which reduces the original -computation to a new @acronym{GCD} computation, and @t{factorial}, which +difference between the @code{gcd} procedure, which reduces the original +computation to a new @acronym{GCD} computation, and @code{factorial}, which requires computing another factorial as a subproblem. In @acronym{GCD}, the answer to the new @acronym{GCD} computation is the answer to the original problem. To compute the next @acronym{GCD}, we simply place the new arguments @@ -31189,8 +31189,8 @@ In the case of factorial (or any recursive process) the answer to the new factorial subproblem is not the answer to the original problem. The value obtained for @math{(n - 1)!} must be multiplied by @math{n} to get the final answer. If we try to imitate the @acronym{GCD} design, and solve the factorial -subproblem by decrementing the @t{n} register and rerunning the factorial -machine, we will no longer have available the old value of @t{n} by which to +subproblem by decrementing the @code{n} register and rerunning the factorial +machine, we will no longer have available the old value of @code{n} by which to multiply the result. We thus need a second factorial machine to work on the subproblem. This second factorial computation itself has a factorial subproblem, which requires a third factorial machine, and so on. Since each @@ -31210,13 +31210,13 @@ subproblem, it can suspend work on the main problem, reuse the same physical parts to work on the subproblem, then continue the suspended computation. In the subproblem, the contents of the registers will be different than they -were in the main problem. (In this case the @t{n} register is decremented.) +were in the main problem. (In this case the @code{n} register is decremented.) In order to be able to continue the suspended computation, the machine must save the contents of any registers that will be needed after the subproblem is solved so that these can be restored to continue the suspended computation. In -the case of factorial, we will save the old value of @t{n}, to be restored -when we are finished computing the factorial of the decremented @t{n} -register.@footnote{One might argue that we don't need to save the old @t{n}; +the case of factorial, we will save the old value of @code{n}, to be restored +when we are finished computing the factorial of the decremented @code{n} +register.@footnote{One might argue that we don't need to save the old @code{n}; after we decrement it and solve the subproblem, we could simply increment it to recover the old value. Although this strategy works for factorial, it cannot work in general, since the old value of a register cannot always be computed @@ -31229,10 +31229,10 @@ nest of recursions the last subproblem to be entered is the first to be finished. This dictates the use of a @newterm{stack}, or ``last in, first out'' data structure, to save register values. We can extend the register-machine language to include a stack by adding two kinds of -instructions: Values are placed on the stack using a @t{save} instruction -and restored from the stack using a @t{restore} instruction. After a -sequence of values has been @t{save}d on the stack, a sequence of -@t{restore}s will retrieve these values in reverse order.@footnote{In +instructions: Values are placed on the stack using a @code{save} instruction +and restored from the stack using a @code{restore} instruction. After a +sequence of values has been @code{save}d on the stack, a sequence of +@code{restore}s will retrieve these values in reverse order.@footnote{In @ref{5.3} we will see how to implement a stack in terms of more primitive operations.} @@ -31245,14 +31245,14 @@ the beginning, as with an iterative process, because after solving the controller must suspend its computation of @math{n!}, solve the @math{(n - 1)!} subproblem, then continue its computation of @math{n!}. This view of the factorial computation suggests the use of the subroutine mechanism described in -@ref{5.1.3}, which has the controller use a @t{continue} register to +@ref{5.1.3}, which has the controller use a @code{continue} register to transfer to the part of the sequence that solves a subproblem and then continue where it left off on the main problem. We can thus make a factorial subroutine -that returns to the entry point stored in the @t{continue} register. Around -each subroutine call, we save and restore @t{continue} just as we do the -@t{n} register, since each ``level'' of the factorial computation will use -the same @t{continue} register. That is, the factorial subroutine must put -a new value in @t{continue} when it calls itself for a subproblem, but it +that returns to the entry point stored in the @code{continue} register. Around +each subroutine call, we save and restore @code{continue} just as we do the +@code{n} register, since each ``level'' of the factorial computation will use +the same @code{continue} register. That is, the factorial subroutine must put +a new value in @code{continue} when it calls itself for a subproblem, but it will need the old value in order to return to the place that called it to solve a subproblem. @@ -31297,9 +31297,9 @@ a subproblem. fact-loop (test (op =) (reg n) (const 1)) (branch (label base-case)) - @r{;; Set up for the recursive call by saving @t{n} and @t{continue}.} - @r{;; Set up @t{continue} so that the computation will continue} - @r{;; at @t{after-fact} when the subroutine returns.} + @r{;; Set up for the recursive call by saving @code{n} and @code{continue}.} + @r{;; Set up @code{continue} so that the computation will continue} + @r{;; at @code{after-fact} when the subroutine returns.} (save continue) (save n) (assign n (op -) (reg n) (const 1)) @@ -31308,7 +31308,7 @@ a subproblem. after-fact (restore n) (restore continue) - (assign val (op *) (reg n) (reg val)) @r{; @t{val} now contains} @math{n(n-1)!} + (assign val (op *) (reg n) (reg val)) @r{; @code{val} now contains} @math{n(n-1)!} (goto (reg continue)) @r{; return to caller} base-case (assign val (const 1)) @r{; base case: }1! = 1 @@ -31329,21 +31329,21 @@ a subproblem. @noindent @ref{Figure 5.11} shows the data paths and controller for a machine that -implements the recursive @t{factorial} procedure. The machine has a stack -and three registers, called @t{n}, @t{val}, and @t{continue}. To +implements the recursive @code{factorial} procedure. The machine has a stack +and three registers, called @code{n}, @code{val}, and @code{continue}. To simplify the data-path diagram, we have not named the register-assignment -buttons, only the stack-operation buttons (@t{sc} and @t{sn} to save -registers, @t{rc} and @t{rn} to restore registers). To operate the -machine, we put in register @t{n} the number whose factorial we wish to -compute and start the machine. When the machine reaches @t{fact-done}, the -computation is finished and the answer will be found in the @t{val} -register. In the controller sequence, @t{n} and @t{continue} are saved +buttons, only the stack-operation buttons (@code{sc} and @code{sn} to save +registers, @code{rc} and @code{rn} to restore registers). To operate the +machine, we put in register @code{n} the number whose factorial we wish to +compute and start the machine. When the machine reaches @code{fact-done}, the +computation is finished and the answer will be found in the @code{val} +register. In the controller sequence, @code{n} and @code{continue} are saved before each recursive call and restored upon return from the call. Returning from a call is accomplished by branching to the location stored in -@t{continue}. @t{Continue} is initialized when the machine starts so -that the last return will go to @t{fact-done}. The @t{val} register, +@code{continue}. @code{Continue} is initialized when the machine starts so +that the last return will go to @code{fact-done}. The @code{val} register, which holds the result of the factorial computation, is not saved before the -recursive call, because the old contents of @t{val} is not useful after the +recursive call, because the old contents of @code{val} is not useful after the subroutine returns. Only the new value, which is the value produced by the subcomputation, is needed. @@ -31357,7 +31357,7 @@ register machines augmented by stacks. When a recursive subproblem is encountered, we save on the stack the registers whose current values will be required after the subproblem is solved, solve the recursive subproblem, then restore the saved registers and continue execution on the main problem. The -@t{continue} register must always be saved. Whether there are other +@code{continue} register must always be saved. Whether there are other registers that need to be saved depends on the particular machine, since not all recursive computations need the original values of registers that are modified during solution of the subproblem (see @ref{Exercise 5.4}). @@ -31376,16 +31376,16 @@ of the Fibonacci numbers, which we introduced in @ref{1.2.2}: @noindent Just as with factorial, we can implement the recursive Fibonacci computation as -a register machine with registers @t{n}, @t{val}, and @t{continue}. +a register machine with registers @code{n}, @code{val}, and @code{continue}. The machine is more complex than the one for factorial, because there are two places in the controller sequence where we need to perform recursive calls---once to compute @math{{\rm Fib}(n - 1)} and once to compute @math{{\rm Fib}(n - 2)}. To set up for each of these calls, we save the registers whose values will be -needed later, set the @t{n} register to the number whose Fib we need to -compute recursively (@math{n - 1} or @math{n - 2}), and assign to @t{continue} the -entry point in the main sequence to which to return (@t{afterfib-n-1} or -@t{afterfib-n-2}, respectively). We then go to @t{fib-loop}. When we -return from the recursive call, the answer is in @t{val}. @ref{Figure 5.12} +needed later, set the @code{n} register to the number whose Fib we need to +compute recursively (@math{n - 1} or @math{n - 2}), and assign to @code{continue} the +entry point in the main sequence to which to return (@code{afterfib-n-1} or +@code{afterfib-n-2}, respectively). We then go to @code{fib-loop}. When we +return from the recursive call, the answer is in @code{val}. @ref{Figure 5.12} shows the controller sequence for this machine. @quotation @@ -31402,14 +31402,14 @@ Fibonacci numbers. @r{;; set up to compute Fib@math{(n-1)}} (save continue) (assign continue (label afterfib-n-1)) - (save n) @r{; save old value of @t{n}} + (save n) @r{; save old value of @code{n}} (assign n (op -) (reg n) - (const 1)) @r{; clobber @t{n} to @t{n-1}} + (const 1)) @r{; clobber @code{n} to @code{n-1}} (goto (label fib-loop)) @r{; perform recursive call} - afterfib-n-1 @r{; upon return, @t{val}} + afterfib-n-1 @r{; upon return, @code{val}} @r{; contains Fib@math{(n-1)}} (restore n) (restore continue) @@ -31420,18 +31420,18 @@ Fibonacci numbers. (assign continue (label afterfib-n-2)) (save val) @r{; save Fib@math{(n-1)}} (goto (label fib-loop)) - afterfib-n-2 @r{; upon return, @t{val}} + afterfib-n-2 @r{; upon return, @code{val}} @r{; contains Fib@math{(n-2)}} (assign n - (reg val)) @r{; @t{n} now contains Fib@math{(n-2)}} - (restore val) @r{; @t{val} now contains Fib@math{(n-1)}} + (reg val)) @r{; @code{n} now contains Fib@math{(n-2)}} + (restore val) @r{; @code{val} now contains Fib@math{(n-1)}} (restore continue) (assign val @r{; Fib@math{(n-1)} + Fib@math{(n-2)}} (op +) (reg val) (reg n)) (goto @r{; return to caller,} - (reg continue)) @r{; answer is in @t{val}} + (reg continue)) @r{; answer is in @code{val}} immediate-answer (assign val (reg n)) @r{; base case: Fib@math{(n) = n}} @@ -31483,8 +31483,8 @@ point in the execution. @quotation @strong{@anchor{Exercise 5.6}Exercise 5.6:} Ben Bitdiddle observes that the -Fibonacci machine's controller sequence has an extra @t{save} and an extra -@t{restore}, which can be removed to make a faster machine. Where are these +Fibonacci machine's controller sequence has an extra @code{save} and an extra +@code{restore}, which can be removed to make a faster machine. Where are these instructions? @end quotation @@ -31493,8 +31493,8 @@ instructions? @subsection Instruction Summary A controller instruction in our register-machine language has one of the -following forms, where each @math{\langle}@math{input_i}@math{\rangle} is either @t{(reg -<@var{register-name}>)} or @t{(const <@var{constant-value}>)}. These +following forms, where each @math{\langle}@math{input_i}@math{\rangle} is either @code{(reg +<@var{register-name}>)} or @code{(const <@var{constant-value}>)}. These instructions were introduced in @ref{5.1.1}: @lisp @@ -31536,10 +31536,10 @@ Instructions to use the stack were introduced in @ref{5.1.4}: The only kind of @math{\langle}@var{constant-value}@math{\rangle} we have seen so far is a number, but later we will use strings, symbols, and lists. For example,@* -@t{(const "abc")} is the string @t{"abc"},@* -@t{(const abc)} is the symbol @t{abc},@* -@t{(const (a b c))} is the list @t{(a b c)},@* -and @t{(const ())} is the empty list. +@code{(const "abc")} is the string @code{"abc"},@* +@code{(const abc)} is the symbol @code{abc},@* +@code{(const (a b c))} is the list @code{(a b c)},@* +and @code{(const ())} is the empty list. @node 5.2, 5.3, 5.1, Chapter 5 @section A Register-Machine Simulator @@ -31595,7 +31595,7 @@ the controller sequence and stopping when it reaches the end of the sequence. @noindent As an example of how these procedures are used, we can define -@t{gcd-machine} to be a model of the @acronym{GCD} machine of +@code{gcd-machine} to be a model of the @acronym{GCD} machine of @ref{5.1.1} as follows: @lisp @@ -31614,7 +31614,7 @@ As an example of how these procedures are used, we can define @end lisp @noindent -The first argument to @t{make-machine} is a list of register names. The +The first argument to @code{make-machine} is a list of register names. The next argument is a table (a list of two-element lists) that pairs each operation name with a Scheme procedure that implements the operation (that is, produces the same output value given the same input values). The last argument @@ -31636,9 +31636,9 @@ the machine, and examine the result when the simulation terminates: @end lisp @noindent -This computation will run much more slowly than a @t{gcd} procedure written +This computation will run much more slowly than a @code{gcd} procedure written in Scheme, because we will simulate low-level machine instructions, such as -@t{assign}, by much more complex operations. +@code{assign}, by much more complex operations. @quotation @strong{@anchor{Exercise 5.7}Exercise 5.7:} Use the simulator to test the @@ -31655,23 +31655,23 @@ machines you designed in @ref{Exercise 5.4}. @node 5.2.1, 5.2.2, 5.2, 5.2 @subsection The Machine Model -The machine model generated by @t{make-@/machine} is represented as a +The machine model generated by @code{make-@/machine} is represented as a procedure with local state using the message-passing techniques developed in -@ref{Chapter 3}. To build this model, @t{make-@/machine} begins by calling -the procedure @t{make-@/new-@/machine} to construct the parts of the machine +@ref{Chapter 3}. To build this model, @code{make-@/machine} begins by calling +the procedure @code{make-@/new-@/machine} to construct the parts of the machine model that are common to all register machines. This basic machine model -constructed by @t{make-@/new-@/machine} is essentially a container for some +constructed by @code{make-@/new-@/machine} is essentially a container for some registers and a stack, together with an execution mechanism that processes the controller instructions one by one. -@t{Make-machine} then extends this basic model (by sending it messages) to +@code{Make-machine} then extends this basic model (by sending it messages) to include the registers, operations, and controller of the particular machine being defined. First it allocates a register in the new machine for each of the supplied register names and installs the designated operations in the machine. Then it uses an @newterm{assembler} (described below in @ref{5.2.2}) to transform the controller list into instructions for the new machine and installs these as the machine's instruction sequence. -@t{Make-machine} returns as its value the modified machine model. +@code{Make-machine} returns as its value the modified machine model. @lisp (define (make-machine register-names @@ -31691,7 +31691,7 @@ machine and installs these as the machine's instruction sequence. @subsubheading Registers We will represent a register as a procedure with local state, as in -@ref{Chapter 3}. The procedure @t{make-register} creates a register that +@ref{Chapter 3}. The procedure @code{make-register} creates a register that holds a value that can be accessed or changed: @lisp @@ -31722,10 +31722,10 @@ The following procedures are used to access registers: @subsubheading The stack We can also represent a stack as a procedure with local state. The procedure -@t{make-stack} creates a stack whose local state consists of a list of the -items on the stack. A stack accepts requests to @t{push} an item onto the -stack, to @t{pop} the top item off the stack and return it, and to -@t{initialize} the stack to empty. +@code{make-stack} creates a stack whose local state consists of a list of the +items on the stack. A stack accepts requests to @code{push} an item onto the +stack, to @code{pop} the top item off the stack and return it, and to +@code{initialize} the stack to empty. @lisp (define (make-stack) @@ -31763,37 +31763,37 @@ The following procedures are used to access stacks: @subsubheading The basic machine -The @t{make-new-machine} procedure, shown in @ref{Figure 5.13,,@w{Fig. 5.13}}, +The @code{make-new-machine} procedure, shown in @ref{Figure 5.13,,@w{Fig. 5.13}}, constructs an object whose local state consists of a stack, an initially empty instruction sequence, a list of operations that initially contains an operation to initialize the stack, and a @newterm{register table} that initially contains -two registers, named @t{flag} and @t{pc} (for ``program counter''). The -internal procedure @t{allocate-@/register} adds new entries to the register -table, and the internal procedure @t{lookup-@/register} looks up registers in +two registers, named @code{flag} and @code{pc} (for ``program counter''). The +internal procedure @code{allocate-@/register} adds new entries to the register +table, and the internal procedure @code{lookup-@/register} looks up registers in the table. -The @t{flag} register is used to control branching in the simulated machine. -@t{Test} instructions set the contents of @t{flag} to the result of the -test (true or false). @t{Branch} instructions decide whether or not to -branch by examining the contents of @t{flag}. +The @code{flag} register is used to control branching in the simulated machine. +@code{Test} instructions set the contents of @code{flag} to the result of the +test (true or false). @code{Branch} instructions decide whether or not to +branch by examining the contents of @code{flag}. -The @t{pc} register determines the sequencing of instructions as the machine -runs. This sequencing is implemented by the internal procedure @t{execute}. +The @code{pc} register determines the sequencing of instructions as the machine +runs. This sequencing is implemented by the internal procedure @code{execute}. In the simulation model, each machine instruction is a data structure that includes a procedure of no arguments, called the @newterm{instruction execution procedure}, such that calling this procedure simulates executing the -instruction. As the simulation runs, @t{pc} points to the place in the +instruction. As the simulation runs, @code{pc} points to the place in the instruction sequence beginning with the next instruction to be executed. -@t{Execute} gets that instruction, executes it by calling the instruction +@code{Execute} gets that instruction, executes it by calling the instruction execution procedure, and repeats this cycle until there are no more -instructions to execute (i.e., until @t{pc} points to the end of the +instructions to execute (i.e., until @code{pc} points to the end of the instruction sequence). @sp 0.3 @c @quotation @noindent -@strong{@anchor{Figure 5.13}Figure 5.13:} @math{\downarrow} The @t{make-new-machine} +@strong{@anchor{Figure 5.13}Figure 5.13:} @math{\downarrow} The @code{make-new-machine} procedure, which implements the basic machine model. @lisp @@ -31871,20 +31871,20 @@ procedure, which implements the basic machine model. @noindent As part of its operation, each instruction execution procedure modifies -@t{pc} to indicate the next instruction to be executed. @t{Branch} and -@t{goto} instructions change @t{pc} to point to the new destination. All -other instructions simply advance @t{pc}, making it point to the next -instruction in the sequence. Observe that each call to @t{execute} calls -@t{execute} again, but this does not produce an infinite loop because -running the instruction execution procedure changes the contents of @t{pc}. - -@t{Make-new-machine} returns a @t{dispatch} procedure that implements +@code{pc} to indicate the next instruction to be executed. @code{Branch} and +@code{goto} instructions change @code{pc} to point to the new destination. All +other instructions simply advance @code{pc}, making it point to the next +instruction in the sequence. Observe that each call to @code{execute} calls +@code{execute} again, but this does not produce an infinite loop because +running the instruction execution procedure changes the contents of @code{pc}. + +@code{Make-new-machine} returns a @code{dispatch} procedure that implements message-passing access to the internal state. Notice that starting the machine -is accomplished by setting @t{pc} to the beginning of the instruction -sequence and calling @t{execute}. +is accomplished by setting @code{pc} to the beginning of the instruction +sequence and calling @code{execute}. For convenience, we provide an alternate procedural interface to a machine's -@t{start} operation, as well as procedures to set and examine register +@code{start} operation, as well as procedures to set and examine register contents, as specified at the beginning of @ref{5.2}: @lisp @@ -31939,13 +31939,13 @@ constructs both a list of instructions and a table that associates each label with a pointer into that list. Then the assembler augments the instruction list by inserting the execution procedure for each instruction. -The @t{assemble} procedure is the main entry to the assembler. It takes the +The @code{assemble} procedure is the main entry to the assembler. It takes the controller text and the machine model as arguments and returns the instruction -sequence to be stored in the model. @t{Assemble} calls -@t{extract-@/labels} to build the initial instruction list and label table +sequence to be stored in the model. @code{Assemble} calls +@code{extract-@/labels} to build the initial instruction list and label table from the supplied controller text. The second argument to -@t{extract-@/labels} is a procedure to be called to process these results: -This procedure uses @t{update-@/insts!} to generate the instruction execution +@code{extract-@/labels} is a procedure to be called to process these results: +This procedure uses @code{update-@/insts!} to generate the instruction execution procedures and insert them into the instruction list, and returns the modified list. @@ -31958,12 +31958,12 @@ list. @end lisp @noindent -@t{Extract-labels} takes as arguments a list @t{text} (the sequence of -controller instruction expressions) and a @t{receive} procedure. -@t{Receive} will be called with two values: (1) a list @t{insts} of -instruction data structures, each containing an instruction from @t{text}; -and (2) a table called @t{labels}, which associates each label from -@t{text} with the position in the list @t{insts} that the label +@code{Extract-labels} takes as arguments a list @code{text} (the sequence of +controller instruction expressions) and a @code{receive} procedure. +@code{Receive} will be called with two values: (1) a list @code{insts} of +instruction data structures, each containing an instruction from @code{text}; +and (2) a table called @code{labels}, which associates each label from +@code{text} with the position in the list @code{insts} that the label designates. @lisp @@ -31990,13 +31990,13 @@ designates. @end lisp @noindent -@t{Extract-labels} works by sequentially scanning the elements of the -@t{text} and accumulating the @t{insts} and the @t{labels}. If an +@code{Extract-labels} works by sequentially scanning the elements of the +@code{text} and accumulating the @code{insts} and the @code{labels}. If an element is a symbol (and thus a label) an appropriate entry is added to the -@t{labels} table. Otherwise the element is accumulated onto the -@t{insts} list.@footnote{Using the @t{receive} procedure here is a way to -get @t{extract-labels} to effectively return two values---@t{labels} and -@t{insts}---without explicitly making a compound data structure to hold +@code{labels} table. Otherwise the element is accumulated onto the +@code{insts} list.@footnote{Using the @code{receive} procedure here is a way to +get @code{extract-labels} to effectively return two values---@code{labels} and +@code{insts}---without explicitly making a compound data structure to hold them. An alternative implementation, which returns an explicit pair of values, is @@ -32024,7 +32024,7 @@ is @end lisp @noindent -which would be called by @t{assemble} as follows: +which would be called by @code{assemble} as follows: @lisp (define (assemble controller-text machine) @@ -32036,14 +32036,14 @@ which would be called by @t{assemble} as follows: insts))) @end lisp -You can consider our use of @t{receive} as demonstrating an elegant way to +You can consider our use of @code{receive} as demonstrating an elegant way to return multiple values, or simply an excuse to show off a programming trick. -An argument like @t{receive} that is the next procedure to be invoked is +An argument like @code{receive} that is the next procedure to be invoked is called a ``continuation.'' Recall that we also used continuations to implement -the backtracking control structure in the @t{amb} evaluator in +the backtracking control structure in the @code{amb} evaluator in @ref{4.3.3}.} -@t{Update-insts!} modifies the instruction list, which initially contains +@code{Update-insts!} modifies the instruction list, which initially contains only the text of the instructions, to include the corresponding execution procedures: @@ -32071,8 +32071,8 @@ procedures: @noindent The machine instruction data structure simply pairs the instruction text with the corresponding execution procedure. The execution procedure is not yet -available when @t{extract-labels} constructs the instruction, and is -inserted later by @t{update-insts!}. +available when @code{extract-labels} constructs the instruction, and is +inserted later by @code{update-insts!}. @lisp (define (make-instruction text) @@ -32111,7 +32111,7 @@ Entries will be looked up in the table with @quotation @strong{@anchor{Exercise 5.8}Exercise 5.8:} The following register-machine code -is ambiguous, because the label @t{here} is defined more than once: +is ambiguous, because the label @code{here} is defined more than once: @lisp start @@ -32125,8 +32125,8 @@ here there @end lisp -With the simulator as written, what will the contents of register @t{a} be -when control reaches @t{there}? Modify the @t{extract-labels} procedure +With the simulator as written, what will the contents of register @code{a} be +when control reaches @code{there}? Modify the @code{extract-labels} procedure so that the assembler will signal an error if the same label name is used to indicate two different locations. @end quotation @@ -32134,8 +32134,8 @@ indicate two different locations. @node 5.2.3, 5.2.4, 5.2.2, 5.2 @subsection Generating Execution Procedures for Instructions -The assembler calls @t{make-execution-procedure} to generate the execution -procedure for an instruction. Like the @t{analyze} procedure in the +The assembler calls @code{make-execution-procedure} to generate the execution +procedure for an instruction. Like the @code{analyze} procedure in the evaluator of @ref{4.1.7}, this dispatches on the type of instruction to generate the appropriate execution procedure. @@ -32174,9 +32174,9 @@ detailed syntax of register-machine expressions from the general execution mechanism, as we did for evaluators in @ref{4.1.2}, by using syntax procedures to extract and classify the parts of an instruction. -@subsubheading @t{Assign} instructions +@subsubheading @code{Assign} instructions -The @t{make-assign} procedure handles @t{assign} instructions: +The @code{make-assign} procedure handles @code{assign} instructions: @lisp (define (make-assign @@ -32198,15 +32198,15 @@ The @t{make-assign} procedure handles @t{assign} instructions: machine labels)))) (lambda () @r{; execution procedure} - @r{; for @t{assign}} + @r{; for @code{assign}} (set-contents! target (value-proc)) (advance-pc pc))))) @end lisp @noindent -@t{Make-assign} extracts the target register name (the second element of the +@code{Make-assign} extracts the target register name (the second element of the instruction) and the value expression (the rest of the list that forms the -instruction) from the @t{assign} instruction using the selectors +instruction) from the @code{assign} instruction using the selectors @lisp (define (assign-reg-name assign-instruction) @@ -32216,12 +32216,12 @@ instruction) from the @t{assign} instruction using the selectors @end lisp @noindent -The register name is looked up with @t{get-register} to produce the target -register object. The value expression is passed to @t{make-operation-exp} -if the value is the result of an operation, and to @t{make-primitive-exp} +The register name is looked up with @code{get-register} to produce the target +register object. The value expression is passed to @code{make-operation-exp} +if the value is the result of an operation, and to @code{make-primitive-exp} otherwise. These procedures (shown below) parse the value expression and produce an execution procedure for the value. This is a procedure of no -arguments, called @t{value-proc}, which will be evaluated during the +arguments, called @code{value-proc}, which will be evaluated during the simulation to produce the actual value to be assigned to the register. Notice that the work of looking up the register name and parsing the value expression is performed just once, at assembly time, not every time the instruction is @@ -32229,11 +32229,11 @@ simulated. This saving of work is the reason we use execution procedures, and corresponds directly to the saving in work we obtained by separating program analysis from execution in the evaluator of @ref{4.1.7}. -The result returned by @t{make-assign} is the execution procedure for the -@t{assign} instruction. When this procedure is called (by the machine -model's @t{execute} procedure), it sets the contents of the target register -to the result obtained by executing @t{value-proc}. Then it advances the -@t{pc} to the next instruction by running the procedure +The result returned by @code{make-assign} is the execution procedure for the +@code{assign} instruction. When this procedure is called (by the machine +model's @code{execute} procedure), it sets the contents of the target register +to the result obtained by executing @code{value-proc}. Then it advances the +@code{pc} to the next instruction by running the procedure @lisp (define (advance-pc pc) @@ -32241,16 +32241,16 @@ to the result obtained by executing @t{value-proc}. Then it advances the @end lisp @noindent -@t{Advance-pc} is the normal termination for all instructions except -@t{branch} and @t{goto}. +@code{Advance-pc} is the normal termination for all instructions except +@code{branch} and @code{goto}. -@subsubheading @t{Test}, @t{branch}, and @t{goto} instructions +@subsubheading @code{Test}, @code{branch}, and @code{goto} instructions -@t{Make-test} handles @t{test} instructions in a similar way. It +@code{Make-test} handles @code{test} instructions in a similar way. It extracts the expression that specifies the condition to be tested and generates an execution procedure for it. At simulation time, the procedure for the -condition is called, the result is assigned to the @t{flag} register, and -the @t{pc} is advanced: +condition is called, the result is assigned to the @code{flag} register, and +the @code{pc} is advanced: @lisp (define @@ -32275,13 +32275,13 @@ the @t{pc} is advanced: @end lisp @noindent -The execution procedure for a @t{branch} instruction checks the contents of -the @t{flag} register and either sets the contents of the @t{pc} to the -branch destination (if the branch is taken) or else just advances the @t{pc} +The execution procedure for a @code{branch} instruction checks the contents of +the @code{flag} register and either sets the contents of the @code{pc} to the +branch destination (if the branch is taken) or else just advances the @code{pc} (if the branch is not taken). Notice that the indicated destination in a -@t{branch} instruction must be a label, and the @t{make-branch} procedure +@code{branch} instruction must be a label, and the @code{make-branch} procedure enforces this. Notice also that the label is looked up at assembly time, not -each time the @t{branch} instruction is simulated. +each time the @code{branch} instruction is simulated. @lisp (define @@ -32305,9 +32305,9 @@ each time the @t{branch} instruction is simulated. @end lisp @noindent -A @t{goto} instruction is similar to a branch, except that the destination +A @code{goto} instruction is similar to a branch, except that the destination may be specified either as a label or as a register, and there is no condition -to check---the @t{pc} is always set to the new destination. +to check---the @code{pc} is always set to the new destination. @lisp (define (make-goto inst machine labels pc) @@ -32337,8 +32337,8 @@ to check---the @t{pc} is always set to the new destination. @subsubheading Other instructions -The stack instructions @t{save} and @t{restore} simply use the stack with -the designated register and advance the @t{pc}: +The stack instructions @code{save} and @code{restore} simply use the stack with +the designated register and advance the @code{pc}: @lisp (define (make-save inst machine stack pc) @@ -32361,9 +32361,9 @@ the designated register and advance the @t{pc}: @end lisp @noindent -The final instruction type, handled by @t{make-perform}, generates an +The final instruction type, handled by @code{make-perform}, generates an execution procedure for the action to be performed. At simulation time, the -action procedure is executed and the @t{pc} advanced. +action procedure is executed and the @code{pc} advanced. @lisp (define (make-perform @@ -32387,9 +32387,9 @@ action procedure is executed and the @t{pc} advanced. @subsubheading Execution procedures for subexpressions -The value of a @t{reg}, @t{label}, or @t{const} expression may be -needed for assignment to a register (@t{make-assign}) or for input to an -operation (@t{make-operation-exp}, below). The following procedure +The value of a @code{reg}, @code{label}, or @code{const} expression may be +needed for assignment to a register (@code{make-assign}) or for input to an +operation (@code{make-operation-exp}, below). The following procedure generates execution procedures to produce values for these expressions during the simulation: @@ -32415,7 +32415,7 @@ the simulation: @end lisp @noindent -The syntax of @t{reg}, @t{label}, and @t{const} expressions is +The syntax of @code{reg}, @code{label}, and @code{const} expressions is determined by @lisp @@ -32433,9 +32433,9 @@ determined by @end lisp @noindent -@t{Assign}, @t{perform}, and @t{test} instructions may include the -application of a machine operation (specified by an @t{op} expression) to -some operands (specified by @t{reg} and @t{const} expressions). The +@code{Assign}, @code{perform}, and @code{test} instructions may include the +application of a machine operation (specified by an @code{op} expression) to +some operands (specified by @code{reg} and @code{const} expressions). The following procedure produces an execution procedure for an ``operation expression''---a list containing the operation and operand expressions from the instruction: @@ -32470,7 +32470,7 @@ The syntax of operation expressions is determined by @noindent Observe that the treatment of operation expressions is very much like the -treatment of procedure applications by the @t{analyze-application} procedure +treatment of procedure applications by the @code{analyze-application} procedure in the evaluator of @ref{4.1.7} in that we generate an execution procedure for each operand. At simulation time, we call the operand procedures and apply the Scheme procedure that simulates the operation to the resulting @@ -32501,8 +32501,8 @@ except the syntax procedures in this section? @end quotation @quotation -@strong{@anchor{Exercise 5.11}Exercise 5.11:} When we introduced @t{save} -and @t{restore} in @ref{5.1.4}, we didn't specify what would happen +@strong{@anchor{Exercise 5.11}Exercise 5.11:} When we introduced @code{save} +and @code{restore} in @ref{5.1.4}, we didn't specify what would happen if you tried to restore a register that was not the last one saved, as in the sequence @@ -32512,27 +32512,27 @@ sequence (restore y) @end lisp -There are several reasonable possibilities for the meaning of @t{restore}: +There are several reasonable possibilities for the meaning of @code{restore}: @enumerate a @item -@t{(restore y)} puts into @t{y} the last value saved on the stack, +@code{(restore y)} puts into @code{y} the last value saved on the stack, regardless of what register that value came from. This is the way our simulator behaves. Show how to take advantage of this behavior to eliminate one instruction from the Fibonacci machine of @ref{5.1.4} (@ref{Figure 5.12}). @item -@t{(restore y)} puts into @t{y} the last value saved on the stack, but -only if that value was saved from @t{y}; otherwise, it signals an error. -Modify the simulator to behave this way. You will have to change @t{save} +@code{(restore y)} puts into @code{y} the last value saved on the stack, but +only if that value was saved from @code{y}; otherwise, it signals an error. +Modify the simulator to behave this way. You will have to change @code{save} to put the register name on the stack along with the value. @item -@t{(restore y)} puts into @t{y} the last value saved from @t{y} -regardless of what other registers were saved after @t{y} and not restored. +@code{(restore y)} puts into @code{y} the last value saved from @code{y} +regardless of what other registers were saved after @code{y} and not restored. Modify the simulator to behave this way. You will have to associate a separate -stack with each register. You should make the @t{initialize-stack} +stack with each register. You should make the @code{initialize-stack} operation initialize all the register stacks. @end enumerate @@ -32548,20 +32548,20 @@ machine model: @item a list of all instructions, with duplicates removed, sorted by instruction type -(@t{assign}, @t{goto}, and so on); +(@code{assign}, @code{goto}, and so on); @item a list (without duplicates) of the registers used to hold entry points (these -are the registers referenced by @t{goto} instructions); +are the registers referenced by @code{goto} instructions); @item -a list (without duplicates) of the registers that are @t{save}d -or @t{restore}d; +a list (without duplicates) of the registers that are @code{save}d +or @code{restore}d; @item for each register, a list (without duplicates) of the sources from which it is -assigned (for example, the sources for register @t{val} in the factorial -machine of @ref{Figure 5.11} are @t{(const 1)} and @t{((op *) (reg n) +assigned (for example, the sources for register @code{val} in the factorial +machine of @ref{Figure 5.11} are @code{(const 1)} and @code{((op *) (reg n) (reg val))}). @end itemize @@ -32574,8 +32574,8 @@ new information. To test your analyzer, define the Fibonacci machine from @quotation @strong{@anchor{Exercise 5.13}Exercise 5.13:} Modify the simulator so that it uses the controller sequence to determine what registers the machine has rather -than requiring a list of registers as an argument to @t{make-machine}. -Instead of pre-allocating the registers in @t{make-machine}, you can +than requiring a list of registers as an argument to @code{make-machine}. +Instead of pre-allocating the registers in @code{make-machine}, you can allocate them one at a time when they are first seen during assembly of the instructions. @end quotation @@ -32591,7 +32591,7 @@ stack to keep track of the number of times registers are saved on the stack and the maximum depth reached by the stack, and add a message to the stack's interface that prints the statistics, as shown below. We also add an operation to the basic machine model to print the stack statistics, by initializing -@t{the-ops} in @t{make-new-machine} to +@code{the-ops} in @code{make-new-machine} to @lisp (list (list 'initialize-stack @@ -32603,7 +32603,7 @@ to the basic machine model to print the stack statistics, by initializing @end lisp @noindent -Here is the new version of @t{make-stack}: +Here is the new version of @code{make-stack}: @lisp (define (make-stack) @@ -32670,8 +32670,8 @@ the factorial machine with instructions to initialize the stack and print the statistics. You may want to also modify the machine so that it repeatedly reads a value for @math{n}, computes the factorial, and prints the result (as we did for the @acronym{GCD} machine in @ref{Figure 5.4}), so that you will not -have to repeatedly invoke @t{get-@/register-@/contents}, -@t{set-@/register-@/contents!}, and @t{start}. +have to repeatedly invoke @code{get-@/register-@/contents}, +@code{set-@/register-@/contents!}, and @code{start}. @end quotation @quotation @@ -32686,7 +32686,7 @@ count and resets the count to zero. @strong{@anchor{Exercise 5.16}Exercise 5.16:} Augment the simulator to provide for @newterm{instruction tracing}. That is, before each instruction is executed, the simulator should print the text of the instruction. Make the -machine model accept @t{trace-on} and @t{trace-off} messages to turn +machine model accept @code{trace-on} and @code{trace-off} messages to turn tracing on and off. @end quotation @@ -32700,7 +32700,7 @@ simulator retain the necessary label information. @end quotation @quotation -@strong{@anchor{Exercise 5.18}Exercise 5.18:} Modify the @t{make-register} +@strong{@anchor{Exercise 5.18}Exercise 5.18:} Modify the @code{make-register} procedure of @ref{5.2.1} so that registers can be traced. Registers should accept messages that turn tracing on and off. When a register is traced, assigning a value to the register should print the name of the @@ -32730,11 +32730,11 @@ label. For example, @end lisp @noindent -installs a breakpoint in @t{gcd-machine} just before the assignment to -register @t{a}. When the simulator reaches the breakpoint it should print +installs a breakpoint in @code{gcd-machine} just before the assignment to +register @code{a}. When the simulator reaches the breakpoint it should print the label and the offset of the breakpoint and stop executing instructions. -Alyssa can then use @t{get-@/register-@/contents} and -@t{set-@/register-@/contents!} to manipulate the state of the simulated machine. +Alyssa can then use @code{get-@/register-@/contents} and +@code{set-@/register-@/contents!} to manipulate the state of the simulated machine. She should then be able to continue execution by saying @lisp @@ -32813,26 +32813,26 @@ individual elements can be accessed by means of an integer index in an amount of time that is independent of the index.@footnote{We could represent memory as lists of items. However, the access time would then not be independent of the index, since accessing the @math{n^{\hbox{\fordrm th}}} element of a list requires @math{n - 1} -@t{cdr} operations.} In order to describe memory operations, we use two +@code{cdr} operations.} In order to describe memory operations, we use two primitive Scheme procedures for manipulating vectors: @itemize @bullet @item -@t{(vector-ref <@var{vector}> <@var{n}>)} returns the @math{n^{\hbox{\ordrm th}}} +@code{(vector-ref <@var{vector}> <@var{n}>)} returns the @math{n^{\hbox{\ordrm th}}} element of the vector. @item -@t{(vector-set! <@var{vector}> <@var{n}> <@var{value}>)} +@code{(vector-set! <@var{vector}> <@var{n}> <@var{value}>)} sets the @math{n^{\hbox{\ordrm th}}} element of the vector to the designated value. @end itemize @noindent -For example, if @t{v} is a vector, then @t{(vector-ref v 5)} gets the -fifth entry in the vector @t{v} and @t{(vector-set! v 5 7)} changes the -value of the fifth entry of the vector @t{v} to 7.@footnote{For -completeness, we should specify a @t{make-vector} operation that constructs +For example, if @code{v} is a vector, then @code{(vector-ref v 5)} gets the +fifth entry in the vector @code{v} and @code{(vector-set! v 5 7)} changes the +value of the fifth entry of the vector @code{v} to 7.@footnote{For +completeness, we should specify a @code{make-vector} operation that constructs vectors. However, in the present application we will use vectors only to model fixed divisions of the computer memory.} For computer memory, this access can be implemented through the use of address arithmetic to combine a @newterm{base @@ -32844,10 +32844,10 @@ vector. We can use vectors to implement the basic pair structures required for a list-structured memory. Let us imagine that computer memory is divided into -two vectors: @t{the-cars} and @t{the-cdrs}. We will represent list +two vectors: @code{the-cars} and @code{the-cdrs}. We will represent list structure as follows: A pointer to a pair is an index into the two vectors. -The @t{car} of the pair is the entry in @t{the-cars} with the designated -index, and the @t{cdr} of the pair is the entry in @t{the-cdrs} with the +The @code{car} of the pair is the entry in @code{the-cars} with the designated +index, and the @code{cdr} of the pair is the entry in @code{the-cdrs} with the designated index. We also need a representation for objects other than pairs (such as numbers and symbols) and a way to distinguish one kind of data from another. There are many methods of accomplishing this, but they all reduce to @@ -32860,7 +32860,7 @@ enables the system to distinguish a pointer to a pair (which consists of the ``pair'' data type and an index into the memory vectors) from pointers to other kinds of data (which consist of some other data type and whatever is being used to represent data of that type). Two data objects are considered to be the -same (@t{eq?}) if their pointers are identical.@footnote{Type information +same (@code{eq?}) if their pointers are identical.@footnote{Type information may be encoded in a variety of ways, depending on the details of the machine on which the Lisp system is to be implemented. The execution efficiency of Lisp programs will be strongly dependent on how cleverly this choice is made, but it @@ -32873,21 +32873,21 @@ indices be? How efficiently can the primitive machine instructions be used to manipulate the type fields of pointers? Machines that include special hardware for the efficient handling of type fields are said to have @newterm{tagged architectures}.} @ref{Figure 5.14} illustrates the use of this method to -represent the list @t{((1 2) 3 4)}, whose box-and-pointer diagram is also +represent the list @code{((1 2) 3 4)}, whose box-and-pointer diagram is also shown. We use letter prefixes to denote the data-type information. Thus, a -pointer to the pair with index 5 is denoted @t{p5}, the empty list is -denoted by the pointer @t{e0}, and a pointer to the number 4 is denoted -@t{n4}. In the box-and-pointer diagram, we have indicated at the lower left -of each pair the vector index that specifies where the @t{car} and -@t{cdr} of the pair are stored. The blank locations in @t{the-cars} and -@t{the-cdrs} may contain parts of other list structures (not of interest +pointer to the pair with index 5 is denoted @code{p5}, the empty list is +denoted by the pointer @code{e0}, and a pointer to the number 4 is denoted +@code{n4}. In the box-and-pointer diagram, we have indicated at the lower left +of each pair the vector index that specifies where the @code{car} and +@code{cdr} of the pair are stored. The blank locations in @code{the-cars} and +@code{the-cdrs} may contain parts of other list structures (not of interest here). @float @c @quotation @anchor{Figure 5.14} @ifinfo -@strong{Figure 5.14:} Box-and-pointer and memory-vector representations of the list @t{((1 2) 3 4)}. +@strong{Figure 5.14:} Box-and-pointer and memory-vector representations of the list @code{((1 2) 3 4)}. @example +---+---+ +---+---+ +---+---+ @@ -32917,7 +32917,7 @@ the-cdrs | | p2 | p4 | | e0 | p7 | | e0 | | ... @center @image{fig/chap5/Fig5.14b,137mm,,,.pdf} @sp 0.7 @quotation -@strong{Figure 5.14:} Box-and-pointer and memory-vector representations of the list @t{((1 2) 3 4)}. +@strong{Figure 5.14:} Box-and-pointer and memory-vector representations of the list @code{((1 2) 3 4)}. @end quotation @sp 0.0 @end iftex @@ -32925,10 +32925,10 @@ the-cdrs | | p2 | p4 | | e0 | p7 | | e0 | | ... @end float @noindent -A pointer to a number, such as @t{n4}, might consist of a type indicating +A pointer to a number, such as @code{n4}, might consist of a type indicating numeric data together with the actual representation of the number 4.@footnote{This decision on the representation of numbers determines whether -@t{eq?}, which tests equality of pointers, can be used to test for equality +@code{eq?}, which tests equality of pointers, can be used to test for equality of numbers. If the pointer contains the number itself, then equal numbers will have the same pointer. But if the pointer contains the index of a location where the number is stored, equal numbers will be guaranteed to have equal @@ -32944,7 +32944,7 @@ A symbol might be represented as a typed pointer that designates a sequence of the characters that form the symbol's printed representation. This sequence is constructed by the Lisp reader when the character string is initially encountered in input. Since we want two instances of a symbol to be recognized -as the ``same'' symbol by @t{eq?} and we want @t{eq?} to be a simple test +as the ``same'' symbol by @code{eq?} and we want @code{eq?} to be a simple test for equality of pointers, we must ensure that if the reader sees the same character string twice, it will use the same pointer (to the same sequence of characters) to represent both occurrences. To accomplish this, the reader @@ -32961,8 +32961,8 @@ character strings by unique pointers is called @newterm{interning} symbols. Given the above representation scheme, we can replace each ``primitive'' list operation of a register machine with one or more primitive vector operations. -We will use two registers, @t{the-cars} and @t{the-cdrs}, to identify the -memory vectors, and will assume that @t{vector-ref} and @t{vector-set!} +We will use two registers, @code{the-cars} and @code{the-cdrs}, to identify the +memory vectors, and will assume that @code{vector-ref} and @code{vector-set!} are available as primitive operations. We also assume that numeric operations on pointers (such as incrementing a pointer, using a pair pointer to index a vector, or adding two numbers) use only the index portion of the typed pointer. @@ -33011,9 +33011,9 @@ are implemented as @end lisp @noindent -@t{Cons} is performed by allocating an unused index and storing the -arguments to @t{cons} in @t{the-cars} and @t{the-cdrs} at that indexed -vector position. We presume that there is a special register, @t{free}, +@code{Cons} is performed by allocating an unused index and storing the +arguments to @code{cons} in @code{the-cars} and @code{the-cdrs} at that indexed +vector position. We presume that there is a special register, @code{free}, that always holds a pair pointer containing the next available index, and that we can increment the index part of that pointer to find the next free location.@footnote{There are other ways of finding free storage. For example, @@ -33031,10 +33031,10 @@ pointer) because we are using a compacting garbage collector, as we will see in @noindent is implemented as the following sequence of vector operations:@footnote{This is -essentially the implementation of @t{cons} in terms of @t{set-car!} and -@t{set-cdr!}, as described in @ref{3.3.1}. The operation -@t{get-new-pair} used in that implementation is realized here by the -@t{free} pointer.} +essentially the implementation of @code{cons} in terms of @code{set-car!} and +@code{set-cdr!}, as described in @ref{3.3.1}. The operation +@code{get-new-pair} used in that implementation is realized here by the +@code{free} pointer.} @lisp (perform (op vector-set!) @@ -33050,7 +33050,7 @@ essentially the implementation of @t{cons} in terms of @t{set-car!} and @end lisp @noindent -The @t{eq?} operation +The @code{eq?} operation @lisp (op eq?) (reg @math{\langle}@math{reg_1}@math{\rangle}) (reg @math{\langle}@math{reg_2}@math{\rangle}) @@ -33058,14 +33058,14 @@ The @t{eq?} operation @noindent simply tests the equality of all fields in the registers, and predicates such -as @t{pair?}, @t{null?}, @t{symbol?}, and @t{number?} need only +as @code{pair?}, @code{null?}, @code{symbol?}, and @code{number?} need only check the type field. @subsubheading Implementing stacks Although our register machines use stacks, we need do nothing special here, since stacks can be modeled in terms of lists. The stack can be a list of the -saved values, pointed to by a special register @t{the-stack}. Thus, @t{ +saved values, pointed to by a special register @code{the-stack}. Thus, @code{ (save <@var{reg}>)} can be implemented as @lisp @@ -33076,7 +33076,7 @@ saved values, pointed to by a special register @t{the-stack}. Thus, @t{ @end lisp @noindent -Similarly, @t{(restore <@var{reg}>)} can be implemented as +Similarly, @code{(restore <@var{reg}>)} can be implemented as @lisp (assign @math{\langle}@var{reg}@math{\rangle} (op car) (reg the-stack)) @@ -33084,7 +33084,7 @@ Similarly, @t{(restore <@var{reg}>)} can be implemented as @end lisp @noindent -and @t{(perform (op initialize-stack))} can be implemented as +and @code{(perform (op initialize-stack))} can be implemented as @lisp (assign the-stack (const ())) @@ -33108,8 +33108,8 @@ of the list structure produced by @end lisp @noindent -with the @t{free} pointer initially @t{p1}. What is the final value of -@t{free} ? What pointers represent the values of @t{x} and @t{y} ? +with the @code{free} pointer initially @code{p1}. What is the final value of +@code{free} ? What pointers represent the values of @code{x} and @code{y} ? @end quotation @quotation @@ -33120,7 +33120,7 @@ available as machine primitives. @enumerate a @item -Recursive @t{count-leaves}: +Recursive @code{count-leaves}: @lisp (define (count-leaves tree) @@ -33132,7 +33132,7 @@ Recursive @t{count-leaves}: @end lisp @item -Recursive @t{count-leaves} with explicit counter: +Recursive @code{count-leaves} with explicit counter: @lisp (define (count-leaves tree) @@ -33151,8 +33151,8 @@ Recursive @t{count-leaves} with explicit counter: @quotation @strong{@anchor{Exercise 5.22}Exercise 5.22:} @ref{Exercise 3.12} of -@ref{3.3.1} presented an @t{append} procedure that appends two lists to form -a new list and an @t{append!} procedure that splices two lists together. +@ref{3.3.1} presented an @code{append} procedure that appends two lists to form +a new list and an @code{append!} procedure that splices two lists together. Design a register machine to implement each of these procedures. Assume that the list-structure memory operations are available as primitive operations. @end quotation @@ -33166,7 +33166,7 @@ memory. With a real computer we will eventually run out of free space in which to construct new pairs.@footnote{This may not be true eventually, because memories may get large enough so that it would be impossible to run out of free memory in the lifetime of the computer. For example, there are about -@math{3\cdot10^{\hbox{\fordrm 13}}} microseconds in a year, so if we were to @t{cons} once per +@math{3\cdot10^{\hbox{\fordrm 13}}} microseconds in a year, so if we were to @code{cons} once per microsecond we would need about @math{10^{\hbox{\fordrm 15}}} cells of memory to build a machine that could operate for 30 years without running out of memory. That much memory seems absurdly large by today's standards, but it is not physically impossible. @@ -33198,7 +33198,7 @@ the future of the computation). The method we shall examine for accomplishing this is known as @newterm{garbage collection}. Garbage collection is based on the observation that, at any moment in a Lisp interpretation, the only objects that can affect the future of the computation are those that can be reached by -some succession of @t{car} and @t{cdr} operations starting from the +some succession of @code{car} and @code{cdr} operations starting from the pointers that are currently in the machine registers.@footnote{We assume here that the stack is represented as a list as described in @ref{5.3.1}, so that items on the stack are accessible via the pointer in the stack register.} @@ -33206,11 +33206,11 @@ Any memory cell that is not so accessible may be recycled. There are many ways to perform garbage collection. The method we shall examine here is called @newterm{stop-and-copy}. The basic idea is to divide memory -into two halves: ``working memory'' and ``free memory.'' When @t{cons} +into two halves: ``working memory'' and ``free memory.'' When @code{cons} constructs pairs, it allocates these in working memory. When working memory is full, we perform garbage collection by locating all the useful pairs in working memory and copying these into consecutive locations in free memory. (The -useful pairs are located by tracing all the @t{car} and @t{cdr} pointers, +useful pairs are located by tracing all the @code{car} and @code{cdr} pointers, starting with the machine registers.) Since we do not copy the garbage, there will presumably be additional free memory that we can use to allocate new pairs. In addition, nothing in the working memory is needed, since all the @@ -33250,28 +33250,28 @@ operations.} We now use our register-machine language to describe the stop-and-copy algorithm in more detail. We will assume that there is a register called -@t{root} that contains a pointer to a structure that eventually points at +@code{root} that contains a pointer to a structure that eventually points at all accessible data. This can be arranged by storing the contents of all the -machine registers in a pre-allocated list pointed at by @t{root} just before +machine registers in a pre-allocated list pointed at by @code{root} just before starting garbage collection.@footnote{This list of registers does not include -the registers used by the storage-allocation system---@t{root}, -@t{the-cars}, @t{the-cdrs}, and the other registers that will be +the registers used by the storage-allocation system---@code{root}, +@code{the-cars}, @code{the-cdrs}, and the other registers that will be introduced in this section.} We also assume that, in addition to the current working memory, there is free memory available into which we can copy the useful data. The current working memory consists of vectors whose base -addresses are in registers called @t{the-cars} and @t{the-cdrs}, and the -free memory is in registers called @t{new-cars} and @t{new-cdrs}. +addresses are in registers called @code{the-cars} and @code{the-cdrs}, and the +free memory is in registers called @code{new-cars} and @code{new-cdrs}. Garbage collection is triggered when we exhaust the free cells in the current -working memory, that is, when a @t{cons} operation attempts to increment the -@t{free} pointer beyond the end of the memory vector. When the -garbage-collection process is complete, the @t{root} pointer will point into -the new memory, all objects accessible from the @t{root} will have been -moved to the new memory, and the @t{free} pointer will indicate the next +working memory, that is, when a @code{cons} operation attempts to increment the +@code{free} pointer beyond the end of the memory vector. When the +garbage-collection process is complete, the @code{root} pointer will point into +the new memory, all objects accessible from the @code{root} will have been +moved to the new memory, and the @code{free} pointer will indicate the next place in the new memory where a new pair can be allocated. In addition, the roles of working memory and new memory will have been interchanged---new pairs will be constructed in the new memory, beginning at the place indicated by -@t{free}, and the (previous) working memory will be available as the new +@code{free}, and the (previous) working memory will be available as the new memory for the next garbage collection. @ref{Figure 5.15} shows the arrangement of memory just before and just after garbage collection. @@ -33331,50 +33331,50 @@ the-cdrs | | | memory @noindent The state of the garbage-collection process is controlled by maintaining two -pointers: @t{free} and @t{scan}. These are initialized to point to the +pointers: @code{free} and @code{scan}. These are initialized to point to the beginning of the new memory. The algorithm begins by relocating the pair -pointed at by @t{root} to the beginning of the new memory. The pair is -copied, the @t{root} pointer is adjusted to point to the new location, and -the @t{free} pointer is incremented. In addition, the old location of the +pointed at by @code{root} to the beginning of the new memory. The pair is +copied, the @code{root} pointer is adjusted to point to the new location, and +the @code{free} pointer is incremented. In addition, the old location of the pair is marked to show that its contents have been moved. This marking is done -as follows: In the @t{car} position, we place a special tag that signals +as follows: In the @code{car} position, we place a special tag that signals that this is an already-moved object. (Such an object is traditionally called a @newterm{broken heart}.)@footnote{The term @emph{broken heart} was coined by David Cressey, who wrote a garbage collector for MDL, a dialect of Lisp -developed at @acronym{MIT} during the early 1970s.} In the @t{cdr} position +developed at @acronym{MIT} during the early 1970s.} In the @code{cdr} position we place a @newterm{forwarding address} that points at the location to which the object has been moved. After relocating the root, the garbage collector enters its basic cycle. At -each step in the algorithm, the @t{scan} pointer (initially pointing at the +each step in the algorithm, the @code{scan} pointer (initially pointing at the relocated root) points at a pair that has been moved to the new memory but -whose @t{car} and @t{cdr} pointers still refer to objects in the old -memory. These objects are each relocated, and the @t{scan} pointer is +whose @code{car} and @code{cdr} pointers still refer to objects in the old +memory. These objects are each relocated, and the @code{scan} pointer is incremented. To relocate an object (for example, the object indicated by the -@t{car} pointer of the pair we are scanning) we check to see if the object +@code{car} pointer of the pair we are scanning) we check to see if the object has already been moved (as indicated by the presence of a broken-heart tag in -the @t{car} position of the object). If the object has not already been -moved, we copy it to the place indicated by @t{free}, update @t{free}, +the @code{car} position of the object). If the object has not already been +moved, we copy it to the place indicated by @code{free}, update @code{free}, set up a broken heart at the object's old location, and update the pointer to -the object (in this example, the @t{car} pointer of the pair we are +the object (in this example, the @code{car} pointer of the pair we are scanning) to point to the new location. If the object has already been moved, -its forwarding address (found in the @t{cdr} position of the broken heart) +its forwarding address (found in the @code{cdr} position of the broken heart) is substituted for the pointer in the pair being scanned. Eventually, all accessible objects will have been moved and scanned, at which point the -@t{scan} pointer will overtake the @t{free} pointer and the process will +@code{scan} pointer will overtake the @code{free} pointer and the process will terminate. We can specify the stop-and-copy algorithm as a sequence of instructions for a register machine. The basic step of relocating an object is accomplished by a -subroutine called @t{relocate-old-result-in-new}. This subroutine gets its +subroutine called @code{relocate-old-result-in-new}. This subroutine gets its argument, a pointer to the object to be relocated, from a register named -@t{old}. It relocates the designated object (incrementing @t{free} in +@code{old}. It relocates the designated object (incrementing @code{free} in the process), puts a pointer to the relocated object into a register called -@t{new}, and returns by branching to the entry point stored in the register -@t{relocate-continue}. To begin garbage collection, we invoke this -subroutine to relocate the @t{root} pointer, after initializing @t{free} -and @t{scan}. When the relocation of @t{root} has been accomplished, we -install the new pointer as the new @t{root} and enter the main loop of the +@code{new}, and returns by branching to the entry point stored in the register +@code{relocate-continue}. To begin garbage collection, we invoke this +subroutine to relocate the @code{root} pointer, after initializing @code{free} +and @code{scan}. When the relocation of @code{root} has been accomplished, we +install the new pointer as the new @code{root} and enter the main loop of the garbage collector. @lisp @@ -33392,14 +33392,14 @@ reassign-root @noindent In the main loop of the garbage collector we must determine whether there are -any more objects to be scanned. We do this by testing whether the @t{scan} -pointer is coincident with the @t{free} pointer. If the pointers are equal, +any more objects to be scanned. We do this by testing whether the @code{scan} +pointer is coincident with the @code{free} pointer. If the pointers are equal, then all accessible objects have been relocated, and we branch to -@t{gc-flip}, which cleans things up so that we can continue the interrupted +@code{gc-flip}, which cleans things up so that we can continue the interrupted computation. If there are still pairs to be scanned, we call the relocate -subroutine to relocate the @t{car} of the next pair (by placing the -@t{car} pointer in @t{old}). The @t{relocate-continue} register is -set up so that the subroutine will return to update the @t{car} pointer. +subroutine to relocate the @code{car} of the next pair (by placing the +@code{car} pointer in @code{old}). The @code{relocate-continue} register is +set up so that the subroutine will return to update the @code{car} pointer. @lisp gc-loop @@ -33415,10 +33415,10 @@ gc-loop @end lisp @noindent -At @t{update-car}, we modify the @t{car} pointer of the pair being -scanned, then proceed to relocate the @t{cdr} of the pair. We return to -@t{update-cdr} when that relocation has been accomplished. After relocating -and updating the @t{cdr}, we are finished scanning that pair, so we continue +At @code{update-car}, we modify the @code{car} pointer of the pair being +scanned, then proceed to relocate the @code{cdr} of the pair. We return to +@code{update-cdr} when that relocation has been accomplished. After relocating +and updating the @code{cdr}, we are finished scanning that pair, so we continue with the main loop. @lisp @@ -33444,29 +33444,29 @@ update-cdr @end lisp @noindent -The subroutine @t{relocate-old-result-in-new} relocates objects as follows: -If the object to be relocated (pointed at by @t{old}) is not a pair, then we -return the same pointer to the object unchanged (in @t{new}). (For example, -we may be scanning a pair whose @t{car} is the number 4. If we represent -the @t{car} by @t{n4}, as described in @ref{5.3.1}, then we want -the ``relocated'' @t{car} pointer to still be @t{n4}.) Otherwise, we -must perform the relocation. If the @t{car} position of the pair to be +The subroutine @code{relocate-old-result-in-new} relocates objects as follows: +If the object to be relocated (pointed at by @code{old}) is not a pair, then we +return the same pointer to the object unchanged (in @code{new}). (For example, +we may be scanning a pair whose @code{car} is the number 4. If we represent +the @code{car} by @code{n4}, as described in @ref{5.3.1}, then we want +the ``relocated'' @code{car} pointer to still be @code{n4}.) Otherwise, we +must perform the relocation. If the @code{car} position of the pair to be relocated contains a broken-heart tag, then the pair has in fact already been -moved, so we retrieve the forwarding address (from the @t{cdr} position of -the broken heart) and return this in @t{new}. If the pointer in @t{old} +moved, so we retrieve the forwarding address (from the @code{cdr} position of +the broken heart) and return this in @code{new}. If the pointer in @code{old} points at a yet-unmoved pair, then we move the pair to the first free cell in -new memory (pointed at by @t{free}) and set up the broken heart by storing a +new memory (pointed at by @code{free}) and set up the broken heart by storing a broken-heart tag and forwarding address at the old location. -@t{Relocate-old-result-in-new} uses a register @t{oldcr} to hold the -@t{car} or the @t{cdr} of the object pointed at by -@t{old}.@footnote{The garbage collector uses the low-level predicate -@t{pointer-to-pair?} instead of the list-structure @t{pair?} operation +@code{Relocate-old-result-in-new} uses a register @code{oldcr} to hold the +@code{car} or the @code{cdr} of the object pointed at by +@code{old}.@footnote{The garbage collector uses the low-level predicate +@code{pointer-to-pair?} instead of the list-structure @code{pair?} operation because in a real system there might be various things that are treated as pairs for garbage-collection purposes. For example, in a Scheme system that conforms to the @acronym{IEEE} standard a procedure object may be implemented -as a special kind of ``pair'' that doesn't satisfy the @t{pair?} predicate. -For simulation purposes, @t{pointer-to-pair?} can be implemented as -@t{pair?}.} +as a special kind of ``pair'' that doesn't satisfy the @code{pair?} predicate. +For simulation purposes, @code{pointer-to-pair?} can be implemented as +@code{pair?}.} @lisp relocate-old-result-in-new @@ -33482,9 +33482,9 @@ pair (test (op broken-heart?) (reg oldcr)) (branch (label already-moved)) (assign new (reg free)) @r{; new location for pair} - @r{;; Update @t{free} pointer.} + @r{;; Update @code{free} pointer.} (assign free (op +) (reg free) (const 1)) - @r{;; Copy the @t{car} and @t{cdr} to new memory.} + @r{;; Copy the @code{car} and @code{cdr} to new memory.} (perform (op vector-set!) (reg new-cars) (reg new) @@ -33517,8 +33517,8 @@ already-moved @noindent At the very end of the garbage-collection process, we interchange the role of -old and new memories by interchanging pointers: interchanging @t{the-cars} -with @t{new-cars}, and @t{the-cdrs} with @t{new-cdrs}. We will then +old and new memories by interchanging pointers: interchanging @code{the-cars} +with @code{new-cars}, and @code{the-cdrs} with @code{new-cdrs}. We will then be ready to perform another garbage collection the next time memory runs out. @lisp @@ -33538,7 +33538,7 @@ In @ref{5.1} we saw how to transform simple Scheme programs into descriptions of register machines. We will now perform this transformation on a more complex program, the metacircular evaluator of @ref{4.1.1}--@/@ref{4.1.4}, which shows how the behavior of a Scheme interpreter -can be described in terms of the procedures @t{eval} and @t{apply}. The +can be described in terms of the procedures @code{eval} and @code{apply}. The @newterm{explicit-control evaluator} that we develop in this section shows how the underlying procedure-@/calling and argument-@/passing mechanisms used in the evaluation process can be described in terms of operations on registers and @@ -33583,8 +33583,8 @@ on the chip and the method by which it was designed.} In designing the explicit-control evaluator, we must specify the operations to be used in our register machine. We described the metacircular evaluator in -terms of abstract syntax, using procedures such as @t{quoted?} and -@t{make-procedure}. In implementing the register machine, we could expand +terms of abstract syntax, using procedures such as @code{quoted?} and +@code{make-procedure}. In implementing the register machine, we could expand these procedures into sequences of elementary list-structure memory operations, and implement these operations on our register machine. However, this would make our evaluator very long, obscuring the basic structure with details. To @@ -33598,15 +33598,15 @@ operations, using the list-structure implementation we described in @ref{5.3}. Our Scheme evaluator register machine includes a stack and seven registers: -@t{exp}, @t{env}, @t{val}, @t{continue}, @t{proc}, @t{argl}, -and @t{unev}. @t{Exp} is used to hold the expression to be evaluated, -and @t{env} contains the environment in which the evaluation is to be -performed. At the end of an evaluation, @t{val} contains the value obtained +@code{exp}, @code{env}, @code{val}, @code{continue}, @code{proc}, @code{argl}, +and @code{unev}. @code{Exp} is used to hold the expression to be evaluated, +and @code{env} contains the environment in which the evaluation is to be +performed. At the end of an evaluation, @code{val} contains the value obtained by evaluating the expression in the designated environment. The -@t{continue} register is used to implement recursion, as explained in +@code{continue} register is used to implement recursion, as explained in @ref{5.1.4}. (The evaluator needs to call itself recursively, since evaluating an expression requires evaluating its subexpressions.) The -registers @t{proc}, @t{argl}, and @t{unev} are used in evaluating +registers @code{proc}, @code{argl}, and @code{unev} are used in evaluating combinations. We will not provide a data-path diagram to show how the registers and @@ -33625,20 +33625,20 @@ will be presented in detail. @subsection The Core of the Explicit-Control Evaluator The central element in the evaluator is the sequence of instructions beginning -at @t{eval-dispatch}. This corresponds to the @t{eval} procedure of the +at @code{eval-dispatch}. This corresponds to the @code{eval} procedure of the metacircular evaluator described in @ref{4.1.1}. When the controller -starts at @t{eval-dispatch}, it evaluates the expression specified by -@t{exp} in the environment specified by @t{env}. When evaluation is -complete, the controller will go to the entry point stored in @t{continue}, -and the @t{val} register will hold the value of the expression. As with the -metacircular @t{eval}, the structure of @t{eval-dispatch} is a case +starts at @code{eval-dispatch}, it evaluates the expression specified by +@code{exp} in the environment specified by @code{env}. When evaluation is +complete, the controller will go to the entry point stored in @code{continue}, +and the @code{val} register will hold the value of the expression. As with the +metacircular @code{eval}, the structure of @code{eval-dispatch} is a case analysis on the syntactic type of the expression to be evaluated.@footnote{In -our controller, the dispatch is written as a sequence of @t{test} and -@t{branch} instructions. Alternatively, it could have been written in a +our controller, the dispatch is written as a sequence of @code{test} and +@code{branch} instructions. Alternatively, it could have been written in a data-directed style (and in a real system it probably would have been) to avoid the need to perform sequential tests and to facilitate the definition of new expression types. A machine designed to run Lisp would probably include a -@t{dispatch-on-type} instruction that would efficiently execute such +@code{dispatch-on-type} instruction that would efficiently execute such data-directed dispatches.} @lisp @@ -33667,9 +33667,9 @@ eval-dispatch @subsubheading Evaluating simple expressions Numbers and strings (which are self-evaluating), variables, quotations, and -@t{lambda} expressions have no subexpressions to be evaluated. For these, -the evaluator simply places the correct value in the @t{val} register and -continues execution at the entry point specified by @t{continue}. +@code{lambda} expressions have no subexpressions to be evaluated. For these, +the evaluator simply places the correct value in the @code{val} register and +continues execution at the entry point specified by @code{continue}. Evaluation of simple expressions is performed by the following controller code: @lisp @@ -33703,27 +33703,27 @@ ev-lambda @end lisp @noindent -Observe how @t{ev-lambda} uses the @t{unev} and @t{exp} registers to +Observe how @code{ev-lambda} uses the @code{unev} and @code{exp} registers to hold the parameters and body of the lambda expression so that they can be -passed to the @t{make-procedure} operation, along with the environment in -@t{env}. +passed to the @code{make-procedure} operation, along with the environment in +@code{env}. @subsubheading Evaluating procedure applications A procedure application is specified by a combination containing an operator and operands. The operator is a subexpression whose value is a procedure, and the operands are subexpressions whose values are the arguments to which the -procedure should be applied. The metacircular @t{eval} handles applications +procedure should be applied. The metacircular @code{eval} handles applications by calling itself recursively to evaluate each element of the combination, and -then passing the results to @t{apply}, which performs the actual procedure +then passing the results to @code{apply}, which performs the actual procedure application. The explicit-control evaluator does the same thing; these -recursive calls are implemented by @t{goto} instructions, together with use +recursive calls are implemented by @code{goto} instructions, together with use of the stack to save registers that will be restored after the recursive call returns. Before each call we will be careful to identify which registers must be saved (because their values will be needed later).@footnote{This is an important but subtle point in translating algorithms from a procedural language, such as Lisp, to a register-machine language. As an alternative to -saving only what is needed, we could save all the registers (except @t{val}) +saving only what is needed, we could save all the registers (except @code{val}) before each recursive call. This is called a @newterm{framed-stack} discipline. This would work but might save more registers than necessary; this could be an important consideration in a system where stack operations are expensive. @@ -33733,14 +33733,14 @@ reused.} We begin the evaluation of an application by evaluating the operator to produce a procedure, which will later be applied to the evaluated operands. To -evaluate the operator, we move it to the @t{exp} register and go to -@t{eval-dispatch}. The environment in the @t{env} register is already -the correct one in which to evaluate the operator. However, we save @t{env} +evaluate the operator, we move it to the @code{exp} register and go to +@code{eval-dispatch}. The environment in the @code{env} register is already +the correct one in which to evaluate the operator. However, we save @code{env} because we will need it later to evaluate the operands. We also extract the -operands into @t{unev} and save this on the stack. We set up -@t{continue} so that @t{eval-dispatch} will resume at -@t{ev-appl-did-operator} after the operator has been evaluated. First, -however, we save the old value of @t{continue}, which tells the controller +operands into @code{unev} and save this on the stack. We set up +@code{continue} so that @code{eval-dispatch} will resume at +@code{ev-appl-did-operator} after the operator has been evaluated. First, +however, we save the old value of @code{continue}, which tells the controller where to continue after the application. @lisp @@ -33758,11 +33758,11 @@ ev-application @noindent Upon returning from evaluating the operator subexpression, we proceed to evaluate the operands of the combination and to accumulate the resulting -arguments in a list, held in @t{argl}. First we restore the unevaluated -operands and the environment. We initialize @t{argl} to an empty list. -Then we assign to the @t{proc} register the procedure that was produced by +arguments in a list, held in @code{argl}. First we restore the unevaluated +operands and the environment. We initialize @code{argl} to an empty list. +Then we assign to the @code{proc} register the procedure that was produced by evaluating the operator. If there are no operands, we go directly to -@t{apply-dispatch}. Otherwise we save @t{proc} on the stack and start +@code{apply-dispatch}. Otherwise we save @code{proc} on the stack and start the argument-evaluation loop:@footnote{We add to the evaluator data-structure procedures in @ref{4.1.3} the following two procedures for manipulating argument lists: @@ -33795,14 +33795,14 @@ ev-appl-did-operator @noindent Each cycle of the argument-evaluation loop evaluates an operand from the list -in @t{unev} and accumulates the result into @t{argl}. To evaluate an -operand, we place it in the @t{exp} register and go to @t{eval-dispatch}, -after setting @t{continue} so that execution will resume with the +in @code{unev} and accumulates the result into @code{argl}. To evaluate an +operand, we place it in the @code{exp} register and go to @code{eval-dispatch}, +after setting @code{continue} so that execution will resume with the argument-accumulation phase. But first we save the arguments accumulated so -far (held in @t{argl}), the environment (held in @t{env}), and the -remaining operands to be evaluated (held in @t{unev}). A special case is +far (held in @code{argl}), the environment (held in @code{env}), and the +remaining operands to be evaluated (held in @code{unev}). A special case is made for the evaluation of the last operand, which is handled at -@t{ev-appl-last-arg}. +@code{ev-appl-last-arg}. @lisp ev-appl-operand-loop @@ -33821,8 +33821,8 @@ ev-appl-operand-loop @noindent When an operand has been evaluated, the value is accumulated into the list held -in @t{argl}. The operand is then removed from the list of unevaluated -operands in @t{unev}, and the argument-evaluation continues. +in @code{argl}. The operand is then removed from the list of unevaluated +operands in @code{unev}, and the argument-evaluation continues. @lisp ev-appl-accumulate-arg @@ -33842,17 +33842,17 @@ ev-appl-accumulate-arg @noindent Evaluation of the last argument is handled differently. There is no need to save the environment or the list of unevaluated operands before going to -@t{eval-dispatch}, since they will not be required after the last operand is +@code{eval-dispatch}, since they will not be required after the last operand is evaluated. Thus, we return from the evaluation to a special entry point -@t{ev-appl-accum-last-arg}, which restores the argument list, accumulates +@code{ev-appl-accum-last-arg}, which restores the argument list, accumulates the new argument, restores the saved procedure, and goes off to perform the application.@footnote{The optimization of treating the last operand specially is known as @newterm{evlis tail recursion} (see @ref{Wand 1980}). We could be somewhat more efficient in the argument evaluation loop if we made evaluation of the first operand a special case too. This would permit us to postpone -initializing @t{argl} until after evaluating the first operand, so as to -avoid saving @t{argl} in this case. The compiler in @ref{5.5} -performs this optimization. (Compare the @t{construct-arglist} procedure of +initializing @code{argl} until after evaluating the first operand, so as to +avoid saving @code{argl} in this case. The compiler in @ref{5.5} +performs this optimization. (Compare the @code{construct-arglist} procedure of @ref{5.5.3}.)} @lisp @@ -33877,26 +33877,26 @@ right to left---see @ref{Exercise 3.8}). This order is not determined by the metacircular evaluator, which inherits its control structure from the underlying Scheme in which it is implemented.@footnote{The order of operand evaluation in the metacircular evaluator is determined by the order of -evaluation of the arguments to @t{cons} in the procedure -@t{list-of-values} of @ref{4.1.1} (see @ref{Exercise 4.1}).} Because -the @t{first-operand} selector (used in @t{ev-appl-operand-loop} to -extract successive operands from @t{unev}) is implemented as @t{car} and -the @t{rest-operands} selector is implemented as @t{cdr}, the +evaluation of the arguments to @code{cons} in the procedure +@code{list-of-values} of @ref{4.1.1} (see @ref{Exercise 4.1}).} Because +the @code{first-operand} selector (used in @code{ev-appl-operand-loop} to +extract successive operands from @code{unev}) is implemented as @code{car} and +the @code{rest-operands} selector is implemented as @code{cdr}, the explicit-control evaluator will evaluate the operands of a combination in left-to-right order. @subsubheading Procedure application -The entry point @t{apply-dispatch} corresponds to the @t{apply} procedure -of the metacircular evaluator. By the time we get to @t{apply-dispatch}, -the @t{proc} register contains the procedure to apply and @t{argl} +The entry point @code{apply-dispatch} corresponds to the @code{apply} procedure +of the metacircular evaluator. By the time we get to @code{apply-dispatch}, +the @code{proc} register contains the procedure to apply and @code{argl} contains the list of evaluated arguments to which it must be applied. The -saved value of @t{continue} (originally passed to @t{eval-dispatch} and -saved at @t{ev-application}), which tells where to return with the result of +saved value of @code{continue} (originally passed to @code{eval-dispatch} and +saved at @code{ev-application}), which tells where to return with the result of the procedure application, is on the stack. When the application is complete, the controller transfers to the entry point specified by the saved -@t{continue}, with the result of the application in @t{val}. As with the -metacircular @t{apply}, there are two cases to consider. Either the +@code{continue}, with the result of the application in @code{val}. As with the +metacircular @code{apply}, there are two cases to consider. Either the procedure to be applied is a primitive or it is a compound procedure. @lisp @@ -33911,19 +33911,19 @@ apply-dispatch @noindent We assume that each primitive is implemented so as to obtain its arguments from -@t{argl} and place its result in @t{val}. To specify how the machine +@code{argl} and place its result in @code{val}. To specify how the machine handles primitives, we would have to provide a sequence of controller -instructions to implement each primitive and arrange for @t{primitive-apply} +instructions to implement each primitive and arrange for @code{primitive-apply} to dispatch to the instructions for the primitive identified by the contents of -@t{proc}. Since we are interested in the structure of the evaluation +@code{proc}. Since we are interested in the structure of the evaluation process rather than the details of the primitives, we will instead just use an -@t{apply-primitive-procedure} operation that applies the procedure in -@t{proc} to the arguments in @t{argl}. For the purpose of simulating the +@code{apply-primitive-procedure} operation that applies the procedure in +@code{proc} to the arguments in @code{argl}. For the purpose of simulating the evaluator with the simulator of @ref{5.2} we use the procedure -@t{apply-primitive-procedure}, which calls on the underlying Scheme system +@code{apply-primitive-procedure}, which calls on the underlying Scheme system to perform the application, just as we did for the metacircular evaluator in @ref{4.1.4}. After computing the value of the primitive application, -we restore @t{continue} and go to the designated entry point. +we restore @code{continue} and go to the designated entry point. @lisp primitive-apply @@ -33939,7 +33939,7 @@ To apply a compound procedure, we proceed just as with the metacircular evaluator. We construct a frame that binds the procedure's parameters to the arguments, use this frame to extend the environment carried by the procedure, and evaluate in this extended environment the sequence of expressions that -forms the body of the procedure. @t{Ev-sequence}, described below in +forms the body of the procedure. @code{Ev-sequence}, described below in @ref{5.4.2}, handles the evaluation of the sequence. @lisp @@ -33962,7 +33962,7 @@ compound-apply @end lisp @noindent -@t{Compound-apply} is the only place in the interpreter where the @t{env} +@code{Compound-apply} is the only place in the interpreter where the @code{env} register is ever assigned a new value. Just as in the metacircular evaluator, the new environment is constructed from the environment carried by the procedure, together with the argument list and the corresponding list of @@ -33971,14 +33971,14 @@ variables to be bound. @node 5.4.2, 5.4.3, 5.4.1, 5.4 @subsection Sequence Evaluation and Tail Recursion -The portion of the explicit-control evaluator at @t{ev-@/sequence} is -analogous to the metacircular evaluator's @t{eval-@/sequence} procedure. It +The portion of the explicit-control evaluator at @code{ev-@/sequence} is +analogous to the metacircular evaluator's @code{eval-@/sequence} procedure. It handles sequences of expressions in procedure bodies or in explicit -@t{begin} expressions. +@code{begin} expressions. -Explicit @t{begin} expressions are evaluated by placing the sequence of -expressions to be evaluated in @t{unev}, saving @t{continue} on the -stack, and jumping to @t{ev-sequence}. +Explicit @code{begin} expressions are evaluated by placing the sequence of +expressions to be evaluated in @code{unev}, saving @code{continue} on the +stack, and jumping to @code{ev-sequence}. @lisp ev-begin @@ -33991,30 +33991,30 @@ ev-begin @noindent The implicit sequences in procedure bodies are handled by jumping to -@t{ev-sequence} from @t{compound-apply}, at which point @t{continue} -is already on the stack, having been saved at @t{ev-application}. +@code{ev-sequence} from @code{compound-apply}, at which point @code{continue} +is already on the stack, having been saved at @code{ev-application}. -The entries at @t{ev-sequence} and @t{ev-sequence-continue} form a loop +The entries at @code{ev-sequence} and @code{ev-sequence-continue} form a loop that successively evaluates each expression in a sequence. The list of -unevaluated expressions is kept in @t{unev}. Before evaluating each +unevaluated expressions is kept in @code{unev}. Before evaluating each expression, we check to see if there are additional expressions to be evaluated in the sequence. If so, we save the rest of the unevaluated expressions (held -in @t{unev}) and the environment in which these must be evaluated (held in -@t{env}) and call @t{eval-dispatch} to evaluate the expression. The two +in @code{unev}) and the environment in which these must be evaluated (held in +@code{env}) and call @code{eval-dispatch} to evaluate the expression. The two saved registers are restored upon the return from this evaluation, at -@t{ev-sequence-continue}. +@code{ev-sequence-continue}. The final expression in the sequence is handled differently, at the entry point -@t{ev-sequence-last-exp}. Since there are no more expressions to be -evaluated after this one, we need not save @t{unev} or @t{env} before -going to @t{eval-dispatch}. The value of the whole sequence is the value of +@code{ev-sequence-last-exp}. Since there are no more expressions to be +evaluated after this one, we need not save @code{unev} or @code{env} before +going to @code{eval-dispatch}. The value of the whole sequence is the value of the last expression, so after the evaluation of the last expression there is nothing left to do except continue at the entry point currently held on the -stack (which was saved by @t{ev-application} or @t{ev-begin}.) Rather -than setting up @t{continue} to arrange for @t{eval-dispatch} to return -here and then restoring @t{continue} from the stack and continuing at that -entry point, we restore @t{continue} from the stack before going to -@t{eval-dispatch}, so that @t{eval-dispatch} will continue at that entry +stack (which was saved by @code{ev-application} or @code{ev-begin}.) Rather +than setting up @code{continue} to arrange for @code{eval-dispatch} to return +here and then restoring @code{continue} from the stack and continuing at that +entry point, we restore @code{continue} from the stack before going to +@code{eval-dispatch}, so that @code{eval-dispatch} will continue at that entry point after evaluating the expression. @lisp @@ -34054,11 +34054,11 @@ In @ref{Chapter 1} we said that the process described by a procedure such as @noindent is an iterative process. Even though the procedure is syntactically recursive (defined in terms of itself), it is not logically necessary for an evaluator to -save information in passing from one call to @t{sqrt-iter} to the +save information in passing from one call to @code{sqrt-iter} to the next.@footnote{We saw in @ref{5.1} how to implement such a process with a register machine that had no stack; the state of the process was stored in a fixed set of registers.} An evaluator that can execute a procedure such as -@t{sqrt-iter} without requiring increasing storage as the procedure +@code{sqrt-iter} without requiring increasing storage as the procedure continues to call itself is called a @newterm{tail-recursive} evaluator. The metacircular implementation of the evaluator in @ref{Chapter 4} does not specify whether the evaluator is tail-recursive, because that evaluator @@ -34068,26 +34068,26 @@ process to see when procedure calls cause a net accumulation of information on the stack. Our evaluator is tail-recursive, because in order to evaluate the final -expression of a sequence we transfer directly to @t{eval-dispatch} without +expression of a sequence we transfer directly to @code{eval-dispatch} without saving any information on the stack. Hence, evaluating the final expression in -a sequence---even if it is a procedure call (as in @t{sqrt-iter}, where the -@t{if} expression, which is the last expression in the procedure body, -reduces to a call to @t{sqrt-iter})---will not cause any information to be +a sequence---even if it is a procedure call (as in @code{sqrt-iter}, where the +@code{if} expression, which is the last expression in the procedure body, +reduces to a call to @code{sqrt-iter})---will not cause any information to be accumulated on the stack.@footnote{This implementation of tail recursion in -@t{ev-sequence} is one variety of a well-known optimization technique used +@code{ev-sequence} is one variety of a well-known optimization technique used by many compilers. In compiling a procedure that ends with a procedure call, one can replace the call by a jump to the called procedure's entry point. Building this strategy into the interpreter, as we have done in this section, provides the optimization uniformly throughout the language.} If we did not think to take advantage of the fact that it was unnecessary to -save information in this case, we might have implemented @t{eval-sequence} +save information in this case, we might have implemented @code{eval-sequence} by treating all the expressions in a sequence in the same way---saving the registers, evaluating the expression, returning to restore the registers, and repeating this until all the expressions have been evaluated:@footnote{We can -define @t{no-more-exps?} as follows: +define @code{no-more-exps?} as follows: -@math{\kern1.2ex}@t{(define (no-more-exps? seq) (null? seq))}} +@math{\kern1.2ex}@code{(define (no-more-exps? seq) (null? seq))}} @lisp ev-sequence @@ -34117,7 +34117,7 @@ will still give the same value for any expression. But this change is fatal to the tail-recursive implementation, because we must now return after evaluating the final expression in a sequence in order to undo the (useless) register saves. These extra saves will accumulate during a nest of procedure calls. -Consequently, processes such as @t{sqrt-iter} will require space +Consequently, processes such as @code{sqrt-iter} will require space proportional to the number of iterations rather than requiring constant space. This difference can be significant. For example, with tail recursion, an infinite loop can be expressed using only the procedure-call mechanism: @@ -34138,16 +34138,16 @@ other than procedure call. @subsection Conditionals, Assignments, and Definitions As with the metacircular evaluator, special forms are handled by selectively -evaluating fragments of the expression. For an @t{if} expression, we must +evaluating fragments of the expression. For an @code{if} expression, we must evaluate the predicate and decide, based on the value of predicate, whether to evaluate the consequent or the alternative. -Before evaluating the predicate, we save the @t{if} expression itself so +Before evaluating the predicate, we save the @code{if} expression itself so that we can later extract the consequent or alternative. We also save the environment, which we will need later in order to evaluate the consequent or -the alternative, and we save @t{continue}, which we will need later in order +the alternative, and we save @code{continue}, which we will need later in order to return to the evaluation of the expression that is waiting for the value of -the @t{if}. +the @code{if}. @lisp ev-if @@ -34163,10 +34163,10 @@ ev-if @noindent When we return from evaluating the predicate, we test whether it was true or false and, depending on the result, place either the consequent or the -alternative in @t{exp} before going to @t{eval-dispatch}. Notice that -restoring @t{env} and @t{continue} here sets up @t{eval-dispatch} to +alternative in @code{exp} before going to @code{eval-dispatch}. Notice that +restoring @code{env} and @code{continue} here sets up @code{eval-dispatch} to have the correct environment and to continue at the right place to receive the -value of the @t{if} expression. +value of the @code{if} expression. @lisp ev-if-decide @@ -34185,10 +34185,10 @@ ev-if-consequent @subsubheading Assignments and definitions -Assignments are handled by @t{ev-assignment}, which is reached from -@t{eval-dispatch} with the assignment expression in @t{exp}. The code at -@t{ev-assignment} first evaluates the value part of the expression and then -installs the new value in the environment. @t{Set-variable-value!} is +Assignments are handled by @code{ev-assignment}, which is reached from +@code{eval-dispatch} with the assignment expression in @code{exp}. The code at +@code{ev-assignment} first evaluates the value part of the expression and then +installs the new value in the environment. @code{Set-variable-value!} is assumed to be available as a machine operation. @lisp @@ -34250,20 +34250,20 @@ ev-definition-1 @quotation @strong{@anchor{Exercise 5.23}Exercise 5.23:} Extend the evaluator to handle -derived expressions such as @t{cond}, @t{let}, and so on +derived expressions such as @code{cond}, @code{let}, and so on (@ref{4.1.2}). You may ``cheat'' and assume that the syntax transformers such -as @t{cond->if} are available as machine operations.@footnote{This isn't +as @code{cond->if} are available as machine operations.@footnote{This isn't really cheating. In an actual implementation built from scratch, we would use our explicit-control evaluator to interpret a Scheme program that performs -source-level transformations like @t{cond->if} in a syntax phase that runs +source-level transformations like @code{cond->if} in a syntax phase that runs before execution.} @end quotation @quotation -@strong{@anchor{Exercise 5.24}Exercise 5.24:} Implement @t{cond} as a new -basic special form without reducing it to @t{if}. You will have to -construct a loop that tests the predicates of successive @t{cond} clauses -until you find one that is true, and then use @t{ev-sequence} to evaluate +@strong{@anchor{Exercise 5.24}Exercise 5.24:} Implement @code{cond} as a new +basic special form without reducing it to @code{if}. You will have to +construct a loop that tests the predicates of successive @code{cond} clauses +until you find one that is true, and then use @code{ev-sequence} to evaluate the actions of the clause. @end quotation @@ -34290,24 +34290,24 @@ precise treatment of evaluation. To understand the behavior of the explicit-control evaluator, we can simulate it and monitor its performance. We will install a driver loop in our evaluator machine. This plays the role of -the @t{driver-loop} procedure of @ref{4.1.4}. The evaluator will +the @code{driver-loop} procedure of @ref{4.1.4}. The evaluator will repeatedly print a prompt, read an expression, evaluate the expression by going -to @t{eval-dispatch}, and print the result. The following instructions form +to @code{eval-dispatch}, and print the result. The following instructions form the beginning of the explicit-control evaluator's controller -sequence:@footnote{We assume here that @t{read} and the various printing +sequence:@footnote{We assume here that @code{read} and the various printing operations are available as primitive machine operations, which is useful for our simulation, but completely unrealistic in practice. These are actually extremely complex operations. In practice, they would be implemented using low-level input-output operations such as transferring single characters to and from a device. -To support the @t{get-global-environment} operation we define +To support the @code{get-global-environment} operation we define -@math{\kern1.2ex}@t{(define the-global-environment (setup-environment))} +@math{\kern1.2ex}@code{(define the-global-environment (setup-environment))} -@math{\kern1.2ex}@t{(define (get-global-environment)} +@math{\kern1.2ex}@code{(define (get-global-environment)} -@math{\kern3.5ex}@t{the-global-environment)}} +@math{\kern3.5ex}@code{the-global-environment)}} @lisp read-eval-print-loop @@ -34327,7 +34327,7 @@ print-result @noindent When we encounter an error in a procedure (such as the ``unknown procedure type -error'' indicated at @t{apply-dispatch}), we print an error message and +error'' indicated at @code{apply-dispatch}), we print an error message and return to the driver loop.@footnote{There are other errors that we would like the interpreter to handle, but these are not so simple. See @ref{Exercise 5.30}.} @@ -34338,7 +34338,7 @@ unknown-expression-type (const unknown-expression-type-error)) (goto (label signal-error)) unknown-procedure-type - @r{; clean up stack (from @t{apply-dispatch}):} + @r{; clean up stack (from @code{apply-dispatch}):} (restore continue) (assign val @@ -34422,7 +34422,7 @@ example, one important factor in performance is how efficiently the evaluator uses the stack. We can observe the number of stack operations required to evaluate various expressions by defining the evaluator register machine with the version of the simulator that collects statistics on stack use -(@ref{5.2.4}), and adding an instruction at the evaluator's @t{print-result} +(@ref{5.2.4}), and adding an instruction at the evaluator's @code{print-result} entry point to print the statistics: @lisp @@ -34459,7 +34459,7 @@ operations used to evaluate the previous expression. @quotation @strong{@anchor{Exercise 5.26}Exercise 5.26:} Use the monitored stack to explore the tail-recursive property of the evaluator (@ref{5.4.2}). -Start the evaluator and define the iterative @t{factorial} procedure from +Start the evaluator and define the iterative @code{factorial} procedure from @ref{1.2.1}: @lisp @@ -34547,10 +34547,10 @@ time required. @quotation @strong{@anchor{Exercise 5.28}Exercise 5.28:} Modify the definition of the -evaluator by changing @t{eval-sequence} as described in @ref{5.4.2} +evaluator by changing @code{eval-sequence} as described in @ref{5.4.2} so that the evaluator is no longer tail-recursive. Rerun your experiments from @ref{Exercise 5.26} and @ref{Exercise 5.27} to demonstrate that both versions -of the @t{factorial} procedure now require space that grows linearly with +of the @code{factorial} procedure now require space that grows linearly with their input. @end quotation @@ -34608,22 +34608,22 @@ Errors that occur in the evaluation process, such as an attempt to access an unbound variable, could be caught by changing the lookup operation to make it return a distinguished condition code, which cannot be a possible value of any user variable. The evaluator can test for this condition code and then do what -is necessary to go to @t{signal-error}. Find all of the places in the +is necessary to go to @code{signal-error}. Find all of the places in the evaluator where such a change is necessary and fix them. This is lots of work. @item Much worse is the problem of handling errors that are signaled by applying primitive procedures, such as an attempt to divide by zero or an attempt to -extract the @t{car} of a symbol. In a professionally written high-quality +extract the @code{car} of a symbol. In a professionally written high-quality system, each primitive application is checked for safety as part of the -primitive. For example, every call to @t{car} could first check that the +primitive. For example, every call to @code{car} could first check that the argument is a pair. If the argument is not a pair, the application would return a distinguished condition code to the evaluator, which would then report the failure. We could arrange for this in our register-machine simulator by making each primitive procedure check for applicability and returning an appropriate distinguished condition code on failure. Then the -@t{primitive-apply} code in the evaluator can check for the condition code -and go to @t{signal-error} if necessary. Build this structure and make it +@code{primitive-apply} code in the evaluator can check for the condition code +and go to @code{signal-error} if necessary. Build this structure and make it work. This is a major project. @end enumerate @@ -34680,8 +34680,8 @@ machine's native language. The compiler that we implement in this section translates programs written in Scheme into sequences of instructions to be executed using the explicit-control evaluator machine's data paths.@footnote{Actually, the machine that runs compiled code can be simpler -than the interpreter machine, because we won't use the @t{exp} and -@t{unev} registers. The interpreter used these to hold pieces of +than the interpreter machine, because we won't use the @code{exp} and +@code{unev} registers. The interpreter used these to hold pieces of unevaluated expressions. With the compiler, however, these expressions get built into the compiled code that the register machine will run. For the same reason, we don't need the machine operations that deal with expression syntax. @@ -34716,10 +34716,10 @@ analyzing expressions will be similar to those used by the interpreter. Moreover, to make it easy to interface compiled and interpreted code, we will design the compiler to generate code that obeys the same conventions of register usage as the interpreter: The environment will be kept in the -@t{env} register, argument lists will be accumulated in @t{argl}, a -procedure to be applied will be in @t{proc}, procedures will return their -answers in @t{val}, and the location to which a procedure should return will -be kept in @t{continue}. In general, the compiler translates a source +@code{env} register, argument lists will be accumulated in @code{argl}, a +procedure to be applied will be in @code{proc}, procedures will return their +answers in @code{val}, and the location to which a procedure should return will +be kept in @code{continue}. In general, the compiler translates a source program into an object program that performs essentially the same register operations as would the interpreter in evaluating the same source program. @@ -34730,14 +34730,14 @@ evaluating the expression, we do not execute the instruction but instead accumulate it into a sequence. The resulting sequence of instructions will be the object code. Observe the efficiency advantage of compilation over interpretation. Each time the interpreter evaluates an expression---for -example, @t{(f 84 96)}---it performs the work of classifying the expression +example, @code{(f 84 96)}---it performs the work of classifying the expression (discovering that this is a procedure application) and testing for the end of the operand list (discovering that there are two operands). With a compiler, the expression is analyzed only once, when the instruction sequence is generated at compile time. The object code produced by the compiler contains only the instructions that evaluate the operator and the two operands, assemble -the argument list, and apply the procedure (in @t{proc}) to the arguments -(in @t{argl}). +the argument list, and apply the procedure (in @code{proc}) to the arguments +(in @code{argl}). This is the same kind of optimization we implemented in the analyzing evaluator of @ref{4.1.7}. But there are further opportunities to gain efficiency @@ -34752,15 +34752,15 @@ arbitrary evaluation. A compiler, on the other hand, can exploit the structure of the particular expression it is processing to generate code that avoids unnecessary stack operations. -As a case in point, consider the combination @t{(f 84 96)}. Before the +As a case in point, consider the combination @code{(f 84 96)}. Before the interpreter evaluates the operator of the combination, it prepares for this evaluation by saving the registers containing the operands and the environment, whose values will be needed later. The interpreter then evaluates the operator -to obtain the result in @t{val}, restores the saved registers, and finally -moves the result from @t{val} to @t{proc}. However, in the particular -expression we are dealing with, the operator is the symbol @t{f}, whose +to obtain the result in @code{val}, restores the saved registers, and finally +moves the result from @code{val} to @code{proc}. However, in the particular +expression we are dealing with, the operator is the symbol @code{f}, whose evaluation is accomplished by the machine operation -@t{lookup-variable-value}, which does not alter any registers. The compiler +@code{lookup-variable-value}, which does not alter any registers. The compiler that we implement in this section will take advantage of this fact and generate code that evaluates the operator using the instruction @@ -34773,17 +34773,17 @@ code that evaluates the operator using the instruction @noindent This code not only avoids the unnecessary saves and restores but also assigns -the value of the lookup directly to @t{proc}, whereas the interpreter would -obtain the result in @t{val} and then move this to @t{proc}. +the value of the lookup directly to @code{proc}, whereas the interpreter would +obtain the result in @code{val} and then move this to @code{proc}. A compiler can also optimize access to the environment. Having analyzed the code, the compiler can in many cases know in which frame a particular variable will be located and access that frame directly, rather than performing the -@t{lookup-variable-value} search. We will discuss how to implement such +@code{lookup-variable-value} search. We will discuss how to implement such variable access in @ref{5.5.6}. Until then, however, we will focus on the kind of register and stack optimizations described above. There are many other optimizations that can be performed by a compiler, such as coding -primitive operations ``in line'' instead of using a general @t{apply} +primitive operations ``in line'' instead of using a general @code{apply} mechanism (see @ref{Exercise 5.38}); but we will not emphasize these here. Our main goal in this section is to illustrate the compilation process in a simplified (but still interesting) context. @@ -34808,9 +34808,9 @@ required operations. In our compiler, we will do essentially the same analysis. Instead of producing execution procedures, however, we will generate sequences of instructions to be run by our register machine. -The procedure @t{compile} is the top-level dispatch in the compiler. It -corresponds to the @t{eval} procedure of @ref{4.1.1}, the -@t{analyze} procedure of @ref{4.1.7}, and the @t{eval-dispatch} +The procedure @code{compile} is the top-level dispatch in the compiler. It +corresponds to the @code{eval} procedure of @ref{4.1.1}, the +@code{analyze} procedure of @ref{4.1.7}, and the @code{eval-dispatch} entry point of the explicit-control-evaluator in @ref{5.4.1}. The compiler, like the interpreters, uses the expression-syntax procedures defined in @ref{4.1.2}.@footnote{Notice, however, that our compiler is a Scheme @@ -34819,7 +34819,7 @@ the actual Scheme procedures used with the metacircular evaluator. For the explicit-control evaluator, in contrast, we assumed that equivalent syntax operations were available as operations for the register machine. (Of course, when we simulated the register machine in Scheme, we used the actual Scheme -procedures in our register machine simulation.)} @t{Compile} performs a +procedures in our register machine simulation.)} @code{Compile} performs a case analysis on the syntactic type of the expression to be compiled. For each type of expression, it dispatches to a specialized @newterm{code generator}: @@ -34860,7 +34860,7 @@ type of expression, it dispatches to a specialized @newterm{code generator}: @subsubheading Targets and linkages -@t{Compile} and the code generators that it calls take two arguments in +@code{Compile} and the code generators that it calls take two arguments in addition to the expression to compile. There is a @newterm{target}, which specifies the register in which the compiled code is to return the value of the expression. There is also a @newterm{linkage descriptor}, which describes how @@ -34872,11 +34872,11 @@ code do one of the following three things: @item continue at the next instruction in sequence (this is specified by the linkage -descriptor @t{next}), +descriptor @code{next}), @item return from the procedure being compiled (this is specified by the linkage -descriptor @t{return}), or +descriptor @code{return}), or @item jump to a named entry point (this is specified by using the designated label as @@ -34885,8 +34885,8 @@ the linkage descriptor). @end itemize @noindent -For example, compiling the expression @t{5} (which is self-evaluating) with -a target of the @t{val} register and a linkage of @t{next} should produce +For example, compiling the expression @code{5} (which is self-evaluating) with +a target of the @code{val} register and a linkage of @code{next} should produce the instruction @lisp @@ -34894,7 +34894,7 @@ the instruction @end lisp @noindent -Compiling the same expression with a linkage of @t{return} should produce +Compiling the same expression with a linkage of @code{return} should produce the instructions @lisp @@ -34905,7 +34905,7 @@ the instructions @noindent In the first case, execution will continue with the next instruction in the sequence. In the second case, we will return from a procedure call. In both -cases, the value of the expression will be placed into the target @t{val} +cases, the value of the expression will be placed into the target @code{val} register. @subsubheading Instruction sequences and stack usage @@ -34917,7 +34917,7 @@ generators for component expressions, just as evaluation of a compound expression is accomplished by evaluating the component expressions. The simplest method for combining instruction sequences is a procedure called -@t{append-@/instruction-@/sequences}. It takes as arguments any number of +@code{append-@/instruction-@/sequences}. It takes as arguments any number of instruction sequences that are to be executed sequentially; it appends them and returns the combined sequence. That is, if @math{\langle}@math{seq_1}@math{\rangle} and @math{\langle}@math{seq_2}@math{\rangle} are sequences of instructions, then evaluating @@ -34936,18 +34936,18 @@ produces the sequence @noindent Whenever registers might need to be saved, the compiler's code generators use -@t{preserving}, which is a more subtle method for combining instruction -sequences. @t{Preserving} takes three arguments: a set of registers and two +@code{preserving}, which is a more subtle method for combining instruction +sequences. @code{Preserving} takes three arguments: a set of registers and two instruction sequences that are to be executed sequentially. It appends the sequences in such a way that the contents of each register in the set is preserved over the execution of the first sequence, if this is needed for the execution of the second sequence. That is, if the first sequence modifies the register and the second sequence actually needs the register's original -contents, then @t{preserving} wraps a @t{save} and a @t{restore} of +contents, then @code{preserving} wraps a @code{save} and a @code{restore} of the register around the first sequence before appending the sequences. -Otherwise, @t{preserving} simply returns the appended instruction sequences. +Otherwise, @code{preserving} simply returns the appended instruction sequences. Thus, for example, -@t{(preserving (list}@math{\;\;\langle{reg_1}\rangle\;\;\langle{reg_2}\rangle}@t{)}@math{\;\;\langle{seg_1}\rangle\;\;\langle{seg_2}\rangle}@t{)} +@code{(preserving (list}@math{\;\;\langle{reg_1}\rangle\;\;\langle{reg_2}\rangle}@code{)}@math{\;\;\langle{seg_1}\rangle\;\;\langle{seg_2}\rangle}@code{)} produces one of the following four sequences of instructions, depending on how @math{\langle}@math{seq_1}@math{\rangle} and @math{\langle}@math{seq_2}@math{\rangle} use @math{\langle}@math{reg_1}@math{\rangle} and @math{\langle}@math{reg_2}@math{\rangle}: @ifinfo @@ -35005,22 +35005,22 @@ $\langle{seq_2}\rangle$ \cr @end tex @noindent -By using @t{preserving} to combine instruction sequences the compiler avoids +By using @code{preserving} to combine instruction sequences the compiler avoids unnecessary stack operations. This also isolates the details of whether or not -to generate @t{save} and @t{restore} instructions within the -@t{preserving} procedure, separating them from the concerns that arise in -writing each of the individual code generators. In fact no @t{save} or -@t{restore} instructions are explicitly produced by the code generators. +to generate @code{save} and @code{restore} instructions within the +@code{preserving} procedure, separating them from the concerns that arise in +writing each of the individual code generators. In fact no @code{save} or +@code{restore} instructions are explicitly produced by the code generators. In principle, we could represent an instruction sequence simply as a list of -instructions. @t{Append-@/instruction-@/sequences} could then combine -instruction sequences by performing an ordinary list @t{append}. However, -@t{preserving} would then be a complex operation, because it would have to +instructions. @code{Append-@/instruction-@/sequences} could then combine +instruction sequences by performing an ordinary list @code{append}. However, +@code{preserving} would then be a complex operation, because it would have to analyze each instruction sequence to determine how the sequence uses its -registers. @t{Preserving} would be inefficient as well as complex, because +registers. @code{Preserving} would be inefficient as well as complex, because it would have to analyze each of its instruction sequence arguments, even though these sequences might themselves have been constructed by calls to -@t{preserving}, in which case their parts would have already been analyzed. +@code{preserving}, in which case their parts would have already been analyzed. To avoid such repetitious analysis we will associate with each instruction sequence some information about its register use. When we construct a basic instruction sequence we will provide this information explicitly, and the @@ -35058,9 +35058,9 @@ constructor for instruction sequences is thus @noindent For example, the two-instruction sequence that looks up the value of the -variable @t{x} in the current environment, assigns the result to @t{val}, -and then returns, requires registers @t{env} and @t{continue} to have -been initialized, and modifies register @t{val}. This sequence would +variable @code{x} in the current environment, assigns the result to @code{val}, +and then returns, requires registers @code{env} and @code{continue} to have +been initialized, and modifies register @code{val}. This sequence would therefore be constructed as @lisp @@ -35089,13 +35089,13 @@ The procedures for combining instruction sequences are shown in @quotation @strong{@anchor{Exercise 5.31}Exercise 5.31:} In evaluating a procedure application, the explicit-control evaluator always saves and restores the -@t{env} register around the evaluation of the operator, saves and restores -@t{env} around the evaluation of each operand (except the final one), saves -and restores @t{argl} around the evaluation of each operand, and saves and -restores @t{proc} around the evaluation of the operand sequence. For each -of the following combinations, say which of these @t{save} and -@t{restore} operations are superfluous and thus could be eliminated by the -compiler's @t{preserving} mechanism: +@code{env} register around the evaluation of the operator, saves and restores +@code{env} around the evaluation of each operand (except the final one), saves +and restores @code{argl} around the evaluation of each operand, and saves and +restores @code{proc} around the evaluation of the operand sequence. For each +of the following combinations, say which of these @code{save} and +@code{restore} operations are superfluous and thus could be eliminated by the +compiler's @code{preserving} mechanism: @lisp (f 'x 'y) @@ -35106,8 +35106,8 @@ compiler's @t{preserving} mechanism: @end quotation @quotation -@strong{@anchor{Exercise 5.32}Exercise 5.32:} Using the @t{preserving} -mechanism, the compiler will avoid saving and restoring @t{env} around the +@strong{@anchor{Exercise 5.32}Exercise 5.32:} Using the @code{preserving} +mechanism, the compiler will avoid saving and restoring @code{env} around the evaluation of the operator of a combination in the case where the operator is a symbol. We could also build such optimizations into the evaluator. Indeed, the explicit-control evaluator of @ref{5.4} already performs a similar @@ -35133,39 +35133,39 @@ think of this idea? @subsection Compiling Expressions In this section and the next we implement the code generators to which the -@t{compile} procedure dispatches. +@code{compile} procedure dispatches. @subsubheading Compiling linkage code In general, the output of each code generator will end with -instructions---generated by the procedure @t{compile-@/linkage}---that -implement the required linkage. If the linkage is @t{return} then we must -generate the instruction @t{(goto (reg continue))}. This needs the -@t{continue} register and does not modify any registers. If the linkage is -@t{next}, then we needn't include any additional instructions. Otherwise, -the linkage is a label, and we generate a @t{goto} to that label, an +instructions---generated by the procedure @code{compile-@/linkage}---that +implement the required linkage. If the linkage is @code{return} then we must +generate the instruction @code{(goto (reg continue))}. This needs the +@code{continue} register and does not modify any registers. If the linkage is +@code{next}, then we needn't include any additional instructions. Otherwise, +the linkage is a label, and we generate a @code{goto} to that label, an instruction that does not need or modify any registers.@footnote{This procedure uses a feature of Lisp called @newterm{backquote} (or @newterm{quasiquote}) that is handy for constructing lists. Preceding a list with a backquote symbol is much like quoting it, except that anything in the list that is flagged with a comma is evaluated. -For example, if the value of @t{linkage} is the symbol @t{branch25}, +For example, if the value of @code{linkage} is the symbol @code{branch25}, then the expression -@math{\kern1.2ex}@t{`((goto (label ,linkage)))} +@math{\kern1.2ex}@code{`((goto (label ,linkage)))} evaluates to the list -@math{\kern1.2ex}@t{((goto (label branch25)))} +@math{\kern1.2ex}@code{((goto (label branch25)))} -Similarly, if the value of @t{x} is the list @t{(a b c)}, then +Similarly, if the value of @code{x} is the list @code{(a b c)}, then -@math{\kern1.2ex}@t{`(1 2 ,(car x))} +@math{\kern1.2ex}@code{`(1 2 ,(car x))} evaluates to the list -@math{\kern1.2ex}@t{(1 2 a)}} +@math{\kern1.2ex}@code{(1 2 a)}} @lisp (define (compile-linkage linkage) @@ -35182,10 +35182,10 @@ evaluates to the list @end lisp @noindent -The linkage code is appended to an instruction sequence by @t{preserving} -the @t{continue} register, since a @t{return} linkage will require the -@t{continue} register: If the given instruction sequence modifies -@t{continue} and the linkage code needs it, @t{continue} will be saved +The linkage code is appended to an instruction sequence by @code{preserving} +the @code{continue} register, since a @code{return} linkage will require the +@code{continue} register: If the given instruction sequence modifies +@code{continue} and the linkage code needs it, @code{continue} will be saved and restored. @lisp @@ -35234,16 +35234,16 @@ register and then proceed as specified by the linkage descriptor. @noindent All these assignment instructions modify the target register, and the one that -looks up a variable needs the @t{env} register. +looks up a variable needs the @code{env} register. Assignments and definitions are handled much as they are in the interpreter. We recursively generate code that computes the value to be assigned to the variable, and append to it a two-instruction sequence that actually sets or defines the variable and assigns the value of the whole expression (the symbol -@t{ok}) to the target register. The recursive compilation has target -@t{val} and linkage @t{next} so that the code will put its result into -@t{val} and continue with the code that is appended after it. The appending -is done preserving @t{env}, since the environment is needed for setting or +@code{ok}) to the target register. The recursive compilation has target +@code{val} and linkage @code{next} so that the code will put its result into +@code{val} and continue with the code that is appended after it. The appending +is done preserving @code{env}, since the environment is needed for setting or defining the variable and the code for the variable value could be the compilation of a complex expression that might modify the registers in arbitrary ways. @@ -35292,27 +35292,27 @@ arbitrary ways. @end lisp @noindent -The appended two-instruction sequence requires @t{env} and @t{val} and -modifies the target. Note that although we preserve @t{env} for this -sequence, we do not preserve @t{val}, because the @t{get-value-code} is -designed to explicitly place its result in @t{val} for use by this sequence. -(In fact, if we did preserve @t{val}, we would have a bug, because this -would cause the previous contents of @t{val} to be restored right after the -@t{get-value-code} is run.) +The appended two-instruction sequence requires @code{env} and @code{val} and +modifies the target. Note that although we preserve @code{env} for this +sequence, we do not preserve @code{val}, because the @code{get-value-code} is +designed to explicitly place its result in @code{val} for use by this sequence. +(In fact, if we did preserve @code{val}, we would have a bug, because this +would cause the previous contents of @code{val} to be restored right after the +@code{get-value-code} is run.) @subsubheading Compiling conditional expressions -The code for an @t{if} expression compiled with a given target and linkage +The code for an @code{if} expression compiled with a given target and linkage has the form @lisp @math{\langle}@emph{compilation of predicate, - target @t{val}, linkage @t{next}}@math{\rangle} + target @code{val}, linkage @code{next}}@math{\rangle} (test (op false?) (reg val)) (branch (label false-branch)) true-branch @math{\langle}@emph{compilation of consequent with given target - and given linkage or @t{after-if}}@math{\rangle} + and given linkage or @code{after-if}}@math{\rangle} false-branch @math{\langle}@emph{compilation of alternative with given target and linkage}@math{\rangle} @@ -35323,13 +35323,13 @@ after-if To generate this code, we compile the predicate, consequent, and alternative, and combine the resulting code with instructions to test the predicate result and with newly generated labels to mark the true and false branches and the end -of the conditional.@footnote{We can't just use the labels @t{true-branch}, -@t{false-branch}, and @t{after-if} as shown above, because there might be -more than one @t{if} in the program. The compiler uses the procedure -@t{make-label} to generate labels. @t{Make-label} takes a symbol as +of the conditional.@footnote{We can't just use the labels @code{true-branch}, +@code{false-branch}, and @code{after-if} as shown above, because there might be +more than one @code{if} in the program. The compiler uses the procedure +@code{make-label} to generate labels. @code{Make-label} takes a symbol as argument and returns a new symbol that begins with the given symbol. For -example, successive calls to @t{(make-label 'a)} would return @t{a1}, -@t{a2}, and so on. @t{Make-label} can be implemented similarly to the +example, successive calls to @code{(make-label 'a)} would return @code{a1}, +@code{a2}, and so on. @code{Make-label} can be implemented similarly to the generation of unique variable names in the query language, as follows: @lisp @@ -35347,9 +35347,9 @@ generation of unique variable names in the query language, as follows: @end lisp } In this arrangement of code, we must branch around the true branch if the test is false. The only slight complication is in how the linkage for the true -branch should be handled. If the linkage for the conditional is @t{return} +branch should be handled. If the linkage for the conditional is @code{return} or a label, then the true and false branches will both use this same linkage. -If the linkage is @t{next}, the true branch ends with a jump around the code +If the linkage is @code{next}, the true branch ends with a jump around the code for the false branch to the label at the end of the conditional. @lisp @@ -35391,26 +35391,26 @@ for the false branch to the label at the end of the conditional. @end lisp @noindent -@t{Env} is preserved around the predicate code because it could be needed by -the true and false branches, and @t{continue} is preserved because it could +@code{Env} is preserved around the predicate code because it could be needed by +the true and false branches, and @code{continue} is preserved because it could be needed by the linkage code in those branches. The code for the true and false branches (which are not executed sequentially) is appended using a -special combiner @t{parallel-@/instruction-@/sequences} described in +special combiner @code{parallel-@/instruction-@/sequences} described in @ref{5.5.4}. -Note that @t{cond} is a derived expression, so all that the compiler needs -to do handle it is to apply the @t{cond->if} transformer (from -@ref{4.1.2}) and compile the resulting @t{if} expression. +Note that @code{cond} is a derived expression, so all that the compiler needs +to do handle it is to apply the @code{cond->if} transformer (from +@ref{4.1.2}) and compile the resulting @code{if} expression. @subsubheading Compiling sequences -The compilation of sequences (from procedure bodies or explicit @t{begin} +The compilation of sequences (from procedure bodies or explicit @code{begin} expressions) parallels their evaluation. Each expression of the sequence is compiled---the last expression with the linkage specified for the sequence, and -the other expressions with linkage @t{next} (to execute the rest of the +the other expressions with linkage @code{next} (to execute the rest of the sequence). The instruction sequences for the individual expressions are -appended to form a single instruction sequence, such that @t{env} (needed -for the rest of the sequence) and @t{continue} (possibly needed for the +appended to form a single instruction sequence, such that @code{env} (needed +for the rest of the sequence) and @code{continue} (possibly needed for the linkage at the end of the sequence) are preserved. @lisp @@ -35424,10 +35424,10 @@ linkage at the end of the sequence) are preserved. linkage)))) @end lisp -@subsubheading Compiling @t{lambda} expressions +@subsubheading Compiling @code{lambda} expressions -@t{Lambda} expressions construct procedures. The object code for a -@t{lambda} expression must have the form +@code{Lambda} expressions construct procedures. The object code for a +@code{lambda} expression must have the form @lisp @math{\langle}@emph{construct procedure object @@ -35436,12 +35436,12 @@ linkage at the end of the sequence) are preserved. @end lisp @noindent -When we compile the @t{lambda} expression, we also generate the code for the +When we compile the @code{lambda} expression, we also generate the code for the procedure body. Although the body won't be executed at the time of procedure construction, it is convenient to insert it into the object code right after -the code for the @t{lambda}. If the linkage for the @t{lambda} -expression is a label or @t{return}, this is fine. But if the linkage is -@t{next}, we will need to skip around the code for the procedure body by +the code for the @code{lambda}. If the linkage for the @code{lambda} +expression is a label or @code{return}, this is fine. But if the linkage is +@code{next}, we will need to skip around the code for the procedure body by using a linkage that jumps to a label that is inserted after the body. The object code thus has the form @@ -35449,13 +35449,13 @@ object code thus has the form @math{\langle}@emph{construct procedure object and assign it to target register}@math{\rangle} @math{\langle}@emph{code for given linkage}@math{\rangle} @emph{or} - @t{(goto (label after-lambda))} + @code{(goto (label after-lambda))} @math{\langle}@emph{compilation of procedure body}@math{\rangle} after-lambda @end lisp @noindent -@t{Compile-lambda} generates the code for constructing the procedure object +@code{Compile-lambda} generates the code for constructing the procedure object followed by the code for the procedure body. The procedure object will be constructed at run time by combining the current environment (the environment at the point of definition) with the entry point to the compiled procedure body @@ -35503,24 +35503,24 @@ procedures, analogous to the structure for compound procedures described in @end lisp @noindent -@t{Compile-lambda} uses the special combiner -@t{tack-@/on-@/instruction-@/sequence} rather than -@t{append-@/instruction-@/sequences} (@ref{5.5.4}) to append the procedure body to the -@t{lambda} expression code, because the body is not part of the sequence of +@code{Compile-lambda} uses the special combiner +@code{tack-@/on-@/instruction-@/sequence} rather than +@code{append-@/instruction-@/sequences} (@ref{5.5.4}) to append the procedure body to the +@code{lambda} expression code, because the body is not part of the sequence of instructions that will be executed when the combined sequence is entered; rather, it is in the sequence only because that was a convenient place to put it. -@t{Compile-lambda-body} constructs the code for the body of the procedure. +@code{Compile-lambda-body} constructs the code for the body of the procedure. This code begins with a label for the entry point. Next come instructions that will cause the run-time evaluation environment to switch to the correct environment for evaluating the procedure body---namely, the definition environment of the procedure, extended to include the bindings of the formal parameters to the arguments with which the procedure is called. After this comes the code for the sequence of expressions that makes up the procedure -body. The sequence is compiled with linkage @t{return} and target -@t{val} so that it will end by returning from the procedure with the -procedure result in @t{val}. +body. The sequence is compiled with linkage @code{return} and target +@code{val} so that it will end by returning from the procedure with the +procedure result in @code{val}. @lisp (define (compile-lambda-body exp proc-entry) @@ -35552,32 +35552,32 @@ linkage has the form @lisp @math{\langle}@emph{compilation of operator, - target @t{proc}, linkage @t{next}}@math{\rangle} + target @code{proc}, linkage @code{next}}@math{\rangle} @math{\langle}@emph{evaluate operands and construct - argument list in @t{argl}}@math{\rangle} + argument list in @code{argl}}@math{\rangle} @math{\langle}@emph{compilation of procedure call with given target and linkage}@math{\rangle} @end lisp @noindent -The registers @t{env}, @t{proc}, and @t{argl} may have to be saved and +The registers @code{env}, @code{proc}, and @code{argl} may have to be saved and restored during evaluation of the operator and operands. Note that this is the -only place in the compiler where a target other than @t{val} is specified. +only place in the compiler where a target other than @code{val} is specified. -The required code is generated by @t{compile-application}. This recursively +The required code is generated by @code{compile-application}. This recursively compiles the operator, to produce code that puts the procedure to be applied -into @t{proc}, and compiles the operands, to produce code that evaluates the +into @code{proc}, and compiles the operands, to produce code that evaluates the individual operands of the application. The instruction sequences for the -operands are combined (by @t{construct-arglist}) with code that constructs -the list of arguments in @t{argl}, and the resulting argument-list code is +operands are combined (by @code{construct-arglist}) with code that constructs +the list of arguments in @code{argl}, and the resulting argument-list code is combined with the procedure code and the code that performs the procedure call -(produced by @t{compile-procedure-call}). In appending the code sequences, -the @t{env} register must be preserved around the evaluation of the operator -(since evaluating the operator might modify @t{env}, which will be needed to -evaluate the operands), and the @t{proc} register must be preserved around +(produced by @code{compile-procedure-call}). In appending the code sequences, +the @code{env} register must be preserved around the evaluation of the operator +(since evaluating the operator might modify @code{env}, which will be needed to +evaluate the operands), and the @code{proc} register must be preserved around the construction of the argument list (since evaluating the operands might -modify @t{proc}, which will be needed for the actual procedure application). -@t{Continue} must also be preserved throughout, since it is needed for the +modify @code{proc}, which will be needed for the actual procedure application). +@code{Continue} must also be preserved throughout, since it is needed for the linkage in the procedure call. @lisp @@ -35602,34 +35602,34 @@ linkage in the procedure call. @noindent The code to construct the argument list will evaluate each operand into -@t{val} and then @t{cons} that value onto the argument list being -accumulated in @t{argl}. Since we @t{cons} the arguments onto -@t{argl} in sequence, we must start with the last argument and end with the +@code{val} and then @code{cons} that value onto the argument list being +accumulated in @code{argl}. Since we @code{cons} the arguments onto +@code{argl} in sequence, we must start with the last argument and end with the first, so that the arguments will appear in order from first to last in the -resulting list. Rather than waste an instruction by initializing @t{argl} +resulting list. Rather than waste an instruction by initializing @code{argl} to the empty list to set up for this sequence of evaluations, we make the first -code sequence construct the initial @t{argl}. The general form of the +code sequence construct the initial @code{argl}. The general form of the argument-list construction is thus as follows: @lisp -@math{\langle}@emph{compilation of last operand, targeted to @t{val}}@math{\rangle} +@math{\langle}@emph{compilation of last operand, targeted to @code{val}}@math{\rangle} (assign argl (op list) (reg val)) -@math{\langle}@emph{compilation of next operand, targeted to @t{val}}@math{\rangle} +@math{\langle}@emph{compilation of next operand, targeted to @code{val}}@math{\rangle} (assign argl (op cons) (reg val) (reg argl)) @dots{} -@math{\langle}@emph{compilation of first operand, targeted to @t{val}}@math{\rangle} +@math{\langle}@emph{compilation of first operand, targeted to @code{val}}@math{\rangle} (assign argl (op cons) (reg val) (reg argl)) @end lisp @noindent -@t{Argl} must be preserved around each operand evaluation except the first -(so that arguments accumulated so far won't be lost), and @t{env} must be +@code{Argl} must be preserved around each operand evaluation except the first +(so that arguments accumulated so far won't be lost), and @code{env} must be preserved around each operand evaluation except the last (for use by subsequent operand evaluations). Compiling this argument code is a bit tricky, because of the special treatment -of the first operand to be evaluated and the need to preserve @t{argl} and -@t{env} in different places. The @t{construct-arglist} procedure takes +of the first operand to be evaluated and the need to preserve @code{argl} and +@code{env} in different places. The @code{construct-arglist} procedure takes as arguments the code that evaluates the individual operands. If there are no operands at all, it simply emits the instruction @@ -35638,11 +35638,11 @@ operands at all, it simply emits the instruction @end lisp @noindent -Otherwise, @t{construct-arglist} creates code that initializes @t{argl} +Otherwise, @code{construct-arglist} creates code that initializes @code{argl} with the last argument, and appends code that evaluates the rest of the -arguments and adjoins them to @t{argl} in succession. In order to process +arguments and adjoins them to @code{argl} in succession. In order to process the arguments from last to first, we must reverse the list of operand code -sequences from the order supplied by @t{compile-@/application}. +sequences from the order supplied by @code{compile-@/application}. @lisp (define (construct-arglist operand-codes) @@ -35694,13 +35694,13 @@ sequences from the order supplied by @t{compile-@/application}. @subsubheading Applying procedures After evaluating the elements of a combination, the compiled code must apply -the procedure in @t{proc} to the arguments in @t{argl}. The code -performs essentially the same dispatch as the @t{apply} procedure in the -metacircular evaluator of @ref{4.1.1} or the @t{apply-dispatch} +the procedure in @code{proc} to the arguments in @code{argl}. The code +performs essentially the same dispatch as the @code{apply} procedure in the +metacircular evaluator of @ref{4.1.1} or the @code{apply-dispatch} entry point in the explicit-control evaluator of @ref{5.4.1}. It checks whether the procedure to be applied is a primitive procedure or a compiled procedure. For a primitive procedure, it uses -@t{apply-primitive-procedure}; we will see shortly how it handles compiled +@code{apply-primitive-procedure}; we will see shortly how it handles compiled procedures. The procedure-application code has the following form: @lisp @@ -35720,10 +35720,10 @@ after-call @noindent Observe that the compiled branch must skip around the primitive branch. -Therefore, if the linkage for the original procedure call was @t{next}, the +Therefore, if the linkage for the original procedure call was @code{next}, the compound branch must use a linkage that jumps to a label that is inserted after the primitive branch. (This is similar to the linkage used for the true branch -in @t{compile-if}.) +in @code{compile-if}.) @lisp (define (compile-procedure-call @@ -35770,20 +35770,20 @@ in @t{compile-if}.) @noindent The primitive and compound branches, like the true and false branches in -@t{compile-if}, are appended using @t{parallel-instruction-sequences} -rather than the ordinary @t{append-instruction-sequences}, because they will +@code{compile-if}, are appended using @code{parallel-instruction-sequences} +rather than the ordinary @code{append-instruction-sequences}, because they will not be executed sequentially. @subsubheading Applying compiled procedures The code that handles procedure application is the most subtle part of the compiler, even though the instruction sequences it generates are very short. A -compiled procedure (as constructed by @t{compile-lambda}) has an entry +compiled procedure (as constructed by @code{compile-lambda}) has an entry point, which is a label that designates where the code for the procedure -starts. The code at this entry point computes a result in @t{val} and -returns by executing the instruction @t{(goto (reg continue))}. Thus, we +starts. The code at this entry point computes a result in @code{val} and +returns by executing the instruction @code{(goto (reg continue))}. Thus, we might expect the code for a compiled-procedure application (to be generated by -@t{compile-proc-appl}) with a given target and linkage to look like this if +@code{compile-proc-appl}) with a given target and linkage to look like this if the linkage is a label @lisp @@ -35795,12 +35795,12 @@ the linkage is a label (goto (reg val)) proc-return (assign @math{\langle}@var{target}@math{\rangle} - (reg val)) @r{; included if target is not @t{val}} + (reg val)) @r{; included if target is not @code{val}} (goto (label @math{\langle}@var{linkage}@math{\rangle})) @r{; linkage code} @end lisp @noindent -or like this if the linkage is @t{return}. +or like this if the linkage is @code{return}. @lisp (save continue) @@ -35812,34 +35812,34 @@ or like this if the linkage is @t{return}. (goto (reg val)) proc-return (assign @math{\langle}@var{target}@math{\rangle} - (reg val)) @r{; included if target is not @t{val}} + (reg val)) @r{; included if target is not @code{val}} (restore continue) (goto (reg continue)) @r{; linkage code} @end lisp @noindent -This code sets up @t{continue} so that the procedure will return to a label -@t{proc-return} and jumps to the procedure's entry point. The code at -@t{proc-return} transfers the procedure's result from @t{val} to the +This code sets up @code{continue} so that the procedure will return to a label +@code{proc-return} and jumps to the procedure's entry point. The code at +@code{proc-return} transfers the procedure's result from @code{val} to the target register (if necessary) and then jumps to the location specified by the -linkage. (The linkage is always @t{return} or a label, because -@t{compile-procedure-call} replaces a @t{next} linkage for the -compound-procedure branch by an @t{after-call} label.) +linkage. (The linkage is always @code{return} or a label, because +@code{compile-procedure-call} replaces a @code{next} linkage for the +compound-procedure branch by an @code{after-call} label.) -In fact, if the target is not @t{val}, that is exactly the code our compiler +In fact, if the target is not @code{val}, that is exactly the code our compiler will generate.@footnote{Actually, we signal an error when the target is not -@t{val} and the linkage is @t{return}, since the only place we request -@t{return} linkages is in compiling procedures, and our convention is that -procedures return their values in @t{val}.} Usually, however, the target is -@t{val} (the only time the compiler specifies a different register is when -targeting the evaluation of an operator to @t{proc}), so the procedure +@code{val} and the linkage is @code{return}, since the only place we request +@code{return} linkages is in compiling procedures, and our convention is that +procedures return their values in @code{val}.} Usually, however, the target is +@code{val} (the only time the compiler specifies a different register is when +targeting the evaluation of an operator to @code{proc}), so the procedure result is put directly into the target register and there is no need to return to a special location that copies it. Instead, we simplify the code by setting -up @t{continue} so that the procedure will ``return'' directly to the place +up @code{continue} so that the procedure will ``return'' directly to the place specified by the caller's linkage: @lisp -@math{\langle}@emph{set up @t{continue} for linkage}@math{\rangle} +@math{\langle}@emph{set up @code{continue} for linkage}@math{\rangle} (assign val (op compiled-procedure-entry) (reg proc)) @@ -35847,10 +35847,10 @@ specified by the caller's linkage: @end lisp @noindent -If the linkage is a label, we set up @t{continue} so that the procedure will -return to that label. (That is, the @t{(goto (reg continue))} the procedure -ends with becomes equivalent to the @t{(goto (label <@var{linkage}>))} at -@t{proc-return} above.) +If the linkage is a label, we set up @code{continue} so that the procedure will +return to that label. (That is, the @code{(goto (reg continue))} the procedure +ends with becomes equivalent to the @code{(goto (label <@var{linkage}>))} at +@code{proc-return} above.) @lisp (assign continue @@ -35862,10 +35862,10 @@ ends with becomes equivalent to the @t{(goto (label <@var{linkage}>))} at @end lisp @noindent -If the linkage is @t{return}, we don't need to set up @t{continue} at -all: It already holds the desired location. (That is, the @t{(goto (reg +If the linkage is @code{return}, we don't need to set up @code{continue} at +all: It already holds the desired location. (That is, the @code{(goto (reg continue))} the procedure ends with goes directly to the place where the -@t{(goto (reg continue))} at @t{proc-return} would have gone.) +@code{(goto (reg continue))} at @code{proc-return} would have gone.) @lisp (assign val @@ -35875,15 +35875,15 @@ continue))} the procedure ends with goes directly to the place where the @end lisp @noindent -With this implementation of the @t{return} linkage, the compiler generates +With this implementation of the @code{return} linkage, the compiler generates tail-recursive code. Calling a procedure as the final step in a procedure body does a direct transfer, without saving any information on the stack. Suppose instead that we had handled the case of a procedure call with a linkage -of @t{return} and a target of @t{val} as shown above for a non-@t{val} +of @code{return} and a target of @code{val} as shown above for a non-@code{val} target. This would destroy tail recursion. Our system would still give the same value for any expression. But each time we called a procedure, we would -save @t{continue} and return after the call to undo the (useless) save. +save @code{continue} and return after the call to undo the (useless) save. These extra saves would accumulate during a nest of procedure calls.@footnote{Making a compiler generate tail-recursive code might seem like a straightforward idea. But most compilers for common languages, including C @@ -35902,18 +35902,18 @@ actually more efficient than garbage collection in the first place, but the details seem to hinge on fine points of computer architecture. (See @ref{Appel 1987} and @ref{Miller and Rozas 1994} for opposing views on this issue.)} -@t{Compile-proc-appl} generates the above procedure-application code by +@code{Compile-proc-appl} generates the above procedure-application code by considering four cases, depending on whether the target for the call is -@t{val} and whether the linkage is @t{return}. Observe that the +@code{val} and whether the linkage is @code{return}. Observe that the instruction sequences are declared to modify all the registers, since executing the procedure body can change the registers in arbitrary ways.@footnote{The -variable @t{all-regs} is bound to the list of names of all the registers: +variable @code{all-regs} is bound to the list of names of all the registers: -@math{\kern1.2ex}@t{(define all-regs '(env proc val argl continue))}} -Also note that the code sequence for the case with target @t{val} and -linkage @t{return} is declared to need @t{continue}: Even though -@t{continue} is not explicitly used in the two-instruction sequence, we must -be sure that @t{continue} will have the correct value when we enter the +@math{\kern1.2ex}@code{(define all-regs '(env proc val argl continue))}} +Also note that the code sequence for the case with target @code{val} and +linkage @code{return} is declared to need @code{continue}: Even though +@code{continue} is not explicitly used in the two-instruction sequence, we must +be sure that @code{continue} will have the correct value when we enter the compiled procedure. @lisp @@ -35998,7 +35998,7 @@ sequence needs or modifies a given register we use the predicates In terms of these predicates and selectors, we can implement the various instruction sequence combiners used throughout the compiler. -The basic combiner is @t{append-instruction-sequences}. This takes as +The basic combiner is @code{append-instruction-sequences}. This takes as arguments an arbitrary number of instruction sequences that are to be executed sequentially and returns an instruction sequence whose statements are the statements of all the sequences appended together. The subtle point is to @@ -36009,17 +36009,17 @@ those registers that must be initialized before the first sequence can be run needed by any of the other sequences that are not initialized (modified) by sequences preceding it. -The sequences are appended two at a time by @t{append-@/2-@/sequences}. This -takes two instruction sequences @t{seq1} and @t{seq2} and returns the -instruction sequence whose statements are the statements of @t{seq1} -followed by the statements of @t{seq2}, whose modified registers are those -registers that are modified by either @t{seq1} or @t{seq2}, and whose -needed registers are the registers needed by @t{seq1} together with those -registers needed by @t{seq2} that are not modified by @t{seq1}. (In +The sequences are appended two at a time by @code{append-@/2-@/sequences}. This +takes two instruction sequences @code{seq1} and @code{seq2} and returns the +instruction sequence whose statements are the statements of @code{seq1} +followed by the statements of @code{seq2}, whose modified registers are those +registers that are modified by either @code{seq1} or @code{seq2}, and whose +needed registers are the registers needed by @code{seq1} together with those +registers needed by @code{seq2} that are not modified by @code{seq1}. (In terms of set operations, the new set of needed registers is the union of the -set of registers needed by @t{seq1} with the set difference of the registers -needed by @t{seq2} and the registers modified by @t{seq1}.) Thus, -@t{append-instruction-sequences} is implemented as follows: +set of registers needed by @code{seq1} with the set difference of the registers +needed by @code{seq2} and the registers modified by @code{seq1}.) Thus, +@code{append-instruction-sequences} is implemented as follows: @lisp (define (append-instruction-sequences . seqs) @@ -36068,24 +36068,24 @@ lists, similar to the (unordered) set representation described in @end lisp @noindent -@t{Preserving}, the second major instruction sequence combiner, takes a list -of registers @t{regs} and two instruction sequences @t{seq1} and -@t{seq2} that are to be executed sequentially. It returns an instruction -sequence whose statements are the statements of @t{seq1} followed by the -statements of @t{seq2}, with appropriate @t{save} and @t{restore} -instructions around @t{seq1} to protect the registers in @t{regs} that -are modified by @t{seq1} but needed by @t{seq2}. To accomplish this, -@t{preserving} first creates a sequence that has the required @t{save}s -followed by the statements of @t{seq1} followed by the required -@t{restore}s. This sequence needs the registers being saved and restored in -addition to the registers needed by @t{seq1}, and modifies the registers -modified by @t{seq1} except for the ones being saved and restored. This -augmented sequence and @t{seq2} are then appended in the usual way. The +@code{Preserving}, the second major instruction sequence combiner, takes a list +of registers @code{regs} and two instruction sequences @code{seq1} and +@code{seq2} that are to be executed sequentially. It returns an instruction +sequence whose statements are the statements of @code{seq1} followed by the +statements of @code{seq2}, with appropriate @code{save} and @code{restore} +instructions around @code{seq1} to protect the registers in @code{regs} that +are modified by @code{seq1} but needed by @code{seq2}. To accomplish this, +@code{preserving} first creates a sequence that has the required @code{save}s +followed by the statements of @code{seq1} followed by the required +@code{restore}s. This sequence needs the registers being saved and restored in +addition to the registers needed by @code{seq1}, and modifies the registers +modified by @code{seq1} except for the ones being saved and restored. This +augmented sequence and @code{seq2} are then appended in the usual way. The following procedure implements this strategy recursively, walking down the list -of registers to be preserved:@footnote{Note that @t{preserving} calls -@t{append} with three arguments. Though the definition of @t{append} +of registers to be preserved:@footnote{Note that @code{preserving} calls +@code{append} with three arguments. Though the definition of @code{append} shown in this book accepts only two arguments, Scheme standardly provides an -@t{append} procedure that takes an arbitrary number of arguments.} +@code{append} procedure that takes an arbitrary number of arguments.} @lisp (define (preserving regs seq1 seq2) @@ -36116,8 +36116,8 @@ shown in this book accepts only two arguments, Scheme standardly provides an @end lisp @noindent -Another sequence combiner, @t{tack-@/on-@/instruction-@/sequence}, is used by -@t{compile-@/lambda} to append a procedure body to another sequence. Because +Another sequence combiner, @code{tack-@/on-@/instruction-@/sequence}, is used by +@code{compile-@/lambda} to append a procedure body to another sequence. Because the procedure body is not ``in line'' to be executed as part of the combined sequence, its register use has no impact on the register use of the sequence in which it is embedded. We thus ignore the procedure body's sets of needed and @@ -36134,8 +36134,8 @@ modified registers when we tack it onto the other sequence. @end lisp @noindent -@t{Compile-if} and @t{compile-procedure-call} use a special combiner -called @t{parallel-@/instruction-@/sequences} to append the two alternative +@code{Compile-if} and @code{compile-procedure-call} use a special combiner +called @code{parallel-@/instruction-@/sequences} to append the two alternative branches that follow a test. The two branches will never be executed sequentially; for any particular evaluation of the test, one branch or the other will be entered. Because of this, the registers needed by the second @@ -36159,7 +36159,7 @@ the first branch. Now that we have seen all the elements of the compiler, let us examine an example of compiled code to see how things fit together. We will compile the -definition of a recursive @t{factorial} procedure by calling @t{compile}: +definition of a recursive @code{factorial} procedure by calling @code{compile}: @lisp (compile @@ -36172,25 +36172,25 @@ definition of a recursive @t{factorial} procedure by calling @t{compile}: @end lisp @noindent -We have specified that the value of the @t{define} expression should be -placed in the @t{val} register. We don't care what the compiled code does -after executing the @t{define}, so our choice of @t{next} as the linkage +We have specified that the value of the @code{define} expression should be +placed in the @code{val} register. We don't care what the compiled code does +after executing the @code{define}, so our choice of @code{next} as the linkage descriptor is arbitrary. -@t{Compile} determines that the expression is a definition, so it calls -@t{compile-@/definition} to compile code to compute the value to be assigned -(targeted to @t{val}), followed by code to install the definition, followed -by code to put the value of the @t{define} (which is the symbol @t{ok}) -into the target register, followed finally by the linkage code. @t{Env} is +@code{Compile} determines that the expression is a definition, so it calls +@code{compile-@/definition} to compile code to compute the value to be assigned +(targeted to @code{val}), followed by code to install the definition, followed +by code to put the value of the @code{define} (which is the symbol @code{ok}) +into the target register, followed finally by the linkage code. @code{Env} is preserved around the computation of the value, because it is needed in order to -install the definition. Because the linkage is @t{next}, there is no +install the definition. Because the linkage is @code{next}, there is no linkage code in this case. The skeleton of the compiled code is thus @lisp -@math{\langle}@emph{save @t{env} if modified by code to compute value}@math{\rangle} +@math{\langle}@emph{save @code{env} if modified by code to compute value}@math{\rangle} @math{\langle}@emph{compilation of definition value, - target @t{val}, linkage @t{next}}@math{\rangle} - @math{\langle}@emph{restore @t{env} if saved above}@math{\rangle} + target @code{val}, linkage @code{next}}@math{\rangle} + @math{\langle}@emph{restore @code{env} if saved above}@math{\rangle} (perform (op define-variable!) (const factorial) (reg val) @@ -36200,19 +36200,19 @@ linkage code in this case. The skeleton of the compiled code is thus @noindent The expression that is to be compiled to produce the value for the variable -@t{factorial} is a @t{lambda} expression whose value is the procedure -that computes factorials. @t{Compile} handles this by calling -@t{compile-lambda}, which compiles the procedure body, labels it as a new +@code{factorial} is a @code{lambda} expression whose value is the procedure +that computes factorials. @code{Compile} handles this by calling +@code{compile-lambda}, which compiles the procedure body, labels it as a new entry point, and generates the instruction that will combine the procedure body at the new entry point with the run-time environment and assign the result to -@t{val}. The sequence then skips around the compiled procedure code, which +@code{val}. The sequence then skips around the compiled procedure code, which is inserted at this point. The procedure code itself begins by extending the procedure's definition environment by a frame that binds the formal parameter -@t{n} to the procedure argument. Then comes the actual procedure body. -Since this code for the value of the variable doesn't modify the @t{env} -register, the optional @t{save} and @t{restore} shown above aren't -generated. (The procedure code at @t{entry2} isn't executed at this point, -so its use of @t{env} is irrelevant.) Therefore, the skeleton for the +@code{n} to the procedure argument. Then comes the actual procedure body. +Since this code for the value of the variable doesn't modify the @code{env} +register, the optional @code{save} and @code{restore} shown above aren't +generated. (The procedure code at @code{entry2} isn't executed at this point, +so its use of @code{env} is irrelevant.) Therefore, the skeleton for the compiled code becomes @lisp @@ -36236,9 +36236,9 @@ after-lambda1 @end lisp @noindent -A procedure body is always compiled (by @t{compile-@/lambda-@/body}) as a -sequence with target @t{val} and linkage @t{return}. The sequence in -this case consists of a single @t{if} expression: +A procedure body is always compiled (by @code{compile-@/lambda-@/body}) as a +sequence with target @code{val} and linkage @code{return}. The sequence in +this case consists of a single @code{if} expression: @lisp (if (= n 1) @@ -36247,41 +36247,41 @@ this case consists of a single @t{if} expression: @end lisp @noindent -@t{Compile-if} generates code that first computes the predicate (targeted to -@t{val}), then checks the result and branches around the true branch if the -predicate is false. @t{Env} and @t{continue} are preserved around the -predicate code, since they may be needed for the rest of the @t{if} -expression. Since the @t{if} expression is the final expression (and only +@code{Compile-if} generates code that first computes the predicate (targeted to +@code{val}), then checks the result and branches around the true branch if the +predicate is false. @code{Env} and @code{continue} are preserved around the +predicate code, since they may be needed for the rest of the @code{if} +expression. Since the @code{if} expression is the final expression (and only expression) in the sequence making up the procedure body, its target is -@t{val} and its linkage is @t{return}, so the true and false branches are -both compiled with target @t{val} and linkage @t{return}. (That is, the +@code{val} and its linkage is @code{return}, so the true and false branches are +both compiled with target @code{val} and linkage @code{return}. (That is, the value of the conditional, which is the value computed by either of its branches, is the value of the procedure.) @lisp -@math{\langle}@emph{save @t{continue}, @t{env} if modified by predicate +@math{\langle}@emph{save @code{continue}, @code{env} if modified by predicate and needed by branches}@math{\rangle} @math{\langle}@emph{compilation of predicate, - target @t{val}, linkage @t{next}}@math{\rangle} - @math{\langle}@emph{restore @t{continue}, @t{env} if saved above}@math{\rangle} + target @code{val}, linkage @code{next}}@math{\rangle} + @math{\langle}@emph{restore @code{continue}, @code{env} if saved above}@math{\rangle} (test (op false?) (reg val)) (branch (label false-branch4)) true-branch5 @math{\langle}@emph{compilation of true branch, - target @t{val}, linkage @t{return}}@math{\rangle} + target @code{val}, linkage @code{return}}@math{\rangle} false-branch4 @math{\langle}@emph{compilation of false branch, - target @t{val}, linkage @t{return}}@math{\rangle} + target @code{val}, linkage @code{return}}@math{\rangle} after-if3 @end lisp @noindent -The predicate @t{(= n 1)} is a procedure call. This looks up the operator -(the symbol @t{=}) and places this value in @t{proc}. It then assembles -the arguments @t{1} and the value of @t{n} into @t{argl}. Then it -tests whether @t{proc} contains a primitive or a compound procedure, and +The predicate @code{(= n 1)} is a procedure call. This looks up the operator +(the symbol @code{=}) and places this value in @code{proc}. It then assembles +the arguments @code{1} and the value of @code{n} into @code{argl}. Then it +tests whether @code{proc} contains a primitive or a compound procedure, and dispatches to a primitive branch or a compound branch accordingly. Both -branches resume at the @t{after-call} label. The requirements to preserve +branches resume at the @code{after-call} label. The requirements to preserve registers around the evaluation of the operator and operands don't result in any saving of registers, because in this case those evaluations don't modify the registers in question. @@ -36311,8 +36311,8 @@ after-call15 @end lisp @noindent -The true branch, which is the constant 1, compiles (with target @t{val} and -linkage @t{return}) to +The true branch, which is the constant 1, compiles (with target @code{val} and +linkage @code{return}) to @lisp (assign val (const 1)) @@ -36321,18 +36321,18 @@ linkage @t{return}) to @noindent The code for the false branch is another procedure call, where the procedure -is the value of the symbol @t{*}, and the arguments are @t{n} and the -result of another procedure call (a call to @t{factorial}). Each of these -calls sets up @t{proc} and @t{argl} and its own primitive and compound +is the value of the symbol @code{*}, and the arguments are @code{n} and the +result of another procedure call (a call to @code{factorial}). Each of these +calls sets up @code{proc} and @code{argl} and its own primitive and compound branches. @ref{Figure 5.17} shows the complete compilation of the definition -of the @t{factorial} procedure. Notice that the possible @t{save} and -@t{restore} of @t{continue} and @t{env} around the predicate, shown +of the @code{factorial} procedure. Notice that the possible @code{save} and +@code{restore} of @code{continue} and @code{env} around the predicate, shown above, are in fact generated, because these registers are modified by the procedure call in the predicate and needed for the procedure call and the -@t{return} linkage in the branches. +@code{return} linkage in the branches. @quotation -@strong{@anchor{Figure 5.17}Figure 5.17:} @math{\downarrow} Compilation of the definition of the @t{factorial} procedure. +@strong{@anchor{Figure 5.17}Figure 5.17:} @math{\downarrow} Compilation of the definition of the @code{factorial} procedure. @smalllisp @r{;; construct the procedure and skip over code} @@ -36343,7 +36343,7 @@ procedure call in the predicate and needed for the procedure call and the (reg env)) (goto (label after-lambda1)) -entry2 @r{; calls to @t{factorial} will enter here} +entry2 @r{; calls to @code{factorial} will enter here} (assign env (op compiled-procedure-env) (reg proc)) @@ -36356,7 +36356,7 @@ entry2 @r{; calls to @t{factorial} will enter here} (save continue) (save env) -@r{;; compute @t{(= n 1)}} +@r{;; compute @code{(= n 1)}} (assign proc (op lookup-variable-value) (const =) @@ -36382,7 +36382,7 @@ primitive-branch17 (reg proc) (reg argl)) -after-call15 @r{; @t{val} now contains result of @t{(= n 1)}} +after-call15 @r{; @code{val} now contains result of @code{(= n 1)}} (restore env) (restore continue) (test (op false?) (reg val)) @@ -36392,28 +36392,28 @@ true-branch5 @r{; return 1} (goto (reg continue)) false-branch4 -@r{;; compute and return @t{(* (factorial (- n 1)) n)}} +@r{;; compute and return @code{(* (factorial (- n 1)) n)}} (assign proc (op lookup-variable-value) (const *) (reg env)) (save continue) - (save proc) @r{; save @t{*}} procedure + (save proc) @r{; save @code{*}} procedure (assign val (op lookup-variable-value) (const n) (reg env)) (assign argl (op list) (reg val)) - (save argl) @r{; save partial argument list for @t{*}} + (save argl) @r{; save partial argument list for @code{*}} -@r{;; compute @t{(factorial (- n 1))},} -@r{;; which is the other argument for @t{*}} +@r{;; compute @code{(factorial (- n 1))},} +@r{;; which is the other argument for @code{*}} (assign proc (op lookup-variable-value) (const factorial) (reg env)) - (save proc) @r{; save @t{factorial} procedure} -@r{;; compute @t{(- n 1)}, which is the argument for @t{factorial}} + (save proc) @r{; save @code{factorial} procedure} +@r{;; compute @code{(- n 1)}, which is the argument for @code{factorial}} (assign proc (op lookup-variable-value) 8 (const -) @@ -36439,10 +36439,10 @@ primitive-branch8 (reg proc) (reg argl)) -after-call6 @r{; @t{val} now contains result of @t{(- n 1)}} +after-call6 @r{; @code{val} now contains result of @code{(- n 1)}} (assign argl (op list) (reg val)) - (restore proc) @r{; restore @t{factorial}} -@r{;; apply @t{factorial}} + (restore proc) @r{; restore @code{factorial}} +@r{;; apply @code{factorial}} (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch11)) compiled-branch10 @@ -36456,13 +36456,13 @@ primitive-branch11 (op apply-primitive-procedure) (reg proc) (reg argl)) -after-call9 @r{; @t{val} now contains result} - @r{; of @t{(factorial (- n 1))}} - (restore argl) @r{; restore partial argument list for @t{*}} +after-call9 @r{; @code{val} now contains result} + @r{; of @code{(factorial (- n 1))}} + (restore argl) @r{; restore partial argument list for @code{*}} (assign argl (op cons) (reg val) (reg argl)) - (restore proc) @r{; restore @t{*}} + (restore proc) @r{; restore @code{*}} (restore continue) -@r{;; apply @t{*} and return its value} +@r{;; apply @code{*} and return its value} (test (op primitive-procedure?) (reg proc)) (branch (label primitive-branch14)) compiled-branch13 @@ -36481,7 +36481,7 @@ primitive-branch14 after-call12 after-if3 after-lambda1 -@r{;; assign the procedure to the variable @t{factorial}} +@r{;; assign the procedure to the variable @code{factorial}} (perform (op define-variable!) (const factorial) (reg val) @@ -36502,7 +36502,7 @@ of a factorial procedure, which is slightly different from the one given above: @end lisp Compile this procedure and compare the resulting code with that produced for -@t{factorial}. Explain any differences you find. Does either program +@code{factorial}. Explain any differences you find. Does either program execute more efficiently than the other? @end quotation @@ -36521,7 +36521,7 @@ procedure @end lisp Annotate the resulting code, showing the essential difference between the code -for iterative and recursive versions of @t{factorial} that makes one process +for iterative and recursive versions of @code{factorial} that makes one process build up stack space and the other run in constant stack space. @end quotation @@ -36645,12 +36645,12 @@ the argument list? @quotation @strong{@anchor{Exercise 5.37}Exercise 5.37:} One way to understand the -compiler's @t{preserving} mechanism for optimizing stack usage is to see +compiler's @code{preserving} mechanism for optimizing stack usage is to see what extra operations would be generated if we did not use this idea. Modify -@t{preserving} so that it always generates the @t{save} and -@t{restore} operations. Compile some simple expressions and identify the +@code{preserving} so that it always generates the @code{save} and +@code{restore} operations. Compile some simple expressions and identify the unnecessary stack operations that are generated. Compare the code to that -generated with the @t{preserving} mechanism intact. +generated with the @code{preserving} mechanism intact. @end quotation @quotation @@ -36658,9 +36658,9 @@ generated with the @t{preserving} mechanism intact. avoiding unnecessary stack operations, but it is not clever at all when it comes to compiling calls to the primitive procedures of the language in terms of the primitive operations supplied by the machine. For example, consider how -much code is compiled to compute @t{(+ a 1)}: The code sets up an argument -list in @t{argl}, puts the primitive addition procedure (which it finds by -looking up the symbol @t{+} in the environment) into @t{proc}, and tests +much code is compiled to compute @code{(+ a 1)}: The code sets up an argument +list in @code{argl}, puts the primitive addition procedure (which it finds by +looking up the symbol @code{+} in the environment) into @code{proc}, and tests whether the procedure is primitive or compound. The compiler always generates code to perform the test, as well as code for primitive and compound branches (only one of which will be executed). We have not shown the part of the @@ -36668,9 +36668,9 @@ controller that implements primitives, but we presume that these instructions make use of primitive arithmetic operations in the machine's data paths. Consider how much less code would be generated if the compiler could @newterm{open-code} primitives---that is, if it could generate code to directly -use these primitive machine operations. The expression @t{(+ a 1)} might be +use these primitive machine operations. The expression @code{(+ a 1)} might be compiled into something as simple as @footnote{We have used the same symbol -@t{+} here to denote both the source-language procedure and the machine +@code{+} here to denote both the source-language procedure and the machine operation. In general there will not be a one-to-one correspondence between primitives of the source language and primitives of the machine.} @@ -36687,13 +36687,13 @@ In this exercise we will extend our compiler to support open coding of selected primitives. Special-purpose code will be generated for calls to these primitive procedures instead of the general procedure-application code. In order to support this, we will augment our machine with special argument -registers @t{arg1} and @t{arg2}. The primitive arithmetic operations of -the machine will take their inputs from @t{arg1} and @t{arg2}. The -results may be put into @t{val}, @t{arg1}, or @t{arg2}. +registers @code{arg1} and @code{arg2}. The primitive arithmetic operations of +the machine will take their inputs from @code{arg1} and @code{arg2}. The +results may be put into @code{val}, @code{arg1}, or @code{arg2}. The compiler must be able to recognize the application of an open-coded primitive in the source program. We will augment the dispatch in the -@t{compile} procedure to recognize the names of these primitives in addition +@code{compile} procedure to recognize the names of these primitives in addition to the reserved words (the special forms) it currently recognizes.@footnote{Making the primitives into reserved words is in general a bad idea, since a user cannot then rebind these names to different procedures. @@ -36707,26 +36707,26 @@ family of code generators for the open-coded primitives. @item The open-coded primitives, unlike the special forms, all need their operands -evaluated. Write a code generator @t{spread-@/arguments} for use by all the -open-coding code generators. @t{Spread-@/arguments} should take an operand +evaluated. Write a code generator @code{spread-@/arguments} for use by all the +open-coding code generators. @code{Spread-@/arguments} should take an operand list and compile the given operands targeted to successive argument registers. Note that an operand may contain a call to an open-coded primitive, so argument registers will have to be preserved during operand evaluation. @item -For each of the primitive procedures @t{=}, @t{*}, @t{-}, and -@t{+}, write a code generator that takes a combination with that operator, +For each of the primitive procedures @code{=}, @code{*}, @code{-}, and +@code{+}, write a code generator that takes a combination with that operator, together with a target and a linkage descriptor, and produces code to spread the arguments into the registers and then perform the operation targeted to the given target with the given linkage. You need only handle expressions with two -operands. Make @t{compile} dispatch to these code generators. +operands. Make @code{compile} dispatch to these code generators. @item -Try your new compiler on the @t{factorial} example. Compare the resulting +Try your new compiler on the @code{factorial} example. Compare the resulting code with the result produced without open coding. @item -Extend your code generators for @t{+} and @t{*} so that they can handle +Extend your code generators for @code{+} and @code{*} so that they can handle expressions with arbitrary numbers of operands. An expression with more than two operands will have to be compiled into a sequence of operations, each with only two inputs. @@ -36739,12 +36739,12 @@ only two inputs. One of the most common optimizations performed by compilers is the optimization of variable lookup. Our compiler, as we have implemented it so far, generates -code that uses the @t{lookup-variable-value} operation of the evaluator +code that uses the @code{lookup-variable-value} operation of the evaluator machine. This searches for a variable by comparing it with each variable that is currently bound, working frame by frame outward through the run-time environment. This search can be expensive if the frames are deeply nested or if there are many variables. For example, consider the problem of looking up -the value of @t{x} while evaluating the expression @t{(* x y z)} in an +the value of @code{x} while evaluating the expression @code{(* x y z)} in an application of the procedure that is returned by @endpage @@ -36757,7 +36757,7 @@ application of the procedure that is returned by @end lisp @noindent -Since a @t{let} expression is just syntactic sugar for a @t{lambda} +Since a @code{let} expression is just syntactic sugar for a @code{lambda} combination, this expression is equivalent to @lisp @@ -36771,40 +36771,40 @@ combination, this expression is equivalent to @end lisp @noindent -Each time @t{lookup-variable-value} searches for @t{x}, it must determine -that the symbol @t{x} is not @t{eq?} to @t{y} or @t{z} (in the -first frame), nor to @t{a}, @t{b}, @t{c}, @t{d}, or @t{e} (in +Each time @code{lookup-variable-value} searches for @code{x}, it must determine +that the symbol @code{x} is not @code{eq?} to @code{y} or @code{z} (in the +first frame), nor to @code{a}, @code{b}, @code{c}, @code{d}, or @code{e} (in the second frame). We will assume, for the moment, that our programs do not -use @t{define}---that variables are bound only with @t{lambda}. Because +use @code{define}---that variables are bound only with @code{lambda}. Because our language is lexically scoped, the run-time environment for any expression will have a structure that parallels the lexical structure of the program in which the expression appears.@footnote{This is not true if we allow internal definitions, unless we scan them out. See @ref{Exercise 5.43}. } Thus, the compiler can know, when it analyzes the above expression, that each time the -procedure is applied the variable @t{x} in @t{(* x y z)} will be found +procedure is applied the variable @code{x} in @code{(* x y z)} will be found two frames out from the current frame and will be the first variable in that frame. We can exploit this fact by inventing a new kind of variable-@/lookup operation, -@t{lexical-@/address-@/lookup}, that takes as arguments an environment and a +@code{lexical-@/address-@/lookup}, that takes as arguments an environment and a @newterm{lexical address} that consists of two numbers: a @newterm{frame number}, which specifies how many frames to pass over, and a @newterm{displacement number}, which specifies how many variables to pass over -in that frame. @t{Lexical-@/address-@/lookup} will produce the value of the +in that frame. @code{Lexical-@/address-@/lookup} will produce the value of the variable stored at that lexical address relative to the current environment. -If we add the @t{lexical-@/address-@/lookup} operation to our machine, we can +If we add the @code{lexical-@/address-@/lookup} operation to our machine, we can make the compiler generate code that references variables using this operation, -rather than @t{lookup-@/variable-@/value}. Similarly, our compiled code can use -a new @t{lexical-@/address-@/set!} operation instead of -@t{set-@/variable-@/value!}. +rather than @code{lookup-@/variable-@/value}. Similarly, our compiled code can use +a new @code{lexical-@/address-@/set!} operation instead of +@code{set-@/variable-@/value!}. In order to generate such code, the compiler must be able to determine the lexical address of a variable it is about to compile a reference to. The lexical address of a variable in a program depends on where one is in the code. -For example, in the following program, the address of @t{x} in expression +For example, in the following program, the address of @code{x} in expression @math{\langle}@var{e1}@math{\kern0.08em\rangle} is (2, 0)---two frames back and the first variable in the frame. At -that point @t{y} is at address (0, 0) and @t{c} is at address (1, 2). In -expression @math{\langle}@var{e2}@math{\kern0.09em\rangle}, @t{x} is at (1, 0), @t{y} is at (1, 1), and @t{c} +that point @code{y} is at address (0, 0) and @code{c} is at address (1, 2). In +expression @math{\langle}@var{e2}@math{\kern0.09em\rangle}, @code{x} is at (1, 0), @code{y} is at (1, 1), and @code{c} is at (0, 2). @lisp @@ -36825,13 +36825,13 @@ the run-time environment when a particular variable-access operation is executed. The compile-time environment is a list of frames, each containing a list of variables. (There will of course be no values bound to the variables, since values are not computed at compile time.) The compile-time environment -becomes an additional argument to @t{compile} and is passed along to each -code generator. The top-level call to @t{compile} uses an empty -compile-time environment. When a @t{lambda} body is compiled, -@t{compile-lambda-body} extends the compile-time environment by a frame +becomes an additional argument to @code{compile} and is passed along to each +code generator. The top-level call to @code{compile} uses an empty +compile-time environment. When a @code{lambda} body is compiled, +@code{compile-lambda-body} extends the compile-time environment by a frame containing the procedure's parameters, so that the sequence making up the body is compiled with that extended environment. At each point in the compilation, -@t{compile-variable} and @t{compile-assignment} use the compile-time +@code{compile-variable} and @code{compile-assignment} use the compile-time environment in order to generate the appropriate lexical addresses. @ref{Exercise 5.39} through @ref{Exercise 5.43} describe how to complete this @@ -36841,32 +36841,32 @@ compile-time environment. @quotation @strong{@anchor{Exercise 5.39}Exercise 5.39:} Write a procedure -@t{lexical-@/address-@/lookup} that implements the new lookup operation. It +@code{lexical-@/address-@/lookup} that implements the new lookup operation. It should take two arguments---a lexical address and a run-time environment---and return the value of the variable stored at the specified lexical address. -@t{Lexical-@/address-@/lookup} should signal an error if the value of the -variable is the symbol @t{*unassigned*}.@footnote{This is the modification +@code{Lexical-@/address-@/lookup} should signal an error if the value of the +variable is the symbol @code{*unassigned*}.@footnote{This is the modification to variable lookup required if we implement the scanning method to eliminate internal definitions (@ref{Exercise 5.43}). We will need to eliminate these definitions in order for lexical addressing to work.} Also write a procedure -@t{lexical-@/address-@/set!} that implements the operation that changes the +@code{lexical-@/address-@/set!} that implements the operation that changes the value of the variable at a specified lexical address. @end quotation @quotation @strong{@anchor{Exercise 5.40}Exercise 5.40:} Modify the compiler to maintain the compile-time environment as described above. That is, add a -compile-time-environment argument to @t{compile} and the various code -generators, and extend it in @t{compile-lambda-body}. +compile-time-environment argument to @code{compile} and the various code +generators, and extend it in @code{compile-lambda-body}. @end quotation @quotation @strong{@anchor{Exercise 5.41}Exercise 5.41:} Write a procedure -@t{find-variable} that takes as arguments a variable and a compile-time +@code{find-variable} that takes as arguments a variable and a compile-time environment and returns the lexical address of the variable with respect to that environment. For example, in the program fragment that is shown above, the compile-time environment during the compilation of expression @math{\langle}@var{e1}@math{\rangle} is -@t{((y z) (a b c d e) (x y))}. @t{Find-variable} should produce +@code{((y z) (a b c d e) (x y))}. @code{Find-variable} should produce @lisp (find-variable @@ -36884,10 +36884,10 @@ the compile-time environment during the compilation of expression @math{\langle} @end quotation @quotation -@strong{@anchor{Exercise 5.42}Exercise 5.42:} Using @t{find-variable} from -@ref{Exercise 5.41}, rewrite @t{compile-@/variable} and -@t{compile-@/assignment} to output lexical-address instructions. In cases -where @t{find-variable} returns @t{not-found} (that is, where the +@strong{@anchor{Exercise 5.42}Exercise 5.42:} Using @code{find-variable} from +@ref{Exercise 5.41}, rewrite @code{compile-@/variable} and +@code{compile-@/assignment} to output lexical-address instructions. In cases +where @code{find-variable} returns @code{not-found} (that is, where the variable is not in the compile-time environment), you should have the code generators use the evaluator operations, as before, to search for the binding. (The only place a variable that is not found at compile time can be is in the @@ -36900,18 +36900,18 @@ those at top level, which act on the global environment. Compilation of a definition does not cause the defined name to be entered in the compile-time environment.} Thus, if you wish, you may have the evaluator operations look directly in the global environment, which can be obtained with the operation -@t{(op get-global-environment)}, instead of having them search the whole -run-time environment found in @t{env}.) Test the modified compiler on a few -simple cases, such as the nested @t{lambda} combination at the beginning of +@code{(op get-global-environment)}, instead of having them search the whole +run-time environment found in @code{env}.) Test the modified compiler on a few +simple cases, such as the nested @code{lambda} combination at the beginning of this section. @end quotation @quotation @strong{@anchor{Exercise 5.43}Exercise 5.43:} We argued in @ref{4.1.6} that internal definitions for block structure should not be considered ``real'' -@t{define}s. Rather, a procedure body should be interpreted as if the -internal variables being defined were installed as ordinary @t{lambda} -variables initialized to their correct values using @t{set!}. +@code{define}s. Rather, a procedure body should be interpreted as if the +internal variables being defined were installed as ordinary @code{lambda} +variables initialized to their correct values using @code{set!}. @ref{4.1.6} and @ref{Exercise 4.16} showed how to modify the metacircular interpreter to accomplish this by scanning out internal definitions. Modify the compiler to perform the same transformation before it compiles a procedure @@ -36934,14 +36934,14 @@ primitive, ignoring the new binding. For example, consider the procedure @end lisp @noindent -which computes a linear combination of @t{x} and @t{y}. We might call it -with arguments @t{+matrix}, @t{*matrix}, and four matrices, but the -open-coding compiler would still open-code the @t{+} and the @t{*} in -@t{(+ (* a x) (* b y))} as primitive @t{+} and @t{*}. Modify the +which computes a linear combination of @code{x} and @code{y}. We might call it +with arguments @code{+matrix}, @code{*matrix}, and four matrices, but the +open-coding compiler would still open-code the @code{+} and the @code{*} in +@code{(+ (* a x) (* b y))} as primitive @code{+} and @code{*}. Modify the open-coding compiler to consult the compile-time environment in order to compile the correct code for expressions involving the names of primitive procedures. (The code will work correctly as long as the program does not -@t{define} or @t{set!} these names.) +@code{define} or @code{set!} these names.) @end quotation @endpage @@ -36952,7 +36952,7 @@ We have not yet explained how to load compiled code into the evaluator machine or how to run it. We will assume that the explicit-control-evaluator machine has been defined as in @ref{5.4.4}, with the additional operations specified in @ref{Footnote 38}. We will implement a procedure -@t{compile-and-go} that compiles a Scheme expression, loads the resulting +@code{compile-and-go} that compiles a Scheme expression, loads the resulting object code into the evaluator machine, and causes the machine to run the code in the evaluator global environment, print the result, and enter the evaluator's driver loop. We will also modify the evaluator so that interpreted @@ -36976,8 +36976,8 @@ it: @noindent To allow the evaluator to handle compiled procedures (for example, to evaluate -the call to @t{factorial} above), we need to change the code at -@t{apply-dispatch} (@ref{5.4.1}) so that it recognizes compiled +the call to @code{factorial} above), we need to change the code at +@code{apply-dispatch} (@ref{5.4.1}) so that it recognizes compiled procedures (as distinct from compound or primitive procedures) and transfers control directly to the entry point of the compiled code:@footnote{Of course, compiled procedures as well as interpreted procedures are compound @@ -37004,17 +37004,17 @@ compiled-apply @end lisp @noindent -Note the restore of @t{continue} at @t{compiled-apply}. Recall that the -evaluator was arranged so that at @t{apply-dispatch}, the continuation would +Note the restore of @code{continue} at @code{compiled-apply}. Recall that the +evaluator was arranged so that at @code{apply-dispatch}, the continuation would be at the top of the stack. The compiled code entry point, on the other hand, -expects the continuation to be in @t{continue}, so @t{continue} must be +expects the continuation to be in @code{continue}, so @code{continue} must be restored before the compiled code is executed. To enable us to run some compiled code when we start the evaluator machine, we -add a @t{branch} instruction at the beginning of the evaluator machine, -which causes the machine to go to a new entry point if the @t{flag} register -is set.@footnote{Now that the evaluator machine starts with a @t{branch}, we -must always initialize the @t{flag} register before starting the evaluator +add a @code{branch} instruction at the beginning of the evaluator machine, +which causes the machine to go to a new entry point if the @code{flag} register +is set.@footnote{Now that the evaluator machine starts with a @code{branch}, we +must always initialize the @code{flag} register before starting the evaluator machine. To start the machine at its ordinary read-eval-print loop, we could use @@ -37028,7 +37028,7 @@ use } @lisp -@r{;; branches if @t{flag} is set:} +@r{;; branches if @code{flag} is set:} (branch (label external-entry)) read-eval-print-loop (perform (op initialize-stack)) @@ -37036,15 +37036,15 @@ read-eval-print-loop @end lisp @noindent -@t{External-entry} assumes that the machine is started with @t{val} +@code{External-entry} assumes that the machine is started with @code{val} containing the location of an instruction sequence that puts a result into -@t{val} and ends with @t{(goto (reg continue))}. Starting at this entry -point jumps to the location designated by @t{val}, but first assigns -@t{continue} so that execution will return to @t{print-result}, which -prints the value in @t{val} and then goes to the beginning of the +@code{val} and ends with @code{(goto (reg continue))}. Starting at this entry +point jumps to the location designated by @code{val}, but first assigns +@code{continue} so that execution will return to @code{print-result}, which +prints the value in @code{val} and then goes to the beginning of the evaluator's read-eval-print loop.@footnote{Since a compiled procedure is an object that the system may try to print, we also modify the system print -operation @t{user-print} (from @ref{4.1.4}) so that it will not +operation @code{user-print} (from @ref{4.1.4}) so that it will not attempt to print the components of a compiled procedure: @lisp @@ -37073,13 +37073,13 @@ external-entry Now we can use the following procedure to compile a procedure definition, execute the compiled code, and run the read-eval-print loop so we can try the procedure. Because we want the compiled code to return to the location in -@t{continue} with its result in @t{val}, we compile the expression with a -target of @t{val} and a linkage of @t{return}. In order to transform the +@code{continue} with its result in @code{val}, we compile the expression with a +target of @code{val} and a linkage of @code{return}. In order to transform the object code produced by the compiler into executable instructions for the -evaluator register machine, we use the procedure @t{assemble} from the +evaluator register machine, we use the procedure @code{assemble} from the register-machine simulator (@ref{5.2.2}). We then initialize the -@t{val} register to point to the list of instructions, set the @t{flag} -so that the evaluator will go to @t{external-entry}, and start the +@code{val} register to point to the list of instructions, set the @code{flag} +so that the evaluator will go to @code{external-entry}, and start the evaluator. @lisp @@ -37120,7 +37120,7 @@ can examine the stack usage of compiled code: @end lisp @noindent -Compare this example with the evaluation of @t{(factorial 5)} using the +Compare this example with the evaluation of @code{(factorial 5)} using the interpreted version of the same procedure, shown at the end of @ref{5.4.4}. The interpreted version required 144 pushes and a maximum stack depth of 28. This illustrates the optimization that results from our @@ -37205,7 +37205,7 @@ of pushes and the maximum stack depth needed by the evaluator to compute @math{n using the recursive factorial procedure given above. @ref{Exercise 5.14} asked you to do the same measurements for the special-purpose factorial machine shown in @ref{Figure 5.11}. Now perform the same analysis using the compiled -@t{factorial} procedure. +@code{factorial} procedure. Take the ratio of the number of pushes in the compiled version to the number of pushes in the interpreted version, and do the same for the maximum stack depth. @@ -37254,34 +37254,34 @@ modify the explicit-control evaluator so that interpreted code can call compiled procedures. Show how to modify the compiler so that compiled procedures can call not only primitive procedures and compiled procedures, but interpreted procedures as well. This requires modifying -@t{compile-procedure-call} to handle the case of compound (interpreted) -procedures. Be sure to handle all the same @t{target} and @t{linkage} -combinations as in @t{compile-proc-appl}. To do the actual procedure -application, the code needs to jump to the evaluator's @t{compound-apply} +@code{compile-procedure-call} to handle the case of compound (interpreted) +procedures. Be sure to handle all the same @code{target} and @code{linkage} +combinations as in @code{compile-proc-appl}. To do the actual procedure +application, the code needs to jump to the evaluator's @code{compound-apply} entry point. This label cannot be directly referenced in object code (since the assembler requires that all labels referenced by the code it is assembling -be defined there), so we will add a register called @t{compapp} to the +be defined there), so we will add a register called @code{compapp} to the evaluator machine to hold this entry point, and add an instruction to initialize it: @lisp (assign compapp (label compound-apply)) - @r{;; branches if @t{flag} is set:} + @r{;; branches if @code{flag} is set:} (branch (label external-entry)) read-eval-print-loop @dots{} @end lisp -To test your code, start by defining a procedure @t{f} that calls a -procedure @t{g}. Use @t{compile-and-go} to compile the definition of -@t{f} and start the evaluator. Now, typing at the evaluator, define -@t{g} and try to call @t{f}. +To test your code, start by defining a procedure @code{f} that calls a +procedure @code{g}. Use @code{compile-and-go} to compile the definition of +@code{f} and start the evaluator. Now, typing at the evaluator, define +@code{g} and try to call @code{f}. @end quotation @quotation -@strong{@anchor{Exercise 5.48}Exercise 5.48:} The @t{compile-and-go} +@strong{@anchor{Exercise 5.48}Exercise 5.48:} The @code{compile-and-go} interface implemented in this section is awkward, since the compiler can be called only once (when the evaluator machine is started). Augment the -compiler-interpreter interface by providing a @t{compile-@/and-@/run} primitive +compiler-interpreter interface by providing a @code{compile-@/and-@/run} primitive that can be called from within the explicit-control evaluator as follows: @lisp @@ -37306,15 +37306,15 @@ explicit-control evaluator's read-eval-print loop, design a register machine that performs a read-compile-execute-print loop. That is, the machine should run a loop that reads an expression, compiles it, assembles and executes the resulting code, and prints the result. This is easy to run in our simulated -setup, since we can arrange to call the procedures @t{compile} and -@t{assemble} as ``register-machine operations.'' +setup, since we can arrange to call the procedures @code{compile} and +@code{assemble} as ``register-machine operations.'' @end quotation @quotation @strong{@anchor{Exercise 5.50}Exercise 5.50:} Use the compiler to compile the metacircular evaluator of @ref{4.1} and run this program using the register-machine simulator. (To compile more than one definition at a time, -you can package the definitions in a @t{begin}.) The resulting interpreter +you can package the definitions in a @code{begin}.) The resulting interpreter will run very slowly because of the multiple levels of interpretation, but getting all the details to work is an instructive exercise. @end quotation @@ -37342,7 +37342,7 @@ Abelson, Harold, Andrew Berlin, Jacob Katzenelson, William McAllister, Guillermo Rozas, Gerald Jay Sussman, and Jack Wisdom. 1992. The Super@-com@-pu@-ter Tool@-kit: A general framework for special-purpose com@-pu@-ting. @cite{In@-ter@-na@-tio@-nal Journal of High-Speed Electronics} 3(3): 337-361. -@url{http://www.hpl.hp.com/techreports/94/HPL-94-30.html, @t{(Online)}} +@url{http://www.hpl.hp.com/techreports/94/HPL-94-30.html, @code{(Online)}} @anchor{Allen 1978} Allen, John. 1978. @cite{Anatomy of Lisp}. New York: McGraw-Hill. @@ -37354,17 +37354,17 @@ Systems@/---Programming Language---Common Lisp}. @anchor{Appel 1987} Appel, Andrew W. 1987. Garbage collection can be faster than stack allocation. @cite{Information Processing Letters} 25(4): 275-279. -@url{http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.8219, @t{(Online)}} +@url{http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.8219, @code{(Online)}} @anchor{Backus 1978} Backus, John. 1978. Can programming be liberated from the von Neumann style? @cite{Communications of the @acronym{ACM}} 21(8): 613-641. -@url{http://www.stanford.edu/class/cs242/readings/backus.pdf, @t{(Online)}} +@url{http://www.stanford.edu/class/cs242/readings/backus.pdf, @code{(Online)}} @anchor{Baker (1978)} Baker, Henry G., Jr. 1978. List processing in real time on a serial computer. @cite{Communications of the @acronym{ACM}} 21(4): 280-293. -@url{http://dspace.mit.edu/handle/1721.1/41976, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/41976, @code{(Online)}} @anchor{Batali et al. 1982} Batali, John, Neil Mayle, Howard Shrobe, Gerald Jay Sussman, and Daniel Weise. @@ -37376,7 +37376,7 @@ Paul Penfield, Jr. Dedham, MA: Artech House. Borning, Alan. 1977. ThingLab---An object-oriented system for building simulations using constraints. In @cite{Proceedings of the 5th International Joint Conference on Artificial Intelligence}. -@url{http://ijcai.org/Past%20Proceedings/IJCAI-77-VOL1/PDF/085.pdf, @t{(Online)}} +@url{http://ijcai.org/Past%20Proceedings/IJCAI-77-VOL1/PDF/085.pdf, @code{(Online)}} @anchor{Borodin and Munro (1975)} Borodin, Alan, and Ian Munro. 1975. @cite{The Computational Complexity of @@ -37393,7 +37393,7 @@ N.J.: Princeton University Press. @anchor{Clark (1978)} Clark, Keith L. 1978. Negation as failure. In @cite{Logic and Data Bases}. New York: Plenum Press, pp. 293-322. -@url{http://www.doc.ic.ac.uk/~klc/neg.html, @t{(Online)}} +@url{http://www.doc.ic.ac.uk/~klc/neg.html, @code{(Online)}} @anchor{Clinger (1982)} Clinger, William. 1982. Nondeterministic call by need is neither lazy nor by @@ -37404,7 +37404,7 @@ Functional Programming}, pp. 226-234. Clinger, William, and Jonathan Rees. 1991. Macros that work. In @cite{Proceedings of the 1991 @acronym{ACM} Conference on Principles of Programming Languages}, pp. 155-162. -@url{http://mumble.net/~jar/pubs/macros_that_work.ps, @t{(Online)}} +@url{http://mumble.net/~jar/pubs/macros_that_work.ps, @code{(Online)}} @anchor{Colmerauer et al. 1973} Colmerauer A., H. Kanoui, R. Pasero, and P. Roussel. 1973. Un syst@`eme de @@ -37423,13 +37423,13 @@ Programming and Its Applications}. New York: Cambridge University Press. Dijkstra, Edsger W. 1968a. The structure of the ``@acronym{THE}'' multiprogramming system. @cite{Communications of the @acronym{ACM}} 11(5): 341-346. -@url{http://www.cs.utexas.edu/users/EWD/ewd01xx/EWD196.PDF, @t{(Online)}} +@url{http://www.cs.utexas.edu/users/EWD/ewd01xx/EWD196.PDF, @code{(Online)}} @anchor{1968b} Dijkstra, Edsger W. 1968b. Cooperating sequential processes. In @cite{Programming Languages}, edited by F. Genuys. New York: Academic Press, pp. 43-112. -@url{http://www.cs.utexas.edu/users/EWD/ewd01xx/EWD123.PDF, @t{(Online)}} +@url{http://www.cs.utexas.edu/users/EWD/ewd01xx/EWD123.PDF, @code{(Online)}} @anchor{Dinesman 1968} Dinesman, Howard P. 1968. @cite{Superior Mathematical Puzzles}. New York: @@ -37440,12 +37440,12 @@ deKleer, Johan, Jon Doyle, Guy Steele, and Gerald J. Sussman. 1977. @acronym{AMORD}: Explicit control of reasoning. In @cite{Proceedings of the @acronym{ACM} Symposium on Artificial Intelligence and Programming Languages}, pp. 116-125. -@url{http://dspace.mit.edu/handle/1721.1/5750, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/5750, @code{(Online)}} @anchor{Doyle (1979)} Doyle, Jon. 1979. A truth maintenance system. @cite{Artificial Intelligence} 12: 231-272. -@url{http://dspace.mit.edu/handle/1721.1/5733, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/5733, @code{(Online)}} @anchor{Feigenbaum and Shrobe 1993} Feigenbaum, Edward, and Howard Shrobe. 1993. The Japanese National Fifth @@ -37459,7 +37459,7 @@ Scheme. Masters thesis, Universit@'e de Montr@'eal. @anchor{Feeley and Lapalme 1987} Feeley, Marc and Guy Lapalme. 1987. Using closures for code generation. @cite{Journal of Computer Languages} 12(1): 47-66. -@url{http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.90.6978, @t{(Online)}} +@url{http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.90.6978, @code{(Online)}} Feller, William. 1957. @cite{An Introduction to Probability Theory and Its Applications}, volume 1. New York: John Wiley & Sons. @@ -37481,7 +37481,7 @@ Solvers}. Cambridge, MA: @acronym{MIT} Press. Friedman, Daniel P., and David S. Wise. 1976. @acronym{CONS} should not evaluate its arguments. In @cite{Automata, Languages, and Programming: Third International Colloquium}, edited by S. Michaelson and R. Milner, pp. 257-284. -@url{https://www.cs.indiana.edu/cgi-bin/techreports/TRNNN.cgi?trnum=TR44, @t{(Online)}} +@url{https://www.cs.indiana.edu/cgi-bin/techreports/TRNNN.cgi?trnum=TR44, @code{(Online)}} @anchor{Friedman et al. 1992} Friedman, Daniel P., Mitchell Wand, and Christopher T. Haynes. 1992. @@ -37491,7 +37491,7 @@ Press/@/McGraw-Hill. @anchor{Gabriel 1988} Gabriel, Richard P. 1988. The Why of @emph{Y}. @cite{Lisp Pointers} 2(2): 15-25. -@url{http://www.dreamsongs.com/Files/WhyOfY.pdf, @t{(Online)}} +@url{http://www.dreamsongs.com/Files/WhyOfY.pdf, @code{(Online)}} Goldberg, Adele, and David Robson. 1983. @cite{Smalltalk-80: The Language and Its Implementation}. Reading, MA: Addison-Wesley. @@ -37509,7 +37509,7 @@ Models}. San Mateo, CA: Morgan-Kaufman. Green, Cordell. 1969. Application of theorem proving to problem solving. In @cite{Proceedings of the International Joint Conference on Artificial Intelligence}, pp. 219-240. -@url{http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.81.9820, @t{(Online)}} +@url{http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.81.9820, @code{(Online)}} @anchor{Green and Raphael (1968)} Green, Cordell, and Bertram Raphael. 1968. The use of theorem-proving @@ -37523,7 +37523,7 @@ Symbolic Computation Group Operating Note 58, University of Utah. @anchor{Guttag 1977} Guttag, John V. 1977. Abstract data types and the development of data structures. @cite{Communications of the @acronym{ACM}} 20(6): 396-404. -@url{http://www-sst.informatik.tu-cottbus.de/~db/doc/People/Broy/Software-Pioneers/Guttag_hist.pdf, @t{(Online)}} +@url{http://www-sst.informatik.tu-cottbus.de/~db/doc/People/Broy/Software-Pioneers/Guttag_hist.pdf, @code{(Online)}} @anchor{Hamming 1980} Hamming, Richard W. 1980. @cite{Coding and Information Theory}. Englewood @@ -37537,7 +37537,7 @@ Functional Programming}, pp. 106-118. @anchor{Hanson 1991} Hanson, Christopher P. 1991. A syntactic closures macro facility. @cite{Lisp Pointers}, 4(3). -@url{ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/prop/synclo.ps.gz, @t{(Online)}} +@url{ftp://ftp.cs.indiana.edu/pub/scheme-repository/doc/prop/synclo.ps.gz, @code{(Online)}} @anchor{Hardy 1921} Hardy, Godfrey H. 1921. Srinivasa Ramanujan. @cite{Proceedings of the London @@ -37562,19 +37562,19 @@ Implementation}. Englewood Cliffs, N.J.: Prentice-Hall. @anchor{Henderson 1982} Henderson. Peter. 1982. Functional Geometry. In @cite{Conference Record of the 1982 @acronym{ACM} Symposium on Lisp and Functional Programming}, pp. 179-187. -@url{http://users.ecs.soton.ac.uk/ph/funcgeo.pdf, @t{(Online)}} -@url{http://users.ecs.soton.ac.uk/ph/papers/funcgeo2.pdf, @t{(2002 version)}} +@url{http://users.ecs.soton.ac.uk/ph/funcgeo.pdf, @code{(Online)}} +@url{http://users.ecs.soton.ac.uk/ph/papers/funcgeo2.pdf, @code{(2002 version)}} @anchor{Hewitt (1969)} Hewitt, Carl E. 1969. @acronym{PLANNER}: A language for proving theorems in robots. In @cite{Proceedings of the International Joint Conference on Artificial Intelligence}, pp. 295-301. -@url{http://dspace.mit.edu/handle/1721.1/6171, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6171, @code{(Online)}} @anchor{Hewitt (1977)} Hewitt, Carl E. 1977. Viewing control structures as patterns of passing messages. @cite{Journal of Artificial Intelligence} 8(3): 323-364. -@url{http://dspace.mit.edu/handle/1721.1/6272, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6272, @code{(Online)}} @anchor{Hoare (1972)} Hoare, C. A. R. 1972. Proof of correctness of data representations. @@ -37592,7 +37592,7 @@ Braid}. New York: Basic Books. Hughes, R. J. M. 1990. Why functional programming matters. In @cite{Research Topics in Functional Programming}, edited by David Turner. Reading, MA: Addison-Wesley, pp. 17-42. -@url{http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf, @t{(Online)}} +@url{http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf, @code{(Online)}} @anchor{IEEE 1990} @acronym{IEEE} Std 1178-1990. 1990. @cite{@acronym{IEEE} Standard for the @@ -37619,7 +37619,7 @@ Art of Computer Programming}. 2nd edition. Reading, MA: Addison-Wesley. @anchor{Kohlbecker 1986} Kohlbecker, Eugene Edmund, Jr. 1986. Syntactic extensions in the programming language Lisp. Ph.D. thesis, Indiana University. -@url{http://www.ccs.neu.edu/scheme/pubs/dissertation-kohlbecker.pdf, @t{(Online)}} +@url{http://www.ccs.neu.edu/scheme/pubs/dissertation-kohlbecker.pdf, @code{(Online)}} @anchor{Konopasek and Jayaraman 1984} Konopasek, Milos, and Sundaresan Jayaraman. 1984. @cite{The TK!Solver Book: A @@ -37630,7 +37630,7 @@ Education}. Berkeley, CA: Osborne/McGraw-Hill. Kowalski, Robert. 1973. Predicate logic as a programming language. Technical report 70, Department of Computational Logic, School of Artificial Intelligence, University of Edinburgh. -@url{http://www.doc.ic.ac.uk/~rak/papers/IFIP%2074.pdf, @t{(Online)}} +@url{http://www.doc.ic.ac.uk/~rak/papers/IFIP%2074.pdf, @code{(Online)}} Kowalski, Robert. 1979. @cite{Logic for Problem Solving}. New York: North-Holland. @@ -37638,13 +37638,13 @@ North-Holland. @anchor{Lamport (1978)} Lamport, Leslie. 1978. Time, clocks, and the ordering of events in a distributed system. @cite{Communications of the @acronym{ACM}} 21(7): 558-565. -@url{http://www.stanford.edu/class/cs240/readings/lamport.pdf, @t{(Online)}} +@url{http://www.stanford.edu/class/cs240/readings/lamport.pdf, @code{(Online)}} @anchor{Lampson et al. 1981} Lampson, Butler, J. J. Horning, R. London, J. G. Mitchell, and G. K. Popek. 1981. Report on the programming language Euclid. Technical report, Computer Systems Research Group, University of Toronto. -@url{http://www.bitsavers.org/pdf/xerox/parc/techReports/CSL-81-12_Report_On_The_Programming_Language_Euclid.pdf, @t{(Online)}} +@url{http://www.bitsavers.org/pdf/xerox/parc/techReports/CSL-81-12_Report_On_The_Programming_Language_Euclid.pdf, @code{(Online)}} @anchor{Landin (1965)} Landin, Peter. 1965. A correspondence between Algol 60 and Church's lambda @@ -37654,72 +37654,72 @@ notation: Part I. @cite{Communications of the @acronym{ACM}} 8(2): 89-101. Lieberman, Henry, and Carl E. Hewitt. 1983. A real-time garbage collector based on the lifetimes of objects. @cite{Communications of the @acronym{ACM}} 26(6): 419-429. -@url{http://dspace.mit.edu/handle/1721.1/6335, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6335, @code{(Online)}} @anchor{Liskov and Zilles (1975)} Liskov, Barbara H., and Stephen N. Zilles. 1975. Specification techniques for data abstractions. @cite{@acronym{IEEE} Transactions on Software Engineering} 1(1): 7-19. -@url{http://csg.csail.mit.edu/CSGArchives/memos/Memo-117.pdf, @t{(Online)}} +@url{http://csg.csail.mit.edu/CSGArchives/memos/Memo-117.pdf, @code{(Online)}} @anchor{McAllester (1978; 1980)} McAllester, David Allen. 1978. A three-valued truth-maintenance system. Memo 473, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://dspace.mit.edu/handle/1721.1/6296, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6296, @code{(Online)}} McAllester, David Allen. 1980. An outlook on truth maintenance. Memo 551, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://dspace.mit.edu/handle/1721.1/6327, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6327, @code{(Online)}} @anchor{McCarthy 1960} McCarthy, John. 1960. Recursive functions of symbolic expressions and their computation by machine. @cite{Communications of the @acronym{ACM}} 3(4): 184-195. -@url{http://www-formal.stanford.edu/jmc/recursive.html, @t{(Online)}} +@url{http://www-formal.stanford.edu/jmc/recursive.html, @code{(Online)}} @anchor{McCarthy 1967} McCarthy, John. 1967. A basis for a mathematical theory of computation. In @cite{Computer Programming and Formal Systems}, edited by P. Braffort and D. Hirschberg. North-Holland. -@url{http://www-formal.stanford.edu/jmc/basis.html, @t{(Online)}} +@url{http://www-formal.stanford.edu/jmc/basis.html, @code{(Online)}} @anchor{McCarthy 1978} McCarthy, John. 1978. The history of Lisp. In @cite{Proceedings of the @acronym{ACM} @acronym{SIGPLAN} Conference on the History of Programming Languages}. -@url{http://www-formal.stanford.edu/jmc/history/lisp.html, @t{(Online)}} +@url{http://www-formal.stanford.edu/jmc/history/lisp.html, @code{(Online)}} @anchor{McCarthy et al. 1965} McCarthy, John, P. W. Abrahams, D. J. Edwards, T. P. Hart, and M. I. Levin. 1965. @cite{Lisp 1.5 Programmer's Manual}. 2nd edition. Cambridge, MA: @acronym{MIT} Press. -@url{http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Prog@/rammers%20Manual.pdf/view, @t{(Online)}} +@url{http://www.softwarepreservation.org/projects/LISP/book/LISP%201.5%20Prog@/rammers%20Manual.pdf/view, @code{(Online)}} @anchor{McDermott and Sussman (1972)} McDermott, Drew, and Gerald Jay Sussman. 1972. Conniver reference manual. Memo 259, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://dspace.mit.edu/handle/1721.1/6203, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6203, @code{(Online)}} @anchor{Miller 1976} Miller, Gary L. 1976. Riemann's Hypothesis and tests for primality. @cite{Journal of Computer and System Sciences} 13(3): 300-317. -@url{http://www.cs.cmu.edu/~glmiller/Publications/b2hd-Mi76.html, @t{(Online)}} +@url{http://www.cs.cmu.edu/~glmiller/Publications/b2hd-Mi76.html, @code{(Online)}} @anchor{Miller and Rozas 1994} Miller, James S., and Guillermo J. Rozas. 1994. Garbage collection is fast, but a stack is faster. Memo 1462, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://dspace.mit.edu/handle/1721.1/6622, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6622, @code{(Online)}} @anchor{Moon 1978} Moon, David. 1978. MacLisp reference manual, Version 0. Technical report, @acronym{MIT} Laboratory for Computer Science. -@url{http://www.softwarepreservation.org/projects/@/LISP/MIT/Moon-MACLISP_Reference_Manual-Apr_08_1974.pdf/view, @t{(Online)}} +@url{http://www.softwarepreservation.org/projects/@/LISP/MIT/Moon-MACLISP_Reference_Manual-Apr_08_1974.pdf/view, @code{(Online)}} @anchor{Moon and Weinreb 1981} Moon, David, and Daniel Weinreb. 1981. Lisp machine manual. Technical report, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://www.unlambda.com/lmman/index.html, @t{(Online)}} +@url{http://www.unlambda.com/lmman/index.html, @code{(Online)}} @anchor{Morris et al. 1980} Morris, J. H., Eric Schmidt, and Philip Wadler. 1980. Experience with an @@ -37734,7 +37734,7 @@ Faber. @anchor{Pitman 1983} Pitman, Kent. 1983. The revised MacLisp Manual (Saturday evening edition). Technical report 295, @acronym{MIT} Laboratory for Computer Science. -@url{http://maclisp.info/pitmanual, @t{(Online)}} +@url{http://maclisp.info/pitmanual, @code{(Online)}} @anchor{Rabin 1980} Rabin, Michael O. 1980. Probabilistic algorithm for testing primality. @@ -37743,7 +37743,7 @@ Rabin, Michael O. 1980. Probabilistic algorithm for testing primality. @anchor{Raymond 1993} Raymond, Eric. 1993. @cite{The New Hacker's Dictionary}. 2nd edition. Cambridge, MA: @acronym{MIT} Press. -@url{http://www.outpost9.com/reference/jargon/jargon_toc.html, @t{(Online)}} +@url{http://www.outpost9.com/reference/jargon/jargon_toc.html, @code{(Online)}} Raynal, Michel. 1986. @cite{Algorithms for Mutual Exclusion}. Cambridge, MA: @acronym{MIT} Press. @@ -37752,17 +37752,17 @@ Raynal, Michel. 1986. @cite{Algorithms for Mutual Exclusion}. Cambridge, MA: Rees, Jonathan A., and Norman I. Adams IV. 1982. T: A dialect of Lisp or, lambda: The ultimate software tool. In @cite{Conference Record of the 1982 @acronym{ACM} Symposium on Lisp and Functional Programming}, pp. 114-122. -@url{http://people.csail.mit.edu/riastradh/t/adams82t.pdf, @t{(Online)}} +@url{http://people.csail.mit.edu/riastradh/t/adams82t.pdf, @code{(Online)}} Rees, Jonathan, and William Clinger (eds). 1991. The @math{\rm revised^4} report on the algorithmic language Scheme. @cite{Lisp Pointers}, 4(3). -@url{http://people.csail.mit.edu/jaffer/r4rs_toc.html, @t{(Online)}} +@url{http://people.csail.mit.edu/jaffer/r4rs_toc.html, @code{(Online)}} @anchor{Rivest et al. (1977)} Rivest, Ronald, Adi Shamir, and Leonard Adleman. 1977. A method for obtaining digital signatures and public-key cryptosystems. Technical memo LCS/TM82, @acronym{MIT} Laboratory for Computer Science. -@url{http://people.csail.mit.edu/rivest/Rsapaper.pdf, @t{(Online)}} +@url{http://people.csail.mit.edu/rivest/Rsapaper.pdf, @code{(Online)}} @anchor{Robinson 1965} Robinson, J. A. 1965. A machine-oriented logic based on the resolution @@ -37775,13 +37775,13 @@ Robinson, J. A. 1983. Logic programming---Past, present, and future. @anchor{Spafford 1989} Spafford, Eugene H. 1989. The Internet Worm: Crisis and aftermath. @cite{Communications of the @acronym{ACM}} 32(6): 678-688. -@url{http://citeseerx.ist.psu.edu/viewdoc/download?@/doi=10.1.1.123.8503&rep=rep1&type=pdf, @t{(Online)}} +@url{http://citeseerx.ist.psu.edu/viewdoc/download?@/doi=10.1.1.123.8503&rep=rep1&type=pdf, @code{(Online)}} @anchor{Steele 1977} Steele, Guy Lewis, Jr. 1977. Debunking the ``expensive procedure call'' myth. In @cite{Proceedings of the National Conference of the @acronym{ACM}}, pp. 153-62. -@url{http://dspace.mit.edu/handle/1721.1/5753, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/5753, @code{(Online)}} @anchor{Steele 1982} Steele, Guy Lewis, Jr. 1982. An overview of Common Lisp. In @@ -37791,19 +37791,19 @@ Programming}, pp. 98-107. @anchor{Steele 1990} Steele, Guy Lewis, Jr. 1990. @cite{Common Lisp: The Language}. 2nd edition. Digital Press. -@url{http://www.cs.cmu.edu/Groups/AI/html/cltl/cltl2.html, @t{(Online)}} +@url{http://www.cs.cmu.edu/Groups/AI/html/cltl/cltl2.html, @code{(Online)}} @anchor{Steele and Sussman 1975} Steele, Guy Lewis, Jr., and Gerald Jay Sussman. 1975. Scheme: An interpreter for the extended lambda calculus. Memo 349, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://dspace.mit.edu/handle/1721.1/5794, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/5794, @code{(Online)}} @anchor{Steele et al. 1983} Steele, Guy Lewis, Jr., Donald R. Woods, Raphael A. Finkel, Mark R. Crispin, Richard M. Stallman, and Geoffrey S. Goodfellow. 1983. @cite{The Hacker's Dictionary}. New York: Harper & Row. -@url{http://www.dourish.com/goodies/jargon.html, @t{(Online)}} +@url{http://www.dourish.com/goodies/jargon.html, @code{(Online)}} @anchor{Stoy 1977} Stoy, Joseph E. 1977. @cite{Denotational Semantics}. Cambridge, MA: @@ -37813,27 +37813,27 @@ Stoy, Joseph E. 1977. @cite{Denotational Semantics}. Cambridge, MA: Sussman, Gerald Jay, and Richard M. Stallman. 1975. Heuristic techniques in computer-aided circuit analysis. @cite{@acronym{IEEE} Transactions on Circuits and Systems} CAS-22(11): 857-865. -@url{http://dspace.mit.edu/handle/1721.1/5803, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/5803, @code{(Online)}} @anchor{Sussman and Steele 1980} Sussman, Gerald Jay, and Guy Lewis Steele Jr. 1980. Constraints---A language for expressing almost-hierachical descriptions. @cite{AI Journal} 14: 1-39. -@url{http://dspace.mit.edu/handle/1721.1/6312, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6312, @code{(Online)}} @anchor{Sussman and Wisdom 1992} Sussman, Gerald Jay, and Jack Wisdom. 1992. Chaotic evolution of the solar system. @cite{Science} 257: 256-262. -@url{http://groups.csail.mit.edu/mac/users/wisdom/ss-chaos.pdf, @t{(Online)}} +@url{http://groups.csail.mit.edu/mac/users/wisdom/ss-chaos.pdf, @code{(Online)}} @anchor{Sussman et al. (1971)} Sussman, Gerald Jay, Terry Winograd, and Eugene Charniak. 1971. Microplanner reference manual. Memo 203A, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://dspace.mit.edu/handle/1721.1/6184, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/6184, @code{(Online)}} @anchor{Sutherland (1963)} Sutherland, Ivan E. 1963. @acronym{SKETCHPAD}: A man-machine graphical com@-mu@-ni@-cation system. Technical report 296, @acronym{MIT} Lincoln Laboratory. -@url{http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.10.4290, @t{(Online)}} +@url{http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.10.4290, @code{(Online)}} @anchor{Teitelman 1974} Teitelman, Warren. 1974. Interlisp reference manual. Technical report, Xerox @@ -37853,7 +37853,7 @@ in Computer Science, volume 123. New York: Springer-Verlag, pp. 334-348. @anchor{Wand 1980} Wand, Mitchell. 1980. Continuation-based program transformation strategies. @cite{Journal of the @acronym{ACM}} 27(1): 164-180. -@url{http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.83.8567, @t{(Online)}} +@url{http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.83.8567, @code{(Online)}} @anchor{Waters (1979)} Waters, Richard C. 1979. A method for analyzing loop programs. @@ -37862,7 +37862,7 @@ Waters, Richard C. 1979. A method for analyzing loop programs. Winograd, Terry. 1971. Procedures as a representation for data in a computer program for understanding natural language. Technical report AI TR-17, @acronym{MIT} Artificial Intelligence Laboratory. -@url{http://dspace.mit.edu/handle/1721.1/7095, @t{(Online)}} +@url{http://dspace.mit.edu/handle/1721.1/7095, @code{(Online)}} @anchor{Winston 1992} Winston, Patrick. 1992. @cite{Artificial Intelligence}. 3rd edition. Reading, @@ -37872,7 +37872,7 @@ MA: Addison-Wesley. Zabih, Ramin, David McAllester, and David Chapman. 1987. Non-deterministic Lisp with dependency-directed backtracking. @cite{@acronym{AAAI}-87}, pp. 59-64. -@url{http://www.aaai.org/Papers/AAAI/1987/AAAI87-011.pdf, @t{(Online)}} +@url{http://www.aaai.org/Papers/AAAI/1987/AAAI87-011.pdf, @code{(Online)}} @anchor{Zippel (1979)} Zippel, Richard. 1979. Probabilistic algorithms for sparse polynomials. diff --git a/src/texinfo.tex b/src/texinfo.tex index 1490d7d..21874e5 100644 --- a/src/texinfo.tex +++ b/src/texinfo.tex @@ -2461,8 +2461,8 @@ \def\tclose#1{% {% % Change normal interword space to be same as for the current font. - \spaceskip = \fontdimen2\font - % + %\spaceskip = \fontdimen2\font % commented out by A.R because + % % normal space looks too thin for typewriter % Switch to typewriter. \tt %