[Style] more revisions
This commit is contained in:
parent
a496213549
commit
38eb1efa91
|
@ -6,22 +6,58 @@
|
|||
|
||||
@section{Commit}
|
||||
|
||||
So what is the major lesson of this section? When you fix a bug, make sure
|
||||
to commit (1) the code delta, (2) the new test case, and (3) the revised
|
||||
docs (if applicable) in one batch. If the creation of a single commit is
|
||||
too complex of if you wish to factor out one of the commits, please push
|
||||
all pieces at once. That way the code base is always in a state where
|
||||
code, tests, and documentation are in sync, and readers of commit messages
|
||||
can evaluate changes completely.
|
||||
@bold{New feature commit:} Commit the new feature, its tests, and its
|
||||
documentations as you wish, but please push them together.
|
||||
|
||||
@section{No Commit ``Bombs'' Please}
|
||||
@bold{Bug fix commit:} When you fix a bug, make sure to commit (1) the
|
||||
code delta, (2) the new test case, and (3) the revised docs (if
|
||||
applicable) in one batch. If the creation of a single commit is too
|
||||
complex of if you wish to factor out one of the commits, please push all
|
||||
pieces at once. That way the code base is always in a state where code,
|
||||
tests, and documentation are in sync, and readers of commit messages can
|
||||
evaluate changes completely.
|
||||
|
||||
@bold{Style change commit:} Submit changes to the style of a file
|
||||
separately from changes to its behavior (new features, bugs).
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{No Commit ``Bombs,'' Please}
|
||||
|
||||
On occasion, you will find that you are spending a significant amount of
|
||||
time working with someone else's code. To avoid potentially painful
|
||||
merges, please (1) inform the author when you create the branch and (2)
|
||||
set the mail hook @margin-note*{See @hyperlink["http://tmp.barzilay.org/git.txt"]{Eli's write-up} on using git in PLT for
|
||||
information on the mechanics.} so that git sends a commit message to both
|
||||
you and the original author. Furthermore, you should test your changes on
|
||||
the actual code base. In some cases it is acceptable to delay such tests,
|
||||
e.g., when you will not know for a long time whether the performance
|
||||
implication allow a commit to the PLT repository.
|
||||
set the mail hook so that git sends a commit message to both you and the
|
||||
original author. Furthermore, you should test your changes on the actual
|
||||
code base. In some cases it is acceptable to delay such tests, e.g., when
|
||||
you will not know for a long time whether the performance implication
|
||||
allow a commit to the PLT repository.
|
||||
|
||||
@margin-note*{See @hyperlink["http://tmp.barzilay.org/git.txt"]{Eli's
|
||||
write-up} on using git in PLT for details.}
|
||||
As a reminder, here are the essential elements of git for working on a
|
||||
fork:
|
||||
@itemlist[
|
||||
|
||||
@item{setup a fork:
|
||||
|
||||
@verbatim{
|
||||
ssh pltgit fork plt eli/my-plt}
|
||||
}
|
||||
|
||||
@item{setup mail notifications:
|
||||
|
||||
@verbatim{
|
||||
ssh pltgit config set eli/my-plt hooks.counter true
|
||||
ssh pltgit config set eli/my-plt hooks.mailinglist "eli at barzilay.org, ..."
|
||||
}}
|
||||
|
||||
@item{allow someone else to push commits to my repository:
|
||||
|
||||
@verbatim{
|
||||
ssh pltgit setperms eli/my-plt
|
||||
RW eli
|
||||
RW someone-else
|
||||
^D
|
||||
}}
|
||||
]
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#lang scribble/base
|
||||
|
||||
@(require "shared.rkt")
|
||||
@(require "shared.rkt" scribble/eval)
|
||||
|
||||
@title{Choosing the Right Construct}
|
||||
|
||||
|
@ -9,13 +9,20 @@ Although the Racket designers don't think that there is one right way for
|
|||
everything, we prefer certain constructs in certain situations for consistency
|
||||
and readability.
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{Comments}
|
||||
|
||||
Following Lisp and Scheme tradition, we use a single semicolon for in-line
|
||||
comments (to the end of a line) and two semicolons for comments that start
|
||||
a line. Think of the second semicolon as making an emphatic point.
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{Definitions}
|
||||
|
||||
Racket comes with quite a few definitional constructs, including
|
||||
@scheme[let], @scheme[let*], @scheme[letrec], and @scheme[define]. Except
|
||||
for the last one, definitional construct increase the indentation level. We
|
||||
therefore request that you favor @scheme[define] when feasible.
|
||||
for the last one, definitional construct increase the indentation level.
|
||||
Therefore, favor @scheme[define] when feasible.
|
||||
|
||||
@compare[
|
||||
@racketmod[#:file
|
||||
|
@ -111,27 +118,35 @@ Keep expressions small. Name intermediate results.
|
|||
@racketmod[#:file
|
||||
@tt{good}
|
||||
racket
|
||||
(define (distance0 p)
|
||||
(define x (posn-x p))
|
||||
(define y (posn-y p))
|
||||
(sqrt (+ (sqr x) (sqr y))))
|
||||
(define (next-month date)
|
||||
(define day (first date))
|
||||
(define month (second date))
|
||||
(define year (third date))
|
||||
(if (= month 12)
|
||||
`(,(+ day 1) 1 ,year)
|
||||
`(,day ,(+ month 1) ,year)))
|
||||
]
|
||||
@; -----------------------------------------------------------------------------
|
||||
@racketmod[#:file
|
||||
@tt{bad}
|
||||
racket
|
||||
(define (distance0 p)
|
||||
(sqrt
|
||||
(+ (sqr (posn-x p))
|
||||
(sqr (posn-y p)))))
|
||||
(define (next-month d)
|
||||
(if (= (cadr d) 12)
|
||||
`(,(+ (car d) 1) 1 ,(caddr d))
|
||||
`(,(car d)
|
||||
,(+ (cadr d) 1)
|
||||
,(caddr d))))
|
||||
]
|
||||
]
|
||||
(It is difficult to illustrate this point with a small example. Please
|
||||
give intermediate names a try.)
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{Structs vs Lists}
|
||||
|
||||
Use @racket[struct]s when you represent a combination of a fixed number of
|
||||
values. Or, don't use lists when structures will do.
|
||||
Use @racket[struct]s when you represent a combination of a small and fixed
|
||||
number of values. For fixed length (long) lists, add a comment or even a
|
||||
contract that states the constraints.
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{Lambda vs Define}
|
||||
|
@ -167,7 +182,12 @@ racket
|
|||
@; -----------------------------------------------------------------------------
|
||||
@section{Identity Functions}
|
||||
|
||||
The identity function is @racket[values]. Try it with @racket[(values 1 2 3)].
|
||||
The identity function is @racket[values]:
|
||||
|
||||
@examples[
|
||||
(map values '(a b c))
|
||||
(values 1 2 3)
|
||||
]
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{List Traversals}
|
||||
|
@ -196,7 +216,9 @@ racket
|
|||
;; examples:
|
||||
(sum-up '(1 2 3))
|
||||
(sum-up #(1 2 3))
|
||||
(sum-up (open-input-string "1 2 3"))
|
||||
(sum-up
|
||||
(open-input-string
|
||||
"1 2 3"))
|
||||
])
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
|
@ -216,7 +238,7 @@ racket
|
|||
])
|
||||
]
|
||||
|
||||
Note: @racket[for] traversals of user-defined sequences tend to be
|
||||
@bold{Note}: @racket[for] traversals of user-defined sequences tend to be
|
||||
slow. If performance matters in these cases, you may wish to fall back on
|
||||
your own traversal functions.
|
||||
|
||||
|
@ -236,18 +258,25 @@ racket
|
|||
(first (second msg)))
|
||||
]
|
||||
@; -----------------------------------------------------------------------------
|
||||
@racketmod[#:file
|
||||
@(begin
|
||||
#reader scribble/comment-reader
|
||||
[racketmod #:file
|
||||
@tt{bad}
|
||||
racket
|
||||
...
|
||||
;; Message -> String
|
||||
(define-syntax-rule
|
||||
(message-name msg)
|
||||
;; ===>
|
||||
;; ==>>
|
||||
(first (second msg)))
|
||||
]
|
||||
)
|
||||
]
|
||||
|
||||
A function is immediately useful in a higher-order context. For a macro,
|
||||
achieving the same goal takes a lot more work.
|
||||
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{Parameters}
|
||||
|
||||
|
|
|
@ -37,17 +37,23 @@ watching Matthew, Robby, Shriram and others create the original code base}
|
|||
@nested[#:style 'inset]{@italic{It is the way we choose to fight our bugs that
|
||||
determines our character, not their presence or absence.} -- Robby, in response}
|
||||
|
||||
Complete correctness is a perfectionist goal beyond the reach of PLT. All
|
||||
Since complete correctness is a perfectionist goal, PLT aims to release
|
||||
good code and to improve it as soon as possible and necessary. All
|
||||
software has mistakes. If they are unknown, the software isn't being
|
||||
used. The goal is, however, to ensure some basic level of correctness
|
||||
before a feature is released and to ensure that the same mistake isn't
|
||||
introduced again.
|
||||
|
||||
Formulate test suites. Use unit testing. Use random testing. Use fuzz
|
||||
testing. Test!
|
||||
Add tests to the appropriate test suites; most are found in
|
||||
@tt{collects/tests/} in your PLT repository. @margin-note*{Due to
|
||||
historical reasons, a few collections come with their own local test
|
||||
suites.} These test suites suggest a culture of testing per tool or
|
||||
language; follow it. Formulate new test suites in the same collection. Use
|
||||
unit testing. Use random testing. Use fuzz testing. Test!
|
||||
|
||||
Run the test suites before you commit. Read DrDr's emails; don't ignore
|
||||
them.
|
||||
Run the test suites before you commit. Read
|
||||
@hyperlink["http://drdr.racket-lang.org/"]{DrDr}'s emails; do not ignore
|
||||
them.
|
||||
|
||||
When you debug, formulate a test case first. Put it into the test suite for
|
||||
the component so the mistake will never be accidentally re-introduced.
|
||||
|
@ -85,16 +91,12 @@ Editing code without an existing test suite is like flying blind. If there
|
|||
@; -----------------------------------------------------------------------------
|
||||
@section{Maintenance}
|
||||
|
||||
Comprehensible code is maintainable. Maintainable code must be easily
|
||||
readable, and the difficulty is that Racket naturally favors the writer,
|
||||
not the reader. And it is precisely for this reason that we need to obey
|
||||
rules.
|
||||
|
||||
Code is comprehensible when you can understand its external purpose. To
|
||||
this end, code must come with external documentation. Released code must
|
||||
have documentation. A change to the external behavior of code must induce
|
||||
a simultaneous change to its documentation---``simultaneous'' means that the
|
||||
two changes are in the same commit to the code base.
|
||||
Comprehensible code is maintainable. Code is comprehensible when you can
|
||||
understand its external purpose. To this end, code must come with external
|
||||
documentation. Released code must have documentation. A change to the
|
||||
external behavior of code must induce a simultaneous change to its
|
||||
documentation---``simultaneous'' means that the two changes are in the
|
||||
same ``push'' to the code base.
|
||||
|
||||
Without adherence to basic elements of style and some internal
|
||||
documentation, code comprehension becomes impossible. The rest of this
|
||||
|
@ -104,13 +106,14 @@ Without adherence to basic elements of style and some internal
|
|||
Readability is not the same as code with documentation, but documentation
|
||||
is a part of it all. For style rules on documenting code, refer to the
|
||||
@hyperlink["http://docs.racket-lang.org/scribble/how-to-doc.html#%28part._reference-style%29"]{style
|
||||
guide} in the Scribble manual. Ideally documentation comes in two parts:
|
||||
a ``Guide'' section, which explains the purpose and suggests use cases, and
|
||||
a traditional ``Reference'' section, which presents the minutae. Also
|
||||
consider adding examples for each function and construct in your
|
||||
``Reference'' section. Finally, ensure you have all the correct
|
||||
@tt{for-label} @tt{require}s and make use of other useful
|
||||
cross-references.
|
||||
guide} in the Scribble manual. Ideally documentation comes in two parts,
|
||||
possibly located in the same document: a ``Guide'' section, which explains
|
||||
the purpose and suggests use cases, and a traditional ``Reference''
|
||||
section, which presents the minutae. The documentation for HtDP/2e
|
||||
teachpacks is an example where the two parts are collocated. Also consider
|
||||
adding examples for each function and construct in your ``Reference''
|
||||
section. Finally, ensure you have all the correct @tt{for-label}
|
||||
@tt{require}s and make use of other useful cross-references.
|
||||
|
||||
|
||||
Having said that, the production of a system like Racket occasionally
|
||||
|
|
|
@ -35,11 +35,11 @@ Many pieces of the code base don't live up to the rules yet. Here is how
|
|||
@emph{Do} run the test suites, and do @emph{not} change the behavior of
|
||||
the file.
|
||||
|
||||
Also, we encourage everyone to look over the commit messages. If you see
|
||||
problems with the code deltas, let the contributor know. If you see a bug
|
||||
fix without docs and tests, let the contributor know. Code should be
|
||||
viewed by more than one person because a second person is likely to catch
|
||||
logical mistakes, performance problems, and unintended effects.
|
||||
Also, look over the commit messages. If you see problems with the code
|
||||
deltas, let the contributor know. If you see a bug fix without docs and
|
||||
tests, let the contributor know. Code should be viewed by more than one
|
||||
person because a second person is likely to catch logical mistakes,
|
||||
performance problems, and unintended effects.
|
||||
|
||||
@bold{Request} This document isn't complete and it isn't perfect. Consider
|
||||
it a call for improvements and suggestions. If you have ideas, contact
|
||||
|
@ -53,10 +53,12 @@ Also, we encourage everyone to look over the commit messages. If you see
|
|||
|
||||
@; -----------------------------------------------------------------------------
|
||||
|
||||
@include-section["correct-maintain-speed.scrbl"]
|
||||
@include-section["some-performance.scrbl"]
|
||||
@include-section["unit.scrbl"]
|
||||
@include-section["constructs.scrbl"]
|
||||
@include-section["textual.scrbl"]
|
||||
@include-section["branch-and-commit.scrbl"]
|
||||
@include-section{correct-maintain-speed.scrbl}
|
||||
@include-section{some-performance.scrbl}
|
||||
@include-section{unit.scrbl}
|
||||
@include-section{constructs.scrbl}
|
||||
@include-section{textual.scrbl}
|
||||
@include-section{branch-and-commit.scrbl}
|
||||
@include-section{acknowledgment.scrbl}
|
||||
|
||||
@include-section{todo.scrbl}
|
||||
|
|
|
@ -260,10 +260,12 @@ rndr-st
|
|||
|
||||
sendMessageToClient
|
||||
|
||||
trvrs-frst
|
||||
traverse_forest
|
||||
])
|
||||
]
|
||||
@;
|
||||
Note that _ (the underline character) is also classified as bad
|
||||
Racketeering.
|
||||
|
||||
Another widely used convention is to @emph{prefix} a function name with the data
|
||||
type of the main argument. This convention generalizes the selector-style
|
||||
|
@ -306,9 +308,27 @@ Finally, in addition to regular alphanumeric characters, Racketeers use a
|
|||
|
||||
@row-table[
|
||||
@row[symbol kind example]
|
||||
@row[? "predicates and boolean-valued functions" boolean?]
|
||||
@row[! "setters and field mutators" set!]
|
||||
@row[% "classes" game-state%]
|
||||
@row[^ "unit signatures" game-context^]
|
||||
@row["@" units testing-context@]
|
||||
@row[? "predicates and boolean-valued functions" boolean?]
|
||||
@row[! "setters and field mutators" set!]
|
||||
@row["#:" "keywords" #:dest-dir]
|
||||
@row[% "classes" game-state%]
|
||||
@row[<%> "interfaces" dc<%>]
|
||||
@row[^ "unit signatures" game-context^]
|
||||
@row["@" "units" testing-context@]
|
||||
@row["#%" "kernel identifiers" #:app]
|
||||
]
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{Graphical Syntax}
|
||||
|
||||
Do not use graphical syntax (comment boxes, XML boxes, etc).
|
||||
|
||||
The use of graphical syntax makes it impossible to read files in
|
||||
alternative editors. It also messes up some revision control systems.
|
||||
When we figure out how to save such files in an editor-compatible way, we
|
||||
may relax this constraint.
|
||||
|
||||
@; -----------------------------------------------------------------------------
|
||||
@section{End of File}
|
||||
|
||||
End files with a newline.
|
||||
|
|
14
collects/scribblings/style/todo.scrbl
Normal file
14
collects/scribblings/style/todo.scrbl
Normal file
|
@ -0,0 +1,14 @@
|
|||
#lang scribble/base
|
||||
|
||||
@(require "shared.rkt")
|
||||
|
||||
@title{Todo List, Call for Contributions}
|
||||
|
||||
@itemlist[#:style 'ordered
|
||||
|
||||
@item{Write a section on when macros, when functions.}
|
||||
|
||||
@item{Write a section on how to design test cases.}
|
||||
|
||||
@item{Find and link to good/bad examples in the code base.}
|
||||
]
|
|
@ -290,6 +290,9 @@ With @racketmodname[rackunit], test suites can be defined within the
|
|||
If your function or method consumers more than two parameters, consider
|
||||
keyword arguments so that call sites can easily be understood.
|
||||
|
||||
Similarly, if your function or method consumers two (or more)
|
||||
@emph{optional} parameters, keyword arguments are a must.
|
||||
|
||||
Please write a purpose statement for your function.
|
||||
If you can, add an informal type and/or contract statement.
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user