Chez Scheme Version 9 User's Guide - GitHub Pages

Transcription

Chez Scheme Version 9User’s GuideCisco Systems, Inc.www.cisco.com

2022 Cisco Systems, Inc.Licensed under the Apache License Version ed April 2022 for Chez Scheme Version 9.5.8.Cisco and the Cisco logo are trademarks or registered trademarks of Cisco and/or its affiliates in the U.S. and other countries. To view a list of Cisco trademarks, go to this URL:http://www.cisco.com/go/trademarks. Third-party trademarks mentioned are the property of their respective owners. The use of the word partner does not imply a partnershiprelationship between Cisco and any other company. (1110R)

ContentsPreface1. Introductionix11.1. Chez Scheme Syntax21.2. Notational Conventions41.3. Parameters51.4. More Information62. Using Chez Scheme72.1. Interacting with Chez Scheme72.2. Expression Editor112.3. The Interaction Environment142.4. Using Libraries and Top-Level Programs172.5. Scheme Shell Scripts202.6. Optimization222.7. Customization242.8. Building and Distributing Applications242.9. Command-Line Options303. Debugging333.1. Tracing333.2. The Interactive Debugger403.3. The Interactive Inspector413.4. The Object Inspector47

ivContents3.5. Locating objects533.6. Nested object size and composition544. Foreign Interface574.1. Subprocess Communication574.2. Calling out of Scheme594.3. Calling into Scheme704.4. Continuations and Foreign Calls734.5. Foreign Data744.6. Providing Access to Foreign Procedures894.7. Using Other Foreign Languages934.8. C Library Routines944.9. Example: Socket Operations5. Binding Forms1051135.1. Definitions1135.2. Multiple-value Definitions1145.3. Recursive Bindings1155.4. Fluid Bindings1165.5. Top-Level Bindings1176. Control Structures1236.1. Conditionals1236.2. Mapping and Folding1256.3. Continuations1256.4. Engines1277. Operations on Objects1337.1. Missing R6RS Type Predicates1337.2. Pairs and Lists1337.3. Characters1377.4. Strings139

Contentsv7.5. Vectors1417.6. Fixnum-Only Vectors1437.7. Bytevectors1467.8. Boxes1507.9. Symbols1527.10. Void1577.11. Sorting1577.12. Hashtables1587.13. Record Types1677.14. Record Equality and Hashing1687.15. Legacy Record Types1717.16. Procedures1878. Numeric Operations1898.1. Numeric Type Predicates1908.2. Fixnum Operations1918.3. Flonum Operations1958.4. Inexact Complex Operations1978.5. Bitwise and Logical Operators2008.6. Random Number Generation2088.7. Miscellaneous Numeric Operations2089. Input/Output Operations2139.1. Generic Ports2139.2. File Options2159.3. Transcoders2179.4. Port Operations2189.5. String Ports2279.6. File Ports2299.7. Custom Ports2309.8. Input Operations230

viContents9.9. Output Operations2389.10. Input/Output Operations2439.11. Non-Unicode Bytevector/String Conversions2449.12. Pretty Printing2459.13. Formatted Output2499.14. Input/Output Control Operations2519.15. Fasl Output2589.16. File System Interface2609.17. Generic Port Examples26510. Libraries and Top-level Programs27510.1. Built-in Libraries27510.2. Running Top-level Programs27710.3. Library and Top-level Program Forms27810.4. Standalone import and export forms27910.5. Explicitly invoking libraries28710.6. Library Parameters28710.7. Library Inspection29011. Syntactic Extension and Modules29311.1. Fluid Keyword Bindings29311.2. Syntax-Rules Transformers29511.3. Syntax-Case Transformers29511.4. Compile-time Values and Properties30011.5. Modules30511.6. Standalone import and export forms31111.7. Built-in Modules31111.8. Meta Definitions31211.9. Conditional expansion31311.10. Aliases31411.11. Annotations315

Contentsvii11.12. Source Tables32112. System Operations32512.1. Exceptions32512.2. Interrupts32912.3. Environments33212.4. Compilation, Evaluation, and Loading33612.5. Source Directories and Files35612.6. Compiler Controls35712.7. Profiling36412.8. Waiter Customization37412.9. Transcript Files37912.10. Times and Dates38012.11. Timing and Statistics38812.12. Cost Centers39212.13. Parameters39412.14. Virtual registers39612.15. Environmental Queries and Settings39812.16. Subset Modes40013. Storage Management40113.1. Garbage Collection40113.2. Weak Pairs, Ephemeron Pairs, and Guardians40513.3. Locking Objects41314. Expression Editor41514.1. Expression Editor Parameters41514.2. Key Binding41714.3. Editing Commands41714.4. Creating New Editing Commands425

