[Style] modules and tables
This commit is contained in:
parent
dbfbd6e860
commit
4c57167af7
|
@ -14,6 +14,7 @@
|
||||||
(all-from-out scribble/manual))
|
(all-from-out scribble/manual))
|
||||||
|
|
||||||
(provide
|
(provide
|
||||||
|
codebox
|
||||||
compare ;; create a comparison box for two code snippets
|
compare ;; create a comparison box for two code snippets
|
||||||
;; good ;; label a code fragment 'good' [doesn't work]
|
;; good ;; label a code fragment 'good' [doesn't work]
|
||||||
;; bad ;; label a code fragment 'bad' [doesn't work]
|
;; bad ;; label a code fragment 'bad' [doesn't work]
|
||||||
|
@ -30,6 +31,11 @@
|
||||||
(define stuff (list (list stuff1) (list stuff2)))
|
(define stuff (list (list stuff1) (list stuff2)))
|
||||||
(table (sty 2 500) (apply map (compose make-flow list) stuff)))
|
(table (sty 2 500) (apply map (compose make-flow list) stuff)))
|
||||||
|
|
||||||
|
;; good: a code snippet in a box
|
||||||
|
(define (codebox stuff1)
|
||||||
|
(define stuff (list (list stuff1)))
|
||||||
|
(table (sty 1 700) (apply map (compose make-flow list) stuff)))
|
||||||
|
|
||||||
(define-syntax (column-table stx)
|
(define-syntax (column-table stx)
|
||||||
(syntax-case stx (col)
|
(syntax-case stx (col)
|
||||||
[(_ (col x ...) ...)
|
[(_ (col x ...) ...)
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#lang scribble/base
|
|
||||||
|
|
||||||
@(require "shared.rkt")
|
|
||||||
|
|
||||||
@title{Size Matters}
|
|
||||||
|
|
||||||
@; -----------------------------------------------------------------------------
|
|
||||||
@section{Code Units}
|
|
||||||
|
|
||||||
Keep functions small. Keep classes small. Keep units small. Keep modules small.
|
|
||||||
|
|
||||||
Anytime a unit of code looks incomprehensible, it is probably too
|
|
||||||
large. Break it up into smaller units. To bring across what these smaller
|
|
||||||
units compute, implement or serve, use meaningful names; see
|
|
||||||
@secref{names}. Conversely, if you can't come up with a good name for such
|
|
||||||
units, you are probably looking at the wrong kind of division; consider
|
|
||||||
alternatives.
|
|
|
@ -52,6 +52,6 @@ create code for the PLT code base.
|
||||||
|
|
||||||
@include-section["correct-maintain-speed.scrbl"]
|
@include-section["correct-maintain-speed.scrbl"]
|
||||||
@include-section["some-performance.scrbl"]
|
@include-section["some-performance.scrbl"]
|
||||||
@include-section["size.scrbl"]
|
@include-section["unit.scrbl"]
|
||||||
@include-section["constructs.scrbl"]
|
@include-section["constructs.scrbl"]
|
||||||
@include-section["textual.scrbl"]
|
@include-section["textual.scrbl"]
|
||||||
|
|
172
collects/scribblings/style/unit.scrbl
Normal file
172
collects/scribblings/style/unit.scrbl
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
#lang scribble/base
|
||||||
|
|
||||||
|
@(require "shared.rkt")
|
||||||
|
|
||||||
|
@title{Units of Code}
|
||||||
|
|
||||||
|
@; -----------------------------------------------------------------------------
|
||||||
|
@section{Module Interfaces}
|
||||||
|
|
||||||
|
The purpose of a module is to provide some services. @margin-note{The
|
||||||
|
modules we discuss in this section coincide with files.}
|
||||||
|
|
||||||
|
@centerline{Equip a module with a short purpose statement.}
|
||||||
|
|
||||||
|
Its interface describes which services it provides, and its body implements
|
||||||
|
the services. At least in principle others shouldn't have to read the
|
||||||
|
implementation ever, but it is quite likely that they have to read the
|
||||||
|
interface.
|
||||||
|
|
||||||
|
@centerline{Place the interface at the top of the module.}
|
||||||
|
|
||||||
|
@compare[
|
||||||
|
@;%
|
||||||
|
@(begin
|
||||||
|
#reader scribble/comment-reader
|
||||||
|
(racketmod #:file
|
||||||
|
@tt{good}
|
||||||
|
racket
|
||||||
|
|
||||||
|
;; This module implements
|
||||||
|
;; several game strategies.
|
||||||
|
|
||||||
|
(require "game-basics.rkt")
|
||||||
|
|
||||||
|
(provide
|
||||||
|
;; Strategy = GameState -> Action
|
||||||
|
|
||||||
|
;; Strategy
|
||||||
|
;; a GUI-based plug in for people
|
||||||
|
human-strategy
|
||||||
|
|
||||||
|
;; Strategy
|
||||||
|
;; a complete tree traversal
|
||||||
|
ai-1-strategy
|
||||||
|
|
||||||
|
;; Strategy
|
||||||
|
;; alpha-beta pruning traversal
|
||||||
|
ai-2-strategy)
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
(define (general-strategy p)
|
||||||
|
... )
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
... some 100 lines ...
|
||||||
|
(define human-strategy
|
||||||
|
(general-strategy create-gui))
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
... some 100 lines ...
|
||||||
|
(define ai-1-strategy
|
||||||
|
(general-strategy traversal))
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
... some 100 lines ...
|
||||||
|
(define ai-2-strategy
|
||||||
|
(general-strategy alpha-beta))))
|
||||||
|
@(begin
|
||||||
|
#reader scribble/comment-reader
|
||||||
|
(racketmod #:file
|
||||||
|
@tt{bad}
|
||||||
|
racket
|
||||||
|
|
||||||
|
;; This module implements
|
||||||
|
;; several game strategies.
|
||||||
|
|
||||||
|
(require "game-basics.rkt")
|
||||||
|
|
||||||
|
;; Strategy = GameState -> Action
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
(define (general-strategy p)
|
||||||
|
... )
|
||||||
|
... some 100 lines ...
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
(provide
|
||||||
|
;; Strategy
|
||||||
|
;; a GUI-based plug in for people
|
||||||
|
human-strategy)
|
||||||
|
|
||||||
|
(define human-strategy
|
||||||
|
(general-strategy create-gui))
|
||||||
|
... some 100 lines ...
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
(provide
|
||||||
|
;; Strategy
|
||||||
|
;; a complete tree traversal
|
||||||
|
ai-1-strategy)
|
||||||
|
|
||||||
|
(define ai-1-strategy
|
||||||
|
(general-strategy traversal))
|
||||||
|
... some 100 lines ...
|
||||||
|
|
||||||
|
;; ------------------------------------------------------------------------------------------
|
||||||
|
(provide
|
||||||
|
;; Strategy
|
||||||
|
;; alpha-beta pruning traversal
|
||||||
|
ai-2-strategy)
|
||||||
|
|
||||||
|
(define ai-2-strategy
|
||||||
|
(general-strategy alpha-beta))))
|
||||||
|
]
|
||||||
|
|
||||||
|
As you can see from this comparison, an interface shouldn't just be a
|
||||||
|
@scheme[provide] with a list of names. Each identifier should come with a
|
||||||
|
purpose statement.
|
||||||
|
|
||||||
|
@bold{Note} Following this documentation guideline is most applicable to
|
||||||
|
modules that are a component of a large application. It is less relevant
|
||||||
|
for a module in the Racket that comes with a full-fledged description in
|
||||||
|
the guide.
|
||||||
|
|
||||||
|
While a one-line purpose statement for a function is usually enough, syntax
|
||||||
|
should come with a description of the grammar clause it introduces
|
||||||
|
@emph{and} its meaning.
|
||||||
|
|
||||||
|
@codebox[
|
||||||
|
@(begin
|
||||||
|
#reader scribble/comment-reader
|
||||||
|
(racketmod #:file
|
||||||
|
@tt{good}
|
||||||
|
racket
|
||||||
|
|
||||||
|
(provide
|
||||||
|
;; (define-strategy (s:id a:id b:id c:id d:id)
|
||||||
|
;; action:definition-or-expression)
|
||||||
|
;;
|
||||||
|
;; (define-strategy (s board tiles available score) ...)
|
||||||
|
;; defines a function from an instance of player to a placement
|
||||||
|
;; The four identifier denote the state of the board,
|
||||||
|
;; the player's hand, the places where a tile can be
|
||||||
|
;; placed, and the player's current score.
|
||||||
|
define-strategy)
|
||||||
|
))]
|
||||||
|
|
||||||
|
If the performance of your module doesn't suffer too much from contracts,
|
||||||
|
consider using @scheme[provide/contract]. The use of type-like contracts
|
||||||
|
(constructor predicates that check only a tag) impose a tolerable overhead
|
||||||
|
and still discover simple mistakes.
|
||||||
|
|
||||||
|
Finally, a module consists of sections. It is good practice to separate the
|
||||||
|
sections with comment lines. You may want to write down purpose statements
|
||||||
|
for sections so that readers can easily understand which part of a module
|
||||||
|
implements which service. Alternatively, consider using the large letter
|
||||||
|
chapter headings in DrRacket to label the sections of a module.
|
||||||
|
|
||||||
|
@; -----------------------------------------------------------------------------
|
||||||
|
@section{Functions & Methods, Classes & Units}
|
||||||
|
|
||||||
|
@; -----------------------------------------------------------------------------
|
||||||
|
@section{Size Matters}
|
||||||
|
|
||||||
|
Keep functions small. Keep classes small. Keep units small. Keep modules small.
|
||||||
|
|
||||||
|
Anytime a unit of code looks incomprehensible, it is probably too
|
||||||
|
large. Break it up into smaller units. To bring across what these smaller
|
||||||
|
units compute, implement or serve, use meaningful names; see
|
||||||
|
@secref{names}. Conversely, if you can't come up with a good name for such
|
||||||
|
units, you are probably looking at the wrong kind of division; consider
|
||||||
|
alternatives.
|
Loading…
Reference in New Issue
Block a user