Simply Scheme: Introducing Computer Science 2/e Copyright (C) 1999 MIT

Appendix A

Running Scheme

cover photo
Brian Harvey
University of California, Berkeley
Matthew Wright
University of California, Santa Barbara

Download PDF version
Back to Table of Contents
BACK chapter thread NEXT
MIT Press web page for Simply Scheme

The precise incantations needed to start Scheme depend on the particular version you're using and the model of computer and operating system you have. It's beyond the scope of this book to teach you the first steps in using a computer; we assume you've already used other programs, if not Scheme. But in this appendix we suggest a few general ideas and point out some knotty details.

One thing that beginners often forget is that a computer generally has many different programs available, and each one has its own capabilities and its own method of operation. If you think of yourself as interacting with "the computer," you're likely to try to use a command suitable for one program when you're actually using a different program. In learning to program in Scheme, you'll probably use at least three programs: Scheme itself, the operating system's shell (which is callled finder on the Macintosh and explorer on Windows), and a text editor. (The text editor may be part of the Scheme package or it may be an entirely separate program.) The shell allows you to run other programs, such as a printing utility or an electronic mail reader.

If you say (+ 2 3) to your text editor, it won't respond by printing 5. Instead, it will insert the seven characters that you typed into the file that you're editing. If you type the same thing to Scheme, it will evaluate the expression.

The Program Development Cycle

Scheme is an interactive language: You can write a program by typing its definition directly into the Scheme interpreter. This ability to interact with Scheme is a great advantage for one-time calculations and for exploratory work, but it's not the best approach for the systematic development of a large program.

There are two issues to consider. First, when writing a large program, you generally don't get it perfect the first time. You make both typing errors and program logic errors, and so you must be able to revise a definition. Typing directly to Scheme, the only way to make such a revision is to retype the entire definition. Second, Scheme does not provide a mechanism to save your work in a permanent file.

For these reasons, programs are generally typed into another program, a text editor, rather than directly at the Scheme prompt. As we'll explain in the next section, there are several ways in which an editing program can be integrated with Scheme, so that the work you do in the editor can be communicated easily to Scheme. But the distinction between Scheme and the editor is easiest to understand if we start by considering the worst possible situation, in which the two are not integrated.

Imagine, therefore, that you have two separate programs available on your computer. One program is a Scheme interpreter. When you start Scheme, you may see some initial message, and then you see a prompt, which is a signal from Scheme that it's ready for you to type something. In this book we've used the character ">" as the prompt. Then, as we explain in the text, you can type an expression, and Scheme will compute and print the value:

> (+ 2 3)
5

Your other program is a text editor. This might be a general-purpose word processing program, with facilities for fancy text formatting, or it might be an editor intended specifically for computer programs. Many editors "know" about Lisp programs and have helpful features, such as automatic indentation, selection of complete expressions, and showing you the matching open parenthesis when you type a close parenthesis.

To write a program, you use the editor. Although you are typing Scheme expressions, you're not talking to Scheme itself, and so the expressions are not evaluated as you type them. Instead, they just appear on the screen like any other text. When you're ready to try out your program, you tell the editor to save the text in a file. (The command to save the program text is the same as it would be for any other text; we assume that you already know how to use the editor on your computer.) You can give the file any name you want, although many people like to use names like something.scm to make it easy to recognize files that contain Scheme programs.

Now you switch from the editor to Scheme. To read your program file into Scheme, you enter the expression

(load "something.scm")

This tells Scheme to read expressions from the specified file.[1]

Once Scheme has read the program definitions from your file, you can continue typing expressions to Scheme in order to test your program. If this testing uncovers an error, you will want to change some definition. Instead of typing the changed definition directly into Scheme, which would only make a temporary change in your program, you switch back to the editor and make the change in your program file. Then switch back to Scheme, and load the corrected file.

This sequence of steps—edit a file, make changes, save the file, switch to Scheme, load the file, test the program, find an error—is called a "development cycle" because what comes after "find an error" is editing the file, beginning another round of the same steps.

Integrated Editing

The development process can become much more convenient if Scheme and the editor "know about" each other. For example, instead of having to reload an entire file when you change one procedure definition, it's faster if your editor can tell Scheme just the one new definition. There are three general approaches to this integration: First, the editor can be in overall charge, with the Scheme interpreter running under control of the editor. Second, Scheme can be in charge, with the editor running under Scheme's supervision. Third, Scheme and the editor can be separate programs, both running under control of a third program, such as a window system, that allows information to be transferred between them.