viiiContents15. Thread System42715.1. Thread Creation42815.2. Mutexes42815.3. Conditions43015.4. Locks43115.5. Locked increment and decrement43215.6. Reference counting with ftype guardians43315.7. Thread Parameters43515.8. Buffered I/O43515.9. Example: Bounded Queues43616. Compatibility Features43916.1. Hash Tables43916.2. Extend-Syntax Macros44116.3. Structures44616.4. Compatibility File450References451Summary of Forms455Index493

PrefaceChez Scheme is both a general-purpose programming language and an implementation ofthat language, with supporting tools and documentation. As a superset of the languagedescribed in the Revised6 Report on Scheme (R6RS), Chez Scheme supports all standard features of Scheme, including first-class procedures, proper treatment of tail calls,continuations, user-defined records, libraries, exceptions, and hygienic macro expansion.Chez Scheme supports numerous non-R6RS features. A few of these are local and top-levelmodules, local import, foreign datatypes and procedures, nonblocking I/O, an interactivetop-level, compile-time values and properties, pretty-printing, and formatted output.The implementation includes a compiler that generates native code for each processor uponwhich it runs along with a run-time system that provides automatic storage management,foreign-language interfaces, source-level debugging, profiling support, and an extensive runtime library.The threaded versions of Chez Scheme support native threads, allowing Scheme programsto take advantage of multiprocessor or multiple-core systems. Nonthreaded versions are alsoavailable and are faster for single-threaded applications. Both 32-bit and 64-bit versionsare available for some platforms. The 64-bit versions support larger heaps, while the 32-bitversions are faster for some applications.Chez Scheme’s interactive programming system includes an expression editor that, likemany shells, supports command-line editing, a history mechanism, and command completion. Unlike most shells that support command-line editing, the expression editor properlysupports multiline expressions.Chez Scheme is intended to be as reliable and efficient as possible, with reliability takingprecedence over efficiency if necessary. Reliability means behaving as designed and documented. While a Chez Scheme program can always fail to work properly because of a bugin the program, it should never fail because of a bug in the Chez Scheme implementation.Efficiency means performing at a high level, consuming minimal CPU time and memory.Performance should be balanced across features, across run time and compile time, andacross programs and data of different sizes. These principles guide Chez Scheme languageand tool design as well as choice of implementation technique; for example, a language feature or debugging hook might not exist in Chez Scheme because its presence would reducereliability, efficiency, or both.The compiler has been rewritten for Version 9 and generates substantially faster code thanthe earlier compiler at the cost of greater compile time. This is the primary differencebetween Versions 8 and 9.

xPrefaceThis book (CSUG) is a companion to The Scheme Programming Language, 4th Edition(TSPL4). TSPL4 serves as an introduction to and reference for R6RS, while CSUG describes Chez Scheme features and tools that are not part of R6RS. For the reader’s convenience, the summary of forms and index at the back of this book contain entries fromboth books, with each entry from TSPL4 marked with a “t” in front of its page number.In the online version, the page numbers given in the summary of forms and index doubleas direct links into one of the documents or the other.Additional documentation for Chez Scheme includes release notes, a manual page, anda number of published papers and articles that describe various aspects of the system’sdesign and implementation.Thank you for using Chez Scheme.

