Beginning Scheme

Algorithms and programs

Our main objectives in this course are to learn about algorithms -- step-by-step methods for solving problems -- and to learn how to direct computers to perform such algorithms for us. A programming language, such as Scheme, is a formal notation in which one can express algorithms so exactly that a computer can perform them without any other assistance from human beings. The expression of an algorithm in such a notation is called a program, and the computer is said to be executing the program when it is performing the algorithm as directed.

Let's start with a very short Scheme program that directs the computer to find the answer to the question ``What is the square root of 137641?'' Here it is:

(sqrt 137641)

When this program is executed, the computer's central processor -- the electronic circuit that directs the movement and transformation of data inside the computer -- calculates the square root, and the DrScheme software takes the result of the calculation and displays it in the Interactions window:

371

When the central processor calculates a square root, it breaks the computation down into a large number of much simpler steps. Some programmers who are experts on square roots and on the idiosyncracies of the Intel Pentium processor figured out and wrote down a step-by-step method for computing the square root of any number, using only the very elementary transformations that the processor can perform. DrScheme recognizes sqrt as the name of this algorithm and knows where the processor instructions that carry it out are stored. When DrScheme receives a command to compute a square root, it recovers these instructions and arranges for the processor to follow them.

Although it would be interesting and instructive to examine the method by which the processor calculates square roots, at this stage it will be more convenient for us to think of sqrt as a primitive procedure, regarding the calculation of a square root as a single step that is usually just part of a much larger program. The idea that a computation can be regarded as a complicated sequence of instructions on one level, and as a unit on another, more abstract level is very common in computer science.

The structure of Scheme programs

A program written in Scheme has a particularly simple structure: it is a sequence of definitions and commands -- any number of them, in any order. DrScheme reacts to each definition in a program by memorizing it, and to each command by carrying out the command and displaying any results that it produces. The expression (sqrt 137641) is a command -- ``Compute the square root of 137641!'' -- and it produces one result, which is duly displayed.

Calls to primitive procedures

The full Scheme language that DrScheme supports contains several hundred primitive procedures -- operations, such as finding the square root of a number, for which DrScheme can use pre-packaged algorithms.

