Summary: This lab introduces the XEmacs editor and then provides practice with lists in Scheme, including the basic operations (cons, car, cdr), list literals, the empty list, and several common built-in procedures.
In the previous lab, you typed commands directly into the Scheme environment, which immediately evaluated and printed the result. While this use of Scheme is quite straightforward, it has at least four disadvantages.
Using a text editor in conjunction with Scheme can address all of these issues.
Getting Started With XEmacs: We will use the popular XEmacs editor as the basis for our work in this lab.
Steps for this Lab:
Basic XEmacs works as a simple editor, allowing you to open files, edit, save, and print as you might in most word processing packages. For our purposes, however, it will be convenient to set up Xemacs with a split screen. In the bottom window, we will write Scheme and take notes, while we will run Chez Scheme in the top window. Further, when typing Scheme, it is nice to have different elements of the langauge appear in different colors. While this provides a nice environment in which to work, it does require a short setup operation.
Customizing XEmacs for Chez Scheme Programming: Files containing Chez Scheme source code conventionally end in .ss (``Scheme source''). The Scheme mode supplied with XEmacs does not recognize this convention (it assumes .scm instead), but a Chez Scheme programmer can make XEmacs aware of it by revising the XEmacs configuration file, .emacs, in her home directory. The revision need only be made once. Afterwards, XEmacs will automatically be reminded of the .ss convention every time it is started up.
The XEmacs configuration file is actually a short computer program that is executed while XEmacs is starting up, before the window appears. (In fact, this program happens to be written in a language that is a close relative of Scheme -- Emacs Lisp. We won't linger to examine the similarities and differences, though -- the current objective is simply to customize XEmacs to work with Chez Scheme programs.)
Start XEmacs and open the file .emacs in your home directory.
Position the editing cursor at the bottom of the file by moving the mouse pointer to the end of the file and clicking with the left mouse button.
The customizations that you need to add are stored in the file /home/walker/151s/labs/xemacs-customization To copy this file into .emacs, bring up the File menu from the menu bar and select the Insert File... operation. Erase the ~/ characters that are supplied automatically and type in the full name of the customization file. Press <Enter> at the end of the file name. The contents of the file will appear in the XEmacs window.
Save the updated .emacs file and exit from XEmacs.
Open a new file named sample.ss in the XEmacs window, by clicking on the dogeared-paper icon at the left end of the toolbar near the top of the XEmacs window -- the one with the word Open underneath it.
A dialogue box pops up, with the names of various editable files displayed above and a prompt at the bottom that looks like this:
Find file: ~/Move the mouse pointer into the dialogue box and type in the name of the file you want to create.
Conventionally, Scheme programs are stored in files with names ending in .ss. For example, you might call the first Scheme file that you create first-test.ss. Type this name in at the Find file prompt, after the slash, and hit the Enter key. (Do NOT click on the OK button.)
Press the <F1> button to split the screen into the two regions.
For much lab work, you will want to write Scheme statements and take notes in the bottom window. After writing a Scheme expression in the bottom window, you can enter the expression directly into Scheme in the top window by moving the mouse immediately after the expression and pressing the Enter key at the far right of your keyboard. (Choosing the Enter key in the middle of your keyboard starts a new line, but does not transfer the preceeding expression to Scheme.)
Check on the interaction between the editing window and Scheme, as follows.
Click your mouse in the bottom editing window, so you can work with the editor.
Type the following line into the editing window:
(+ 2 3)
Place the mouse after this expression, and press Enter at the right of the keyboard. You should see the corresponding response 5 in the Scheme window.
Clarify that the Enter key only enters the information immediately preceeding the mouse. In this line, what happens if the mouse is positioned immediately after the 2? immediately after the 3? on the 3 itself? immediately after the right parenthesis?
Now enter the following lines into the editing window:
(define pi 3.141596535)
pi
(* 2 pi 10)
and enter each of these expressions into Scheme. Each time you Enter the expression, you should see a corresponding response in the Scheme window.
As you are typing, note that when you type a right parenthesis, XEmacs shows you which left parenthesis it matches. This will be particularly helpful when typing longer Scheme programs.
In Scheme mode, pressing the <Tab> key automatically indents the line containing the editing cursor to the correct position. If you use XEmacs to edit Scheme code and follow every carriage return with a tab, you'll always have correctly indented Scheme code.
If you forget to exit from Chez Scheme before closing the XEmacs window in which it is running, XEmacs will remind you by printing the question
Active processes exist; kill them and exit anyway? (yes or no)
in a pop-up box superimposed on it. If you click on the small rectangle containing the word Yes in response, XEmacs will shut down Chez Scheme for you as it shuts itself down.
While XEmacs is an extremely powerful editor, many common capabilities are highlighted with buttons and menus at the top of window. These menus are analogous to most word processing packages, and thus are not discussed here. Ask the instructor as questions arise. (If something particularly strange seems to be happening, type <Ctrl/g> to stop the processing of a command.)
In Scheme, a list is written by enclosing the elements of the list in parentheses. Here are some simple examples:
(+ x y) (this is a list) (sqrt x) ()These lists have 3, 4, 2, and 0 components, respectively. The list () with 0 components also is called the empty list or the null list.
Any or all components of a list can, in turn, be lists:
(* pi (expt r 2)) (+ (* x x) (* 3 x) 2) (all x (if (human x) (mortal x))) ( () ) ((())) ((()())())In reviewing the second of these examples, (+ (* x x) (* 3 x) 2) is a list with four components:
+ (* x x) (* 3 x) 2List Extraction Functions: Parts of lists can be extracted by car and cdr:
(car '(a b c)) = a (car '((a) b c)) = (a) (car (car '((a) b c))) = a (car 'a) error: a is not a list. (car '()) error: () is not a pair. (cdr '(a b c)) = (b c) (cdr '((a) b c)) = (b c) (cdr (cdr '(a b c))) = (c) (cdr (car '((a) b c))) = () (cdr 'a) error: a is not a list. (cdr '()) error: () is not a pair.In each of these examples, note that car and cdr are applied to a list which is introduced with a quote. Since parentheses are used both to group data into a list and to call procedures, the Scheme interactive interface needs to see a single quote at the front of a list literal, so that it will treat it as a datum instead of evaluating it.
Since combinations of car and cdr are frequently used, all combinations up to four uses of car and cdr are defined as functions of the form cxxxr:
(caar x) = (car (car x)) (cadr x) = (car (cdr x)) (caddr x) = (car (cdr (cdr x)))List Constructor Function:
(cons 'a '(b c)) = (a b c) (cons 'a '()) = (a) (cons '(a) '(b)) = ((a) b)The list function makes a list out of the elements that follow:
(list 'a 'b 'c 'd) = (a b c d) (list 'a '(b c)) = (a (b c)) (list 'a '()) = (a ()) (list '(a) '(b)) = ((a) (b))List Manipulation Functions
(append '(a) '(b)) = (a b) (append '(a b) '(c d)) = (a b c d) (append '(a) '(b) '(c)) = (a b c)reverse makes a new list that is the reverse of the top level of the list given as its argument.
(reverse '(a b)) = (b a) (reverse '((a b)(c d))) = ((c d)(a b))length returns the number of components in the [top level] of a list.
(length '(a)) = 1 (length '(a b)) = 2 (length '((a b))) = 1 (length '(+ (* x x) (* 3 x) 2)) = 4Steps for this Lab:
(length 5) (length '(+ 2 3)) (length (+ 2 3))In each case, explain the result.
all if human
((a) (b c)) (+ (* x x) (* 3 x) 2)
(append '(a b c) '( )) (list '(a b c) '( )) (cons '(a b c) '( ))In each case, explain why you received the result that you obtain.
This document is available on the World Wide Web as
http://www.math.grin.edu/~walker/courses/151.sp00/lab-lists.html