1. IntroductionThis book describes Chez Scheme extensions to the Revised6 Report on Scheme [28](R6RS). It contains as well a concise summary of standard and Chez Scheme forms andprocedures, which gives the syntax of each form and the number and types of arguments accepted by each procedure. Details on standard R6RS features can be found in The SchemeProgramming Language, 4th Edition (TSPL4) [11] or the Revised6 Report on Scheme. TheScheme Programming Language, 4th Edition also contains an extensive introduction to theScheme language and numerous short and extended examples.Most of this document also applies equally to Petite Chez Scheme, which is fully compatible with the complete Chez Scheme system but uses a high-speed interpreter in placeof Chez Scheme’s incremental native-code compiler. Programs written for Chez Schemerun unchanged in Petite Chez Scheme as long as they do not require the compiler to beinvoked. In fact, Petite Chez Scheme is built from the same sources as Chez Scheme, withall but the compiler sources included. A detailed discussion of the impact of this distinctionappears in Section 2.8.The remainder of this chapter covers Chez Scheme extensions to Scheme syntax (Section 1.1), notational conventions used in this book (Section 1.2), the use of parameters forsystem customization (Section 1.3), and where to look for more information on Chez Scheme(Section 1.4).Chapter 2 describes how one uses Chez Scheme for program development, scripting, and application delivery, plus how to get the compiler to generate the most efficient code possible.Chapter 3 describes debugging and object inspection facilities. Chapter 4 documents facilities for interacting with separate processes or code written in other languages. Chapter 5describes binding forms. Chapter 6 documents control structures. Chapter 7 documentsoperations on nonnumeric objects, while Chapter 8 documents various numeric operations,including efficient type-specific operations. Chapter 9 describes input/output operationsand generic ports, which allow the definition of ports with arbitrary input/output semantics. Chapter 10 discusses how R6RS libraries and top-level programs are loaded intoChez Scheme along with various features for controlling and tracking the loading process.Chapter 11 describes syntactic extension and modules. Chapter 12 describes system operations, such as operations for interacting with the operating system and customizingChez Scheme’s user interface. Chapter 13 describes how to invoke and control the storage management system and documents guardians and weak pairs. Chapter 14 describesChez Scheme’s expression editor and how it can be customized. Chapter 15 documentsthe procedures and syntactic forms that comprise the interface to Chez Scheme’s nativethread system. Finally, Chapter 16 describes various compatibility features.

21. IntroductionThe back of this book contains a bibliography, the summary of forms, and an index. Thepage numbers appearing in the summary of forms and the italicized page numbers appearingin the index indicate the locations in the text where forms and procedures are formallydefined. The summary of forms and index includes entries from TSPL4, so that they coverthe entire set of Chez Scheme features. A TSPL4 entry is marked by a “t” prefix on thepage number.Online versions and errata for this book and for TSPL4 can be found at www.scheme.com.Acknowledgments: Michael Adams, Mike Ashley, Carl Bruggeman, Bob Burger, SamDaniel, George Davidson, Matthew Flatt, Aziz Ghuloum, Bob Hieb, Andy Keep, and OscarWaddell have contributed substantially to the development of Chez Scheme. Chez Scheme’sexpression editor is based on a command-line editor for Scheme developed from 1989through 1994 by C. David Boyer. File compression is performed with the use of the lz4compression library developed by Yann Collet or the zlib compression library developedby Jean-loup Gailly and Mark Adler. Implementations of the list and vector sorting routines are based on Olin Shiver’s opportunistic merge-sort algorithm and implementation.Michael Lenaghan provided a number of corrections for earlier drafts of this book. Manyof the features documented in this book were suggested by current Chez Scheme users,and numerous comments from users have also led to improvements in the text. Additionalsuggestions for improvements to Chez Scheme and to this book are welcome.1.1. Chez Scheme SyntaxChez Scheme extends Scheme’s syntax both at the object (datum) level and at the level ofsyntactic forms. At the object level, Chez Scheme supports additional representations forsymbols that contain nonstandard characters, nondecimal numbers expressed in floatingpoint and scientific notation, vectors with explicit lengths, shared and cyclic structures,records, boxes, and more. These extensions are described below. Form-level extensionsare described throughout the book and summarized in the Summary of Forms, which alsoappears in the back of this book.Chez Scheme extends the syntax of identifiers in several ways. First, the sequence ofcharacters making up an identifier’s name may start with digits, periods, plus signs, andminus signs as long as the sequence cannot be parsed as a number. For example, 0abc, , and . are all valid identifiers in Chez Scheme. Second, the single-character sequences{ and } are identifiers. Third, identifiers containing arbitrary characters may be printedby escaping them with \ or with . \ is used to escape a single character (except ’x’,since \x marks the start of a hex scalar value), whereas is used to escape the group ofcharacters that follow it up through the matching . For example, \ \ is an identifierwith a two-character name consisting of the character followed by the character \, and hit me! is an identifier whose name contains a space.In addition, gensyms (page 7.9) are printed with #{ and } brackets that enclose boththe “pretty” and “unique” names, e.g., #{g1426 e5g1c94g642dssw-a}. They may also beprinted using the pretty name only with the prefix #:, e.g., #:g1426.

