Programs are easier to read and to understand when they are written in a familiar style and follow standard coding conventions. Most organizations that develop software therefore require programmers to write programs that follow the organization's preferred style and coding conventions. Programs are generally written once, read many times, and edited over and over again. Style conventions help both you and any other programmer using your code (such as your homework partner) to more easily understand what you were thinking when you wrote the code.
In addition to following the Design Recipe, all code must adhere to the following style guidelines, which are intended to make your code easier to read, debug, and edit.
; my-function : Number String -> Number
; Add double the string-length to twice the number cubed
(check-expect (my-function 2 "hi") 20)
(check-expect (my-function 3 "hello") 64)
(define (my-function n s)
(+ (double (cube-num n)) (double-length s)))
; cube-num : Number -> Number
; Produces the cube of this number
(check-expect (cube-num 0) 0)
(check-expect (cube-num 5) 125)
(define (cube-num n)
(expt n 3))
; double-length : String -> Number
; Produces twice the length of this string
(check-expect (double-length "") 0)
(check-expect (double-length "goodbye") 14)
(define (double-length s)
(double (string-length s)))
; double : Number -> Number
; Computes 2n
(check-expect (double 0) 0)
(check-expect (double 4) 8)
(define (double n)
(* n 2))
Use names that make sense with respect to the problem, for your data definitions, field names, functions, constants, and parameters. Also make sure to capitalize terms appropriately based upon their type...
Constants | All caps with dashes between words |
(define MY-NUMBER-EXAMPLE 10)
(define SUN-IMG (circle 35 "solid" "yellow"))
Structure names/fields and Function names/parameters | All lower-case with dashes between words (known as kebab-case) |
(define-struct struct-name [field-name])
(define (my-function-name my-param-name)
(+ my-param-name 3))
Data Types | Title case (e.g., ThisIsADataType or ThisIsAnotherOne) |
; ------------------------ GOOD
(define (f-good l)
(cond [(empty? l) 0]
[else (f-good (rest l))])) ; HERE
; ------------------------ BAD
(define (f-bad l)
(cond [(empty? l) 0]
[else (f-bad (rest l))]
) ; NOT HERE
) ; OR HERE
; ----------------- GOOD
(define (foo-good-short-name x y z)
(max (* x y) ; Break after each argument to max,
(* y z) ; and align all arguments in a column
(* x z) ; (This works best with short-named functions)
(* x y z)))
; ----------------- GOOD
(define (foo-good-longer-name x y z)
(max ; Break after max itself
(* x y) ; Then indent each argument 1 space
(* y z) ; (This works better when function names are long)
(* x z)
(* x y z)))
; ----------------- BAD
(define (foo-bad x y z)
(max (* x y) (* y ; These linebreaks make it hard
z) ; to follow what part of the
(* x z) (* x ; function we are in and should
y ; be avoided.
z)))
place-image
might easily fit on one line, and logically form a pair of coordinates, and so could stay on one line in good style.
Some more examples...
; ---------------- All breaks to avoid...
(define ; Don't break here
(foo x y z)
...)
(define-struct ; Don't break here
foo [x y z])
(define-struct foo ; or here
[x y z])
(if (> x 2) #true #false)
(> x 2)
could be any Boolean expression) should instead just be replaced by...
(> x 2)