The Style
Basics
In addition to following the design recipe, all code must adhere to the following basic style guidelines:
Organize your program top-down, regardless of how you actual work through your wish list. The phrase "top down" means that project files consist of a general purpose statement, a data definition and a constant definition section, a main function, followed by sections for handler functions, and wrapped up by general utility functions.
Separate distinct sections of your program with dashed lines that are exactly 80 columns wide.
Arrange your functions according to the design recipe. Place short and informative test cases between the signature and the function definition. Place any additional long or complicated test cases below the function or at the bottom of your program in a separate test section.
Use (function, constant, parameter) names that make sense with respect to the problem.
Design concise functions. No function should span more than five to eight lines. If it does, reconsider your interpretation of the "one task, one function" guideline.
If a function consumes a complex argument and must perform several different tasks, design several functions that all consume the argument, produce a value in the same data collection, and hand it over to the next function:;; ------------------------------------------------- GOOD
;; HHState -> HHState
(define (hungry-henry-action-per-clock-tick hh-world-state)
(bump-tick-value
(eat-all-cup-cakes-in-reach
(move-hungry-henry-closer-to-wp hh-world-state))))
;; HHState -> HHState
(define (bump-tick-value hh-world-state) ...)
;; HHState -> HHState
(define (eat-all-cup-cakes-in-reach hh-world-state) ...)
;; HHState -> HHState
(define (move-hungry-henry-closer-to-wp hh-world-state) ...)
Piling the code from these three functions into the first one would yield a confusing mess.Keep lines narrow. No line should span more than 80 characters. See bottom right of DrRacket or use its edit -> find longest line menu.
Break lines at those points suggested by HtDP.
Programs use the parentheses style displayed in HtDP and this web page:
;; ------------------------ GOOD
(define (f l)
(cond [(empty? l) 0]
[else (f (rest l))]))
;; ------------------------ BAD
(define (f l)
(cond [(empty? 1) 0]
[else (f (rest l))]
)
)
The dangling parentheses in the second code excerpt are considered extremely bad style. You will lose all style points for using it even once.
Not observing these very basic guidelines leads to unreadable code and to loss of points.
Testing & Randomness
When you design functions that create (pseudo-)random results, do not give up on testing. To make this guide concrete, consider this example:
; Number Number -> Posn ; create a Posn located at random points in [0,width) x [0,height)
(check-expect (posn? (create-cupcake 100 200)) true) (check-expect (posn? (create-cupcake 20 1000)) true)
; Number Number Posn -> Boolean ; property tester
(define (in-range? width height p) (and (<= 0 (posn-x p) width) (<= 0 (posn-y p) height))) (check-expect (in-range? 100 200 (create-cupcake 100 200)) true) (check-expect (in-range? 20 1000 (create-cupcake 20 1000)) true)
; N -> [List-of Posn] ; create the given number of cupcakes
(define (create-many-cupcakes n) (local ((define (one i) (create-cupcake SCENE-WIDTH SCENE-HEIGHT))) (build-list n one)))
; Posn -> Boolean ; property tester
(define (one? p) (in-range? SCENE-WIDTH SCENE-HEIGHT p)) (check-expect (andmap one? (create-many-cupcakes 100)) true)