1.1. Chez Scheme Syntax3Arbitrary radixes from two through 36 may be specified with the prefix #n r, where n is theradix. Case is not significant, so #n R may be used as well. Digit values from 10 through 35are specified as either lower- or upper-case alphabetic characters, just as for hexadecimalnumbers. For example, #36rZZ is 35 36 35, or 1295.Chez Scheme also permits nondecimal numbers to be printed in floating-point or scientific notation. For example, #o1.4 is equivalent to 1.5, and #b1e10 is equivalent to 4.0.Digits take precedence over exponent specifiers, so that #x1e20 is simply the four-digithexadecimal number equivalent to 7712.In addition to the standard named characters #\alarm, #\backspace, #\delete, #\esc,#\linefeed, #\newline, #\page, #\return, #\space, and #\tab, Chez Scheme recognizes#\bel, #\ls, #\nel, #\nul, #\rubout, and #\vt (or #\vtab). Characters whose scalarvalues are less than 256 may also be printed with an octal syntax consisting of the prefix#\ followed by a three octal-digit sequence. For example, #\000 is equivalent to #\nul.Chez Scheme’s fxvectors, or fixnum vectors, are printed like vectors but with the prefix#vfx( in place of #(. Vectors, bytevectors, and fxvectors may be printed with an explicitlength prefix, and when the explicit length prefix is specified, duplicate trailing elementsmay be omitted. For example, #(a b c) may be printed as #3(a b c), and a vector oflength 100 containing all zeros may be printed as #100(0).Chez Scheme’s boxes are printed with a #& prefix, e.g., #&17 is a box containing the integer17.Records are printed with the syntax #[type-name field .], where the symbol type-nameis the name of the record type and field . are the printed representations for the contentsof the fields of the record.Shared and cyclic structure may be printed using the graph mark and reference prefixes#n and #n #. #n is used to mark an item in the input, and #n # is used to refer to theitem marked n. For example, ’(#1 (a) . #1#) is a pair whose car and cdr contain thesame list, and #0 (a . #0#) is a cyclic list, i.e., its cdr is itself.A primitive form (see page 358) may be abbreviated in the same manner as a quoteform, using the #% prefix. For example, #%car is equivalent to ( primitive car), #2%carto ( primitive 2 car), and #3%car to ( primitive 3 car).Chez Scheme’s end-of-file object is printed #!eof. If the end-of-file object appears outsideof any datum within a file being loaded, load will treat it as if it were a true end of fileand stop loading at that point. Inserting #!eof into the middle of a file can thus be handywhen tracking down a load-time error.Broken pointers in weak pairs (see page 406) are represented by the broken weak pointerobject, which is printed #!bwp.In addition to the standard delimiters (whitespace, open and close parentheses, open andclose brackets, double quotes, semi-colon, and #), Chez Scheme also treats as delimitersopen and close braces, single quote, backward quote, and comma.Finally, Chez Scheme accepts #true and #false as alternative spellings of the booleans #tand #f. Like the external representation of numbers, case is not significant; for example,#T, #True and #TRUE are all equivalent.

41. IntroductionThe Chez Scheme lexical extensions described above are disabled in an input stream afteran #!r6rs comment directive has been seen, unless a #!chezscheme comment directivehas been seen since. Each library loaded implicitly via import and each RNRS top-levelprogram loaded via the --program command-line option, the scheme-script command, orthe load-program procedure is treated as if it begins implicitly with an #!r6rs commentdirective.The case of symbol and character names is normally significant, as required by the Revised6Report. Names are folded, as if by string-foldcase, following a #!fold-case commentdirective in the same input stream unless a #!no-fold-case has been seen since. Namesare also folded if neither directive has been seen and the parameter case-sensitive hasbeen set to #f.The printer invoked by write, put-datum, pretty-print, and the format s option alwaysprints standard Revised6 Report objects using the standard syntax, unless a different behavior is requested via the setting of one of the print parameters. For example, it printssymbols in the extended identifier syntax of Chez Scheme described above using hex scalarvalue escapes, unless the parameter print-extended-identifiers is set to true. Similarly, it does not print the explicit length or suppress duplicate trailing elements unless theparameter print-vector-length is set to true.1.2. Notational ConventionsThis book follows essentially the same notational conventions as The Scheme Programming Language, 4th Edition. These conventions are repeated below, with notes specific toChez Scheme.When the value produced by a procedure or syntactic form is said to be unspecified, theform or procedure may return any number of values, each of which may be any Schemeobject. Chez Scheme usually returns a single, unique void object (see void) whenever theresult is unspecified; avoid counting on this behavior, however, especially if your programmay be ported to another Scheme implementation. Printing of the void object is suppressedby Chez Scheme’s waiter (read-evaluate-print loop).This book uses the words “must” and “should” to describe program requirements, such asthe requirement to provide an index that is less than the length of the vector in a call tovector-ref. If the word “must” is used, it means that the requirement is enforced by theimplementation, i.e., an exception is raised, usually with condition type &assertion. If theword “should” is used, an exception may or may not be raised, and if not, the behavior ofthe program is undefined. The phrase “syntax violation” is used to describe a situation inwhich a program is malformed. Syntax violations are detected prior to program execution.When a syntax violation is detected, an exception of type &syntax is raised and the programis not executed.Scheme objects are displayed in a typewriter typeface just as they are to be typed at thekeyboard. This includes identifiers, constant objects, parenthesized Scheme expressions,and whole programs. An italic typeface is used to set off syntax variables in the descriptionsof syntactic forms and arguments in the descriptions of procedures. Italics are also used

