# Some Things to Remember About Style

updated 1 July 2003
style up to recursion
1. Give variables and procedure good names
• If you write a procedure that returns only #t or #f, have that procedure end with a ?

• It should be (reasonably) easy to tell what your procedure might do just by looking at its name. It should be (reasonably) easy to tell what kinds of arguments your procedure takes by looking at the names of its placeholders.

• In general, avoid using variable names that are only one letter long. It is reasonably OK to use n for integers, but try to use num or something like that for generic numbers. It's also OK to use s for generic sentences or w for generic words, but only if you can't find better names. Also, if a variable can take any data type and you just can't come up with a good name, you can use x, y, or z.

• Never use the name of a procedure (like word, sentence, or list) as the name of an argument for your function.
Examples: Don't write this:
```(define (bob x) ;;what is bob? what data types can x be?
(= (remainder x 2) 0))
```
when you could write this:
```(define (even? n)        ;;even? returns a boolean and it asks if an
(= (remainder n 2) 0)) ;;integer (n) is even
```
and don't write this:
```(define (short-word word)
(< (count word) 3))
```
when you could write this:
```(define (short-word? wd)
(< (count wd) 3))
```
2. Don't write code that you don't need
• You never need to write anything like (if (even? n) #t #f). If n is even, (even? n) returns #t. If n is odd, (even? n) returns #f. How is this different from the big if above? It's not. Similarly, don't write something like (if (even? n) #f #t). This is exactly the same as saying (not (even? n)).

• Don't add extra base cases to a recursive function unless you actually need them. They can get in the way if you are trying to debug something.
Example:
```(define (sent-max num-sent)
(cond ((empty? num-sent) '()) ;;You don't want this line
((empty? (bf num-sent))
(first num-sent))
(else (max (first num-sent) (sent-max (bf num-sent))))))
```
Why is this bad? If you do something silly like (+ (sent-max '()) 4), you get an error from +, not sent-max!

• Don't bother to test if something is equal to #t. If you are careful when you write your code, all you will need to know is if something is true or false. The same goes for member. You don't need to test something like (not (equal? #f (member letter wd))).

• Don't include extra tests in a cond.
Example:
```(cond ((and (>= x 4) (even? y)) 'yes)
((and (>= x 4) (not (even? y))) 'no) ;;if you get here, y .... ;;can't be even!

(cond ((and (>= x 4) (even? y)) 'yes)
((>= x 4) 'no) ;;this is fine ....
```
• Don't put more than one expression in an else statement.
Example,
```(else (+ 4 7) (+ x y)) ;;you never see the results of (+ 4 7)!
```
For that matter, don't write more than one expression without connecting them somehow.
Example:
```(define (badidea1 x)
(+ x 9) (* 7 x)) ;;you do the (+ x 9), but it doesn't matter to
```
• Don't write an if without something to do if the test is false.
Example:
```(if (= x 8) 'absolutely) ;;what do if x isn't equal to 8? If x is
;;  always equal to 8, why have the if?
```
• Don't use and or or with only one argument. (and x) is the same thing as x.

• Similarly, don't write something like (sentence '(this is already a sentence)) or (word 'this_is_already_a_word). Neither of these actually do anything.

• You probably won't need to do this on a test, but when you do write code for the project, you should include comments that describe all of your big procedures. Also, put a comment any place that you do something complicated.

• If you really want to be fancy, you can include formal specifications for each important function you write. They look like this:
```;;;;;;;;;;;;;;;;;;;;; procedure name here
;;INPUTS: give the placeholder names and what data types they can be
;;REQUIRES: anything else about the variables (all positive, for
;; example)
;;RETURNS: tell what the procedure returns
;;EXAMPLE: give at least one example: show a procedure call and
;; tell what it returns. It never hurts to have a couple
;; of these. If your procedure returns several very different kinds
;; of data, include one test that shows each kind. If your procedure
;; returns only #t or #f, ;; show a test that returns #t and a test
;; that returns #f ;;
```
4. Make your code easy on the eyes
• Use indentation to make your code more readable. The Editor or Emacs do most of it for you. Do not write a big procedure in one line. This makes people who have to read it very angry.

• Keep all of the cases in a cond statement indented the same amount.

• If you are creating several variables in a let statement, put each one on a separate line and make sure they are all indented by the same amount.

• If a procedure has many arguments, or if some of the arguments are long, put them on several lines and make sure they are all lined up.
Example: don't do this:
```(define (quadratic-rule a b c) (se (/ (+ (- b) (sqrt (- (* b b) (* 4 a c)))) (* a 2)) (/ (- (- b) (sqrt (- (* b b) (* 4 a c)))) (* a 2)))))
```
```(define (quadratic-rule a b c)
(se (/ (+ (- b) ;;add -b
(sqrt (- (* b b) to sqrt(b^2 - 4ac)
(* 4 a c))))
(* a 2)) ;;end of the first term
(/ (- (- b)
(sqrt (- (* b b) ;
(* 4 a c))))
(* a 2)))) ;;end of the second term
```
• Don't write procedures that just go on and on and on. Limit your procedures to about 24 lines of code. If they are much longer than this, try to break them into several different procedures.

5. More if and cond stuff
• Use if when you want to decide between two things and cond when you want to decide among more than two things.

• Make sure that you always use an else! If you can't think of anything good to put in the else, put an error message.
Example: don't do
```(define (badidea3 x)
(cond ((word? x) (sentence 'word x))
((sentence? x) x)))
```
```(define (betteridea x)