COS 371: Programming Languages

Spring 2022

Scheme Style Guide

Names

  1. Use descriptive variable names.
  2. Use lowercase names, possibly with-hyphens, not with_underscores or camelCase.
  3. Use lst as the variable name for a list.
  4. Predicates (those that return true or false) ends in ?, like prime?, not isPrime.
  5. Procedures with side effect ends in !, like set! and set-car!. [These start half way through the semester.]

Parentheses, linebreaks, and indentation

Scheme code should be readable without counting parentheses!
  1. Trust DrRacket's automatic indentation. (I have never found a need to go against it.) Select a code block and press Tab to re-auto-indent.
  2. Do not put parentheses on their own line.

    Good:

    (define factorial
      (lambda (n)
        (if (zero? n)
            1
            (* n (factorial (- n 1))))))
    
    Bad:
    (define  ; bad, do NOT put a line break here; see below.
      factorial
      ( lambda ( n )(if (zero? n )
    ;  ^        ^ ^ ^           ^ all bad, see next item.
            1
            (* n (factorial (- n 1)))
        ) ; bad
      ) ; bad
    ) ; bad
    
    Not only is the second using extra lines for no real purpose, the first style allows you to simply keep adding ) until the parentheses are balanced (as judged by DrRacket's highlighting).
  3. Do not put spaces after ( or before ); do put space between ) (.
  4. Put subexpressions all on the same line or all on different lines.

    Good:

    (+ 1 2 3 4 5)
    
    (+ (- 1 2)
       (* 3 4 5)
       (/ 6 7))
    
    Bad:
    (+ (- 1 2)
       (* 3 4) 5
       (/ 6 7))
    
    It's easy to miss the 5 hiding on the same line as (* 3 4).
  5. Leave the first subexpression on the same line in define, lambda, if, let forms. (See above and below.) The cond form may be an exception to this rule:
  6. Line up cond clauses.
    (define fib
      (lambda (n)
        (cond
          ((<= n 0)  0)
          ((= n 1)   1)
          (else      (+ (fib (- n 1))
                        (fib (- n 2)))))))
    
  7. Add blank lines as appropriate. Just like writing English in paragraphs. Don't add too many blank lines (no one wants to read an essay consisting of single-sentence paragraphs) nor too few (pages of text with no organization).
  8. Don't have excessively long lines. Typically try to keep lines shorter than 80 characters.

Scheme features

(This section may not make sense yet.)
  1. Avoid using boolean literals #t or #f. Likely the expression can be simplified:
    (if (equal? a b) #t #f)    -->   (equal? a b)
    (if a b #f)                -->   (and a b)
    
  2. Use cond instead of a nest of if forms.
  3. Consider using let* instead of a nest of let forms.
  4. Avoid global variables.
  5. Avoid assignment/mutation. [Even after being granted such power in the second half of the semester.]

Documentation

  1. Use ;;; triple semicolons at the top of a file to document author name(s) and the purpose of the program.
  2. Use ;; double semicolons to document each procedure, describing briefly what it does.
  3. Use ; single semicolon to add short comments about certain lines, but...
  4. Do not comment every line of code.
  5. Comment on tricky things.

References

Here are some style guides I looked at when compiling this document.
  1. Eli Barzilay: extremely good style guide for Racket, which is very close to Scheme.
  2. Scheme wiki: explains some of the rationale behind these guidelines quite well.
  3. Dartmouth: good examples and explanations.