If you're using a Unix system, you will be able to take a separate editor program and run Scheme from within that editor. The editor can copy any part of your program into the running Scheme, as if you had typed it to Scheme yourself. We use Jove, a free, small, fast version of EMACS. Most people use the more featureful GNU version of EMACS, which is installed on most Unix systems and available at ftp://prep.ai.mit.edu/pub/gnu/ and many mirror sites for download.

If you're using a Macintosh or Windows version of Scheme, it will probably come with its own text editor and instructions on how to use it. These editors typically provide standard word-processing features such as cut and paste, search and replace, and saving files. Also, they typically have a way to ask Scheme to evaluate an expression directly from the editor.

If you're using SCM under DOS, you should read the section "Editing Scheme Code" in the README file that comes with the SCM distribution. It will explain that editing can be done in different ways depending on the precise software available to you. You can buy a DOS editor that works like the Unix editors, or you can ask SCM to start a separate editor program while SCM remains active.

Finally, if you're running Scheme under Windows or another windowing operating system (like X or the Macintosh Finder), you can run any editor in another window and use the cut and paste facility to transfer information between the editor and Scheme.

Getting Our Programs

This book uses some programs that we wrote in Scheme. You'll want these files available to you while reading the book:

simply.scm extended Scheme primitives
functions.scm    the functions program of Chapters 2 and 21
ttt.scm the tic-tac-toe example from Chapter 10
match.scm the pattern matcher example from Chapter 16
spread.scm the spreadsheet program example from Chapter 24
database.scm the beginning of the database project
copyleft the GNU General Public License (see Appendix D)

In particular, the file simply.scm must be loaded into Scheme to allow anything in the book to work. Some Scheme systems allow you to load such a "startup" file permanently, so that it'll be there automatically from then on. In other versions of Scheme, you must say

(load "simply.scm")

at the beginning of every Scheme session.

There are three ways to get these program files:

    If you have access to the Internet, the most recent versions of all these files can be found at ftp://anarres.cs.berkeley.edu/pub/scheme/

    If you know someone who already has these files, you may copy them and distribute them freely. (The programs are copyrighted but are provided under a license that allows unlimited redistribution on a nonprofit basis; see Appendix D.)
    If you're stranded on a desert island with nothing but a computer and a copy of this book, you can type them in yourself; complete listings for all six programs, plus the GNU Public License, appear in the text of the book.

Tuning Our Programs for Your System

Almost all of the programs we distribute with this book will work without modification in the popular versions of Scheme. We've included "defensive" procedures that allow our programs to work even in versions that don't conform to current Scheme standards in various ways. However, there are a few details that we couldn't make uniform in all versions.

1. Many versions of Scheme include a random procedure to generate random numbers, but the standard does not require it, and so we've provided one just in case. If your Scheme includes a primitive random, it's probably better than the one we provide, because we have no way to choose a different starting value in each Scheme session.

Before loading simply.scm into Scheme, do the following experiment:

> (random 5)

If you get an error message, do nothing. If you get a random number as the result, edit simply.scm and remove the definition of random.

2. Do the following experiment:

> (error "Your error is" "string")

If the message you get doesn't include quotation marks around the word string, then do nothing. But if you do see "string" with quotation marks, edit simply.scm and change the definition of error-printform to

(define (error-printform x) x)

3. Although the Scheme standard says that the read procedure should not read the newline character following an expression that it reads, some old versions of Scheme get this wrong.

After loading simply.scm, do the following experiment:

> (read-line)

End the line with the return or enter key (whichever is appropriate in your version of Scheme) as usual, but don't type a second return or enter yet. If Scheme prints () right away, skip this paragraph; your version of Scheme behaves correctly. If, on the other hand, nothing happens, type another return or enter. In this case you must edit functions.scm and remove the invocation of read-line on the first line of the body of the functions procedure.

4. There is a substantial loss of efficiency in treating strings of digits as numbers in some contexts and as text in other contexts. When we're treating 1024 as text, we want to be able to take its butfirst, which should be 024. But in Scheme, 024 is the same as 24, so instead butfirst returns a string:

> (butfirst 1024)
"024"

Yet we want to be able to do arithmetic on this value:

