• Aucun résultat trouvé

A Note about Parentheses and Indenting

The two biggest barriers to learning Scheme are probably parentheses and indenting. In Scheme, parentheses are used a little differently than in most programming languages. Indenting is also very important, because the surface syntax of the language is so regular. When reading Scheme code,

experienced programmers read the indenting structure as much as the tokens. If you don't parenthesize correctly, your programs won't run correctly. And if you don't indent them correctly, they'll be hard to understand.

The syntax of Scheme is more similar to that of C or Pascal than it may appear at first glance. After all, almost all programming languages are based on nested (statements or) expressions. Like C or Pascal, Scheme is free-form, and you can indent it any way you want.

Some people write Scheme code indented like C, with closing parentheses lined up under opening parentheses to show nesting. (People who do this are usually beginners who haven't learned to use an editor properly, as I'll explain later.) They might write

;; A poorly indented if expression

The first version looks a little more like C, but it's not really easier to read. The second example shows its structure just as clearly if you know how to read Scheme, and is in fact easier to read because it's not all stretched out. The second example takes up less space on the page or a computer screen. (This is important when editing code in a window and doing other things in another window--you can see more

http://www.federated.com/~jim/schintro-v14/schintro_24.html (1 of 2)11/3/2006 8:54:35 PM

An Introduction to Scheme and its Implementation - Parentheses and Indenting

of your program at a time.)

There are a couple of things to keep in mind about parentheses in Scheme. The first thing is that parentheses are significant. In C or Pascal, you can often leave parentheses out, because of "operator precedence parsing," where the compiler figures out the grouping. More importantly, you can often add extra parentheses around expressions without affecting their meanings.

This is not true in Scheme! In Scheme, the parentheses are not just there to clarify the association of operators. In Scheme, parentheses are not optional, and putting extra parentheses around things changes their meaning. For example, the expression foo is a variable reference, whose effect is to fetch the value of the variable foo. On the other hand, the expression (foo) is a call to the procedure named foo with zero arguments.

(Notice that even in C, it's not generally acceptable to write a procedure call with too few parentheses or too many: a call foo(a, b) can't be written just foo a, b or as foo((a, b)).)

In general, you have to know where parentheses are needed and where they are not, which requires understanding Scheme's rules. Some parentheses indicate procedure calls, while others are just delimiters of special forms. Luckily, the rules are simple; they should become very clear in the next chapter or two.

The other thing to know about parentheses is that they have to match. For every opening parenthesis there has to be a closing parenthesis, and of course it must be in the right place.

Let Your Editor Help: Editors Make Parenthesis Matching Easy

Indenting Simple Things: Procedure calls and simple control constructs

Indenting cond: Cond is unreadable without proper indenting

Indenting Procedure Definitions

Go to the first, previous, next, last section, table of contents.

http://www.federated.com/~jim/schintro-v14/schintro_24.html (2 of 2)11/3/2006 8:54:35 PM

An Introduction to Scheme and its Implementation - Let Your Editor Help

Go to the first, previous, next, last section, table of contents.

Let Your Editor Help You

Matching parentheses is easy if you have a decent text editor. For example, in vi, you can position the cursor over a parenthesis and hit %, and it will scan forward or backward (from an opening or closing parenthesis, respectively) to find the matching parenthesis and highlight it, skipping over any matched parenthesis pairs; it will warn you if no match is found.

Most editors have a feature like this. Learn to use it. It's usually easy to get the opening parentheses right, and then if you're in doubt, use the editor to make sure you get the closing parentheses in the right place.

Some editors, like Emacs, have special modes for editing Lisp and Scheme. This can be helpful, but just helping match parentheses is the crucial thing for an editor for Scheme. One of the nice things about the Emacs Scheme mode is that it will indent your code automatically if you like, which will show you whether your expressions nest the way they think you do--if you don't get the parentheses right, the text will look funny and tip you off to your error.

(One Emacs mode for Scheme is cmuscheme, which is available from the usual sources of Emacs mode code. It's just a set of Emacs Lisp routines that customizes Emacs to "understand" Scheme syntax and help you format it. You use the Emacs Lisp package cmuscheme.el, and it gives you a handy Scheme editing mode. It's available from the Scheme Repository.)

Even without a special package, an editor can help you a lot. For example, most modes in Emacs automatically match parentheses, flashing an opening parentheses when you type the corresponding closing parenthesis. A few minutes figuring out how your editor matches parentheses will save you a lot of time.

Go to the first, previous, next, last section, table of contents.

http://www.federated.com/~jim/schintro-v14/schintro_25.html11/3/2006 8:54:40 PM

An Introduction to Scheme and its Implementation - Indenting Simple Things

Go to the first, previous, next, last section, table of contents.

Indenting Procedure Calls and Simple Control Constructs

Go to the first, previous, next, last section, table of contents.

http://www.federated.com/~jim/schintro-v14/schintro_26.html11/3/2006 8:54:45 PM

An Introduction to Scheme and its Implementation - Indenting cond

Go to the first, previous, next, last section, table of contents.

Indenting cond

Be careful about parentheses and indenting with cond. Notice that the expressions within a test-action clause are indented by only one character, but that's very significant. Without that indenting, a cond is very hard to read.

Suppose we replace the following awkward if expression with a cond.

;; awkward if expression requiring begins to sequence actions in branches (if (a)

(begin (b) (c)) (begin (e) (f))) We could write it like this:

(cond ((a)

Sometimes, when the clauses of a cond are small, a whole clause will be written out horizontally. The above example is likely to be written like this:

(cond ((a) (b) (c)) (else (d) (e)))

Also be careful about the parentheses around condition expressions. Notice that the parentheses around (a) are there because the condition is call to a with zero arguments, not because you always put parentheses around the condition expression. (Notice that there are no parentheses around #t, and there wouldn't be parentheses around a if we just wanted to test the value of the variable a, rather than call it and test the result.)

Go to the first, previous, next, last section, table of contents.

http://www.federated.com/~jim/schintro-v14/schintro_27.html11/3/2006 8:54:59 PM

An Introduction to Scheme and its Implementation - Indenting Procedure Definitions

Go to the first, previous, next, last section, table of contents.

Indenting Procedure Definitions

As I hinted earlier, there's a special rule for indenting procedure definitions. You generally indent the body of a procedure a few characters (I use 3), but you don't line the body expressions up directly under the list of variable names.

Don't do this:

(define (double x) (+ x x))

If you do this, a procedure definition looks like a procedure call, or a normal variable definition. To make it clearer you're defining a procedure, do this:

(define (double x) (+ x x))

This makes it clear that the (double x) is a different kind of thing from (+ x x). The former declares how the procedure can be called, and the latter says what it will do.

Go to the first, previous, next, last section, table of contents.

http://www.federated.com/~jim/schintro-v14/schintro_28.html11/3/2006 8:55:04 PM

An Introduction to Scheme and its Implementation - Values are Pointers

Go to the first, previous, next, last section, table of contents.