A procedure call is a command that directs DrScheme to activate a procedure such as sqrt. (Note that `sqrt' is the name of the procedure, and `(sqrt 137641)' is the procedure call.) In Scheme, every procedure call begins with a left parenthesis and ends with the matching right parenthesis. Within the parentheses, one always begins by identifying the procedure to be called and then continues by identifying the arguments -- the values that the procedure is supposed to operate on. The sqrt procedure takes only one argument -- the number of which you want the square root -- but other procedures take two or more arguments, and some need no arguments at all.

All arithmetic in Scheme is done with procedure calls. The primitive procedure + adds numbers together; the primitive procedure - subtracts one number from another. Similarly, the primitive procedure * performs multiplication, and the primitive procedure / performs division. The fact that in a procedure call the procedure is identified first makes calls to these procedures look different from ordinary arithmetic expressions. For instance, to tell DrScheme to subtract 68343 from 81722, one gives the command

(- 81722 68343)

If this command is the whole program, running it causes DrScheme to display the result:

13379

Definitions

DrScheme learns new names for things by reading definitions. Here's what a definition looks like:

(define days-in-a-week 7)

Like a procedure call, a definition begins and ends with matching parentheses. To distinguish between definitions and procedure calls, DrScheme looks at what comes immediately after the left parenthesis. In a definition, the keyword define must appear at that point. Define is not the name of a procedure; it is a keyword, constituting part of the syntax of the Scheme programming language. Its only role is to serve as the mark of a definition.

After the keyword define, a definition contains the name being defined and an expression that identifies the value that the name should stand for. In this example, the name is days-in-a-week. (In Scheme, a name can contain hyphens internally.) The value that it names is the number 7. Once DrScheme has seen this definition, it remembers that days-in-a-week stands for 7.

For example, here is a Scheme program that begins with the definition shown above, and continues with a command that uses the name that the definition introduces:

(define days-in-a-week 7)

(* days-in-a-week 52)

When this program is executed, DrScheme displays the result of the computation that the command directs it to perform:

364

Since the value associated with the name days-in-the-week is 7, and the result of multiplying 7 by 52 is 364, this result is correct.

The value that gets a new name need not be a number; it can be anything, even a procedure. For example, if you don't like the name * for the multiplication procedure and would rather call it by the name multiply, you can just start each program with the definition

(define multiply *)

More procedures

At this point, I hope you're wondering what other useful and interesting procedures are built into Scheme. Section 6.2.5 of the Revised5 report on the algorithmic language Scheme contains a list of the ones that are mainly about numbers, and that's only one section of the full roster of standard Scheme procedures. Fortunately, most of the primitive procedures perform small, simple jobs and are easily learned.

Editing Scheme programs

When you start DrScheme, the window that first appears is divided horizontally into two subwindows: a Definitions window (on top), in which you'll develop and modify your programs, and an Interactions window (on the bottom), in which you'll experiment with them and test them.

Editing in the Definitions window

Although you can type anything you want to into the Definitions window, DrScheme expects to find a Scheme program there, and makes some assumptions about how to format what you type that are based on this assumption. DrScheme executes the program in the Definitions window only when you click on the Execute button.

In the Definitions window, you can perform a variety of editing operations to modify the text of the program:

(If you're curious about the rest of the operations listed on the Edit menu, you can find explanations of them in ``Using DrScheme: Interface reference: Menus: Edit,'' a section of the PLT DrScheme Programming Environment Manual. Still more editing operations are discussed in the section ``Using DrScheme: Interface reference: Keyboard shortcuts.'')

Comments

Programs are intended to be read both by people and by computers. Because people understand much richer and more flexible notations than computers -- real languages, as opposed to the extremely limited pseudo-languages used to direct the execution of algorithms -- it is essential to be able to include comments in program files. Comments are intended exclusively for human readers; the computer ignores them as if they were so much blank space.

In a Scheme program, any line that begins with one or more semicolons is a comment:

; This is a comment.  DrScheme will store it along with the
; rest of the text of a program, but does not even attempt to
; execute any part of it.

;;; The following definition, however, is read and processed:

(define centimeters-in-an-inch 254/100)

;;; And the following expression is evaluated when this program is
;;; executed:

(* 36 centimeters-in-an-inch)

It is also possible to place a comment to the right of a definition or command. The semicolon and everything to its right (on the same line) are ignored during execution.

(define centimeters-in-a-foot
  (* 12 centimeters-in-an-inch))  ; One foot equals twelve inches.

We'll use comments for several purposes in Scheme programs:

Using comments, you can and should think of writing a program as rather like writing an essay in which you describe the problem you're trying to solve and your method of solution. The code sections fit into such an essay as exhibits showing the exact, formal algorithms that express your solution.

Editing in the Interactions window

In the Interactions window, insertion and deletion operations work only in the region following the last prompt. The idea is that you cannot change the past: You can't go back and un-give commands that you have already given, and that DrScheme has already responded to. The Interactions window is supposed to contain an accurate transcript of what has been done and cannot be undone.

However, while you're working on a command -- even a complicated one that extends over several lines -- the editing operations work exactly as they do in the Definitions window. There is also one extra editing operation: If you press the <Esc> key (in the upper left-hand corner of our keyboards) and then the <P> key (for ``previous''), DrScheme makes a copy of the last command or definition that it processed in the Interactions window and places it after the prompt, so that you can revise it or repeat it easily.

Developing programs

Most of the writing that you do while developing a Scheme program takes place in the Definitions window. That's the place in which you record definitions that you want to keep, commentary about your program, sample calls to procedures, test cases, and so on.

If there are definitions and commands that you want to keep track of (so that you don't have to retype them from scratch later on, for instance), but that you don't want DrScheme to execute as part of your program, you can ``comment them out'' by putting a semicolon at the beginning of every line that they occupy. You can even comment out a large block of code in one step by first selecting the block (holding down the left mouse button while dragging the mouse over it) and then clicking on the word Scheme on the menu bar and clicking on Comment Out on the menu that appears.

The item Uncomment on that same menu has the opposite effect: It removes a semicolon from the beginning of each line in the selected block.

Loading a saved program back into DrScheme

Once you have saved a program in a file, as described in the ``Beginning Scheme'' handout, you can load it into DrScheme again from that file, in order to execute it, to modify or extend it, or just to read it over again. In fact, there are several different ways to recover the contents of DrScheme files.

The most straightforward method is to select the Open command from the File menu, and edit the white text field on the window that appears (the one labelled ``Full pathname'') so that it contains the name of the file in which your program is stored:

(screenshot)

Clicking on the OK button in the lower right-hand corner loads your program. Depending on whether the Definitions or Interaction window is free at the time you load the program, DrScheme either places the program in the appropriate window or creates a new frame-and-window combination and loads the program into it. In the latter case, DrScheme usually displays the program in only one text area. You can make the other one visible by selecting Show Interactions or Show Definitions (as appropriate) from the Show menu.

If you just want to execute the program in the file, rather than having it displayed on the screen, you can use a standard Scheme procedure called load. When invoked, load directs DrScheme to open a file and quickly read the program that it contains, memorizing each definition and executing each command. The load procedure takes one argument, a character string giving the name of the file in which the program is stored.

The term characters refers generically to letters, digits, punctuation marks, and such like -- the lowest-level constituents of text. A character string is a sequence containing any number of characters, ``strung together'' in a linear order. In Scheme, a character string is usually written just by placing the character sequence between double quotation marks. For instance, the string consisting of the three lower-case letters c, a, and t, in that order, is written in Scheme as "cat". (Without the quotation marks, Scheme would incorrectly interpret cat as a symbol like sqrt or area, and expect it to stand for something further.)

Here, then, is what a call to the load procedure looks like. This one expresses the command ``Execute the contents of the file named frogs.ss!''

(load "frogs.ss")

The parentheses enclose the procedure call and contain the name of the procedure, load, and the operand, "frogs.ss".

The help desk

DrScheme provides a lot of documentation about Scheme on-line. The usual entry point is the help desk, a browser that knows where to find all the documentation and provides access to it.

(screenshot)

To activate the help desk, select Help Desk from the Help menu. Clicking on the first link in the Help Desk window brings up a short introductory document, ``How to use Help Desk.''


This document is available on the World Wide Web as

http://www.cs.grinnell.edu/~walker/courses/151.sp04/readings/beginning-Scheme.xhtml

created August 23, 1997 and revised August 6, 2002 by John David Stone (stone@cs.grinnell.edu) and Ben Gum (gum@cs.grinnell.edu)
last revised January 18, 2004 by Henry M. Walker at walker@cs.grinnell.edu.
Validated as XHTML 1.0 by the World Wide Web Consortium Cascading Style Sheet validated by the World Wide Web Consortium
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.