1.3. Parameters5to set off technical terms the first time they appear. The first letter of an identifier that isnot ordinarily capitalized is not capitalized when it appears at the beginning of a sentence.The same is true for syntax variables written in italics.In the description of a syntactic form or procedure, a pattern shows the syntactic formor the application of the procedure. The syntax keyword or procedure name is given intypewriter font, as are parentheses. The remaining pieces of the syntax or arguments areshown in italics, using names that imply the types of the expressions or arguments expectedby the syntactic form or procedure. Ellipses are used to specify zero or more occurrencesof a subexpression or argument.1.3. ParametersAll Chez Scheme system customization is done via parameters. A parameter is a procedurethat encapsulates a hidden state variable. When invoked without arguments, a parameterreturns the value of the encapsulated variable. When invoked with one argument, theparameter changes the value of the variable to the value of its argument. A parameter mayraise an exception if its argument is not appropriate, or it may filter the argument in someway.New parameters may be created and used by programs running in Chez Scheme. Parameters are used rather than global variables for program customization for two reasons:First, unintentional redefinition of a customization variable can cause unexpected problems,whereas unintentional redefinition of a parameter simply makes the parameter inaccessible.For example, a program that defines *print-level* for its own purposes in early releasesof Chez Scheme would have unexpected effects on the printing of Scheme objects, whereasa program that defines print-level for its own purposes simply loses the ability to alterthe printer’s behavior. Of course, a program that invokes print-level by accident can stillaffect the system in unintended ways, but such an occurrence is less likely, and can onlyhappen in an incorrect program.Second, invalid values for parameters can be detected and rejected immediately when the“assignment” is made, rather than at the point where the first use occurs, when it is toolate to recover and reinstate the old value. For example, an assignment of *print-level*to 1 would not have been caught until the first call to write or pretty-print, whereasan attempted assignment of 1 to the parameter print-level, i.e., (print-level -1), isflagged as an error immediately, before the change is actually made.Built-in system parameters are described in different sections throughout this book and arelisted along with other syntactic forms and procedures in the Summary of Forms in the backof this book. Parameters marked “thread parameters” have per-thread values in threadedversions of Chez Scheme, while the values of parameters marked “global parameters” areshared by all threads. Nonthreaded versions of Chez Scheme do not distinguish betweenthread and global parameters. See Sections 12.13 and 15.7 for more information on creatingand manipulating parameters.

61. Introduction1.4. More InformationThe articles and technical reports listed below document various features of Chez Schemeand its implementation: syntactic abstraction [14, 8, 17], modules [32], libraries [21], storage management [12, 13], threads [10], multiple return values [2], optional arguments [16], continuations [7, 25, 3], eq? hashtables [20], internal definitions, letrec, and letrec* [33, 22], equal? [1], engines [15], floating-point printing [4], code generation [18], register allocation [6], procedure inlining [31], profiling [5], and history of the implementation [9].Links to abstracts and electronic versions of these publications are available at the urlhttp://www.cs.indiana.edu/chezscheme/pubs/.