> (+ 3 (butfirst 1024))
27

To accomplish this, we redefine all of Scheme's arithmetic procedures to accept strings of digits and convert them to numbers. This redefinition slows down all arithmetic, not just arithmetic on strange numbers, and it's only rarely important to the programs we write. Therefore, we've provided a way to turn this part of the package off and on again. If your programs run too slowly, try saying

> (strings-are-numbers #f)

If you find that some program doesn't work because it tries to do arithmetic on a digit string and gets an error message, you can say

> (strings-are-numbers #t)

to restore the original behavior of our programs. We recommend that you leave strings-are-numbers true while exploring the first few chapters, so that the behavior of the word data type will be consistent. When you get to the large example programs, you may want to change to false.

Loading Our Programs

Scheme's load procedure doesn't scan your entire disk looking for the file you want to load. Instead, it only looks in one particular directory (DOS/Unix) or folder (Macintosh/Windows). If you want to load our programs, you have to make sure that Scheme can find them.

The first way to accomplish this is to give the full "path" as part of the argument to load. Here are some examples:[2]

UNIX-SCHEME> (load "/usr/people/matt/scheme-stuff/simply.scm")

WINDOWS-SCHEME> (load "c:\\scheme\\simply.scm")

MAC-SCHEME> (load "Hard Disk:Scheme Folder:simply.scm")

Under Unix, directories in a path are separated by forward slash characters. Under Windows and DOS, directories are separated by backward slash characters, which have a special meaning to Scheme. So you must use double backslashes as in our example above. On a Macintosh, you separate the parts of a path with colons. (However, most versions of Scheme for the Macintosh or Windows have a load command in one of the menus that opens a standard file selection dialog box, so you can use that instead.)

The other possibility is to put the files in the place where your version of Scheme looks for them. In many versions of Scheme, load looks for files in the folder that contains the Scheme program itself. Put our files in that folder.

On Unix, the default loading directory is whatever directory you're in at the moment. If you want to work on different projects in different directories, there's no way to make it so that load will always find our files. (But see our suggestion about writing book-load.)

Versions of Scheme

There are lots of them, both free and commercial. Three places to look for pointers are

http://swissnet.ai.mit.edu/scheme-home.html
http://www.schemers.org
http://www.cs.indiana.edu/scheme-repository

In general, there are four things you should be sure to learn about whatever version of Scheme you choose:

    Most versions of Scheme include a debugger to help you find program errors. If you call a primitive with an argument not in its domain, for example, Scheme will start the debugger, which will have features to let you find out where in your program the error occurred. These debuggers vary greatly among versions of Scheme. The first thing you should learn is how to leave the debugger, so you can get back to a Scheme prompt!
    Many versions of Scheme will read an initialization file if you create one. That is, when you start Scheme, it will look for a file of a particular name (something like init.scm, but not usually exactly that), and if there is such a file, Scheme will load it automatically. You can copy our simply.scm file to the proper filename for your version, and you'll have our added primitives available every time you start Scheme.
    Most versions of Scheme provide a trace capability, but the format of the trace results are quite different from one version to another.
    If you are using a Macintosh, one thing to watch out for is that some versions of Scheme expect you to use the ENTER key at the end of an expression, while others expect you to use the RETURN key.

Scheme Standards

The Web sites listed above will provide the latest version of the Revisedn Report on the Algorithmic Language Scheme. You can get the document in either Postscript or HTML format.

IEEE Standard 1178-1990, IEEE Standard for the Scheme Programming Language, may be ordered from IEEE by calling 1-800-678-IEEE or 908-981-1393 or writing IEEE Service Center, 445 Hoes Lane, P.O. Box 1331, Piscataway, NJ 08855-1331, and using order number SH14209 ($28 for IEEE members, $40 for others). ISBN 1-55937-125-0.


[1] If you see an error message about "end of file" or "EOF," it probably means that the file you are trying to load contains unbalanced parentheses; you have started an expression with a left parenthesis, and the file ended before Scheme saw a matching right parenthesis.

[2] Suggestion for instructors: when we teach this class, we define a procedure like

(define (book-load filename)
  (load (string-append "/usr/cs3/progs-from-book/" filename)))

so that students can just say

(book-load "functions.scm")

(back to Table of Contents)

BACK chapter thread NEXT

Brian Harvey, bh@cs.berkeley.edu