• Aucun résultat trouvé

SAVING FOR ANOTHER DAY

Dans le document COMMON LISP An Interactive Approach (Page 91-97)

So far, all your typing of Lisp S-expressions has been directly to the top-level Lisplistener. If you defined a function and found that you had made a mistake in it, you had to type it all in again. You also couldn’t define a function and save it for another session. Both these problems are solved by typing your function definitions into a file. You can use a normal text file, editing it with the same editor that you use to type letters, papers, electronic mail, or programs in any other programming language. However, there are certain benefits if you use a special editor that is provided with yourCommon Lispor an Emacs editor such as GNU Emacs.1 I will describe these benefits below.

Once you type a series of defunforms into some file, you should save it.

First, you must choose a namefor the file; on many systems, you must also choose an extension. The name can be any sequence of letters followed by digits. (Most systems have more complicated naming rules and allow other characters, but since these rules differ, let’s use this one.) Let’s say you choosemyfunctionsas the name of your file. The extension, if required by your system, will be the same for allLispsource files. Let’s say the extension islisp. There will also be a separator character between the name and the extension. This is often the period, so we’ll use that. That makes the name of your file myfunctions.lisp. How you save a file depends on the editor you use.

You can choose to load your source file into Common Lispand use the

1Available from Free Software Foundation, 1000 Massachusetts Avenue, Cam-bridge, MA 02138, U.S.A.

67

68 II: PROGRAMMING IN PURE LISP functions defined there in “interpreted mode,” or you can compile the file, load the compiled version intoCommon Lisp, and use the compiled versions of the functions. Generally, compiled functions use less time and space to execute, but can be more difficult to debug. Therefore, you should debug the interpreted versions of your functions until you are quite confident of them.

Then you should compile the file and use the compiled versions for efficiency.

Often, you will find more bugs when you compile your file: the compiler will give you error messages and warnings. You should not consider your programming task complete until you have compiled your file without error messages or warnings. The compiler will automatically give the compiled version of your file the same name as your source file and a standard extension that is different from the standard extension ofLispsource files.

Once you’ve saved your file, you can get the functions defined in it into yourLispby executing the form(load "myfunctions").

(load filename)Reads the file whose name is given by the string filename and evaluates all the top-level forms in it. If filename contains an ex-tension, that file will be read. Otherwise,loadwill either read the file whose name is given by filename and whose extension is the standard Lispsource extension, or it will read the file whose name is given by file-nameand whose extension is the standardLispcompiled file extension, whichever is more recent.

If your system organizes its files as a directory hierarchy, then there will be a way for you to specify a “full path name” for your file that is system-dependent.

Once you’ve loaded your function definitions, you can test them. If you need to alter a function definition, return to the editor, edit your file, save it again, load it again, and continue testing. ModernLisp development en-vironments, containing either a specialLispeditor or an Emacs-type editor, make this process much easier.

If you have a modernLispdevelopment environment, you will be able to do the following:

Divide your screen into two windows, with an active editor open to your Lisp source file running in one window and an activeCommon Lisp listener running in the other.

Move your cursor into the editor window and type and editdefunforms.

Either copy a form from the editor window into the Common Lisp window and evaluate it there, or directly evaluate adefunform in the editor window so that the function is defined in the environment of the Common Lispwindow.

12: Saving for Another Day 69

Move your cursor into the Common Lisp window and interact with Common Lisp as you’ve become used to; in particular, to test the functions defined in the file appearing in the editor window.

Move your cursor into the editor window and save the file there. This need be done only every half hour or so, or just before terminating your session.

This process is the standard method experienced Lispers use to develop theirLispprograms.

Certain standard styles are recommended when writing Common Lisp source files:

defunforms: The first opening parenthesis of each defun form starts at the first character position of a line. The other lines are indented to show the structure of the form. Many editors will do the indenting automatically or semiautomatically.

Comments: Comments are preceded by the comment character ; and ex-tend to the rest of the line. There are three levels of comments:

Comments outside any function definition start with;;;and begin in the first character position on the line.

Comments inside a function definition, on their own line, start with;;and are indented with the rest of the definition.

Comments on the same line asLispcode begin with;and are to the right of theLispcode.

Packaging details: Typically, each file will define functions in a separate package. It is helpful if the beginning of each of your files looks like the following:

;;; Establish the default package

;;; for symbols read in this file.

(in-package ’package-name)

;;; Shadow any symbols from automatically inherited

;;; packages that have the same names as symbols

;;; in this package.

(shadow ’(symbol1, symbol2. . .))

;;; Shadow and import any symbols from other packages

;;; that are to be available as internal symbols

;;; in this package, but whose names conflict with

;;; symbols from automatically inherited packages.

(shadowing-import ’(symbol1, symbol2. . .))

70 II: PROGRAMMING IN PURE LISP

;;; Specify any packages all of whose external

;;; symbols are to be accessible

;;; as internal symbols in this package.

(use-package ’(package-name1, package-name2. . .))

;;; Explicitly import any other symbols that are to

;;; be accessible as internal symbols

;;; in this package.

(import ’(symbol1, symbol2. . .))

;;; Export the symbols from this package that are to

;;; be accessible to other packages.

(export ’(symbol1, symbol2. . .))

Under the new Common Lisp standard, you will be able to do this using the functiondefpackageas follows:

(defpackage package-name (:shadow symbol-names)

(:shadowing-import-from package-name symbol-names) ..

.

(:shadowing-import-from package-name symbol-names) (:use package-names)

(:import-from package-name symbol-names) ..

.

(:import-from package-name symbol-names) (:export symbol-names))

(in-package package-name)

Exercises

12.1 (p1)Begin a file namedmatch. Set it up so that the functions in it will be defined in thematchpackage.

12.2 (p1) In your match file, define a function variablep that takes one symbol as an argument and returnsTif the first character of the sym-bol’s name is #\? and returns NIL otherwise. If you have a modern Lisp development environment, develop and test this function using the two-window approach described in this chapter.

12: Saving for Another Day 71 12.3 (i) Compile your match file by evaluating the form

(compile-file "match").

12.4 (i) Load your matchfile using the load function. Can you tell that you’ve loaded the compiled file instead of the source file? Testvariablep again.

12.5 (p2) Begin a file namedcalculator. Set it up so that the functions in it will be defined in thecalculatorpackage.

12.6 (p2) In your calculator file, define the function combine-expr to take an arithmetic operator, an operand, and a list representing an arithmetic expression and return the expression with the operator and operand applied to the first member of the expression. For example, (combine-expr ’+ 3 ’(5 - 6 * 8)) should evaluate to ((3 + 5) -6 * 8).

CHAPTER 13

Dans le document COMMON LISP An Interactive Approach (Page 91-97)