2. Using Chez SchemeChez Scheme is often used interactively to support program development and debugging,yet it may also be used to create stand-alone applications with no interactive component.This chapter describes the various ways in which Chez Scheme is typically used and, moregenerally, how to get the most out of the system. Sections 2.1, 2.2, and 2.3 describe how oneuses Chez Scheme interactively. Section 2.4 discusses how libraries and RNRS top-level programs are used in Chez Scheme. Section 2.5 covers support for writing and running Schemescripts, including compiled scripts and compiled RNRS top-level programs. Section 2.6 describes how to structure and compile an application to get the most efficient code possibleout of the compiler. Section 2.7 describes how one can customize the startup process, e.g.,to alter or eliminate the command-line options, to preload Scheme or foreign code, or torun Chez Scheme as a subordinate program of another program. Section 2.8 describes howto build applications using Chez Scheme with Petite Chez Scheme for run-time support.Finally, Section 2.9 covers command-line options used when invoking Chez Scheme.2.1. Interacting with Chez SchemeOne of the simplest and most effective ways to write and test Scheme programs is tocompose them using a text editor, like vi or emacs, and test them interactively withChez Scheme running in a shell window. When Chez Scheme is installed with defaultoptions, entering the command scheme at the shell’s prompt starts an interactive Schemesession. The command petite does the same for Petite Chez Scheme. After entering thiscommand, you should see a short greeting followed by an angle-bracket on a line by itself,like this:Chez Scheme Version 9.5.1Copyright 1984-2017 Cisco Systems, Inc. You also should see that the cursor is sitting one space to the right of the angle-bracket.The angle-bracket is a prompt issued by the system’s “REPL,” which stands for “ReadEval Print Loop,” so called because it reads, evaluates, and prints an expression, thenloops back to read, evaluate, and print the next, and so on. (In Chez Scheme, the REPLis also called a waiter.)

82. Using Chez SchemeIn response to the prompt, you can type any Scheme expression. If the expression is wellformed, the REPL will run the expression and print the value. Here are a few examples: 33 ( 3 4)7 (cons ’a ’(b c d))(a b c d)The reader used by the REPL is more sophisticated than an ordinary reader. In fact, it’s afull-blown “expression editor” (“expeditor” for short) like a regular text editor but for justone expression at a time. One thing you might soon notice is that the system automaticallyindents the second and subsequent lines of an expression. For example, let’s say we want todefine fact, a procedure that implements the factorial function. If we type (define factfollowed by the enter key, the cursor should be sitting under the first e in define, so thatif we then type (lambda (x), we should see: (define fact(lambda (x)The expeditor also allows us to move around within the expression (even across lines) andedit the expression to correct mistakes. After typing: (define fact(lambda (x)(if ( n 0)0(* n (factwe might notice that the procedure’s argument is named x but we have been referencingit as n. We can move back to the second line using the arrow keys, remove the offending xwith the backspace key, and replace it with n. (define fact(lambda (n)(if ( n 0)0(* n (factWe can then return to the end of the expression with the arrow keys and complete thedefinition. (define fact(lambda (n)(if ( n 0)0(* n (fact (- n 1))))))Now that we have a complete form with balanced parentheses, if we hit enter with the

2.1. Interacting with Chez Scheme9cursor just after the final parenthesis, the expeditor will send it on to the evaluator. We’llknow that it has accepted the definition when we get another right-angle prompt.Now we can test our definition by entering, say, (fact 6) in response to the prompt: (fact 6)0The printed value isn’t what we’d hoped for, since 6! is actually 720. The problem, ofcourse, is that the base-case return-value 0 should have been 1. Fortunately, we don’t haveto retype the definition to correct the mistake. Instead, we can use the expeditor’s historymechanism to retrieve the earlier definition. The up-arrow key moves backward throughthe history. In this case, the first up-arrow retrieves (fact 6), and the second retrieves thefact definition.As we move back through the history, the expression editor shows us only the first line, soafter two up arrows, this is all we see of the definition: (define factWe can force the expeditor to show the entire expression by typing L (control L, i.e., thecontrol and L keys pressed together): (define fact(lambda (n)(if ( n 0)0(* n (fact (- n 1))))))Now we can move to the fourth line and change the 0 to a 1. (define fact(lambda (n)(if ( n 0)1(* n (fact (- n 1))))))We’re now ready to enter the corrected definition. If the cursor is on the fourth line andwe hit enter, however, it will just open up a new line between the old fourth and fifth lines.This is useful in other circumstances, but not now. Of course, we can work around this byusing the arrow keys to move to the end of the expression, but an easier way is to type J,which forces the expression to be entered immediately no matter where the cursor is.Finally, w

both books, with each entry from TSPL4 marked with a \t" in front of its page number. In the online version, the page numbers given in the summary of forms and index double as direct links into one of the documents or the other.