mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Google Common Lisp Style Guide updated to 1.10,
integrating more feedback from inside and outside Google.
This commit is contained in:
parent
8dba399b33
commit
0c584cb624
145
lispguide.xml
145
lispguide.xml
|
@ -2,9 +2,10 @@
|
||||||
<?xml-stylesheet type="text/xsl" href="styleguide.xsl"?>
|
<?xml-stylesheet type="text/xsl" href="styleguide.xsl"?>
|
||||||
<GUIDE title="Google Common Lisp Style Guide">
|
<GUIDE title="Google Common Lisp Style Guide">
|
||||||
|
|
||||||
|
|
||||||
<p align="right">
|
<p align="right">
|
||||||
|
|
||||||
Revision 1.8
|
Revision 1.10
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,9 +13,8 @@ Revision 1.8
|
||||||
Robert Brown
|
Robert Brown
|
||||||
</address>
|
</address>
|
||||||
|
|
||||||
|
|
||||||
<address>
|
<address>
|
||||||
François-René Rideau
|
<a HREF="mailto:tunes@google.com">François-René Rideau</a>
|
||||||
</address>
|
</address>
|
||||||
|
|
||||||
<address>
|
<address>
|
||||||
|
@ -490,8 +490,7 @@ François-René Rideau
|
||||||
before committing code.
|
before committing code.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
We should/will/must incorporate code coverage
|
You should incorporate code coverage into your testing process.
|
||||||
into our testing process.
|
|
||||||
Tests are not sufficient
|
Tests are not sufficient
|
||||||
if they do not cover all new and updated code;
|
if they do not cover all new and updated code;
|
||||||
code that for whatever reason cannot be included in coverage results
|
code that for whatever reason cannot be included in coverage results
|
||||||
|
@ -531,7 +530,7 @@ François-René Rideau
|
||||||
<p>
|
<p>
|
||||||
If you're not sure, consult a dictionary,
|
If you're not sure, consult a dictionary,
|
||||||
Google for alternative spellings,
|
Google for alternative spellings,
|
||||||
or ask a local grammar nazi.
|
or ask a local expert.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Here are examples of choosing the correct spelling:
|
Here are examples of choosing the correct spelling:
|
||||||
|
@ -616,7 +615,7 @@ François-René Rideau
|
||||||
<STYLEPOINT title="Indentation">
|
<STYLEPOINT title="Indentation">
|
||||||
<SUMMARY>
|
<SUMMARY>
|
||||||
<p>
|
<p>
|
||||||
Indent your code the way GNU Emacs does.
|
Indent your code the way a properly configured GNU Emacs does.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Indent carefully to make the code easier to understand.
|
Indent carefully to make the code easier to understand.
|
||||||
|
@ -738,10 +737,10 @@ François-René Rideau
|
||||||
(defconstant +golden-ratio64+ #xe08c1d668b756f82 "more digits of the golden ratio")
|
(defconstant +golden-ratio64+ #xe08c1d668b756f82 "more digits of the golden ratio")
|
||||||
|
|
||||||
(defmacro incf32 (x y)
|
(defmacro incf32 (x y)
|
||||||
"like incf, but for integers modulo 2**32"
|
"Like INCF, but for integers modulo 2**32"
|
||||||
`(setf ,x (logand (+ ,x ,y) #xffffffff)))
|
`(setf ,x (logand (+ ,x ,y) #xffffffff)))
|
||||||
(defmacro incf64 (x y)
|
(defmacro incf64 (x y)
|
||||||
"like incf, but for integers modulo 2**64"
|
"Like INCF, but for integers modulo 2**64"
|
||||||
`(setf ,x (logand (+ ,x ,y) #xffffffffffffffff)))
|
`(setf ,x (logand (+ ,x ,y) #xffffffffffffffff)))
|
||||||
</CODE_SNIPPET>
|
</CODE_SNIPPET>
|
||||||
<p>
|
<p>
|
||||||
|
@ -1343,7 +1342,8 @@ François-René Rideau
|
||||||
It is possible to fake global lexical variables
|
It is possible to fake global lexical variables
|
||||||
with a differently named global variable
|
with a differently named global variable
|
||||||
and a <code>DEFINE-SYMBOL-MACRO</code>.
|
and a <code>DEFINE-SYMBOL-MACRO</code>.
|
||||||
You should not use this trick.
|
You should not use this trick,
|
||||||
|
unless you first publish a library that abstracts it away.
|
||||||
</p>
|
</p>
|
||||||
<CODE_SNIPPET>
|
<CODE_SNIPPET>
|
||||||
(defconstant +hash-results+ #xbd49d10d10cbee50)
|
(defconstant +hash-results+ #xbd49d10d10cbee50)
|
||||||
|
@ -1358,26 +1358,31 @@ François-René Rideau
|
||||||
</SUMMARY>
|
</SUMMARY>
|
||||||
<BODY>
|
<BODY>
|
||||||
<p>
|
<p>
|
||||||
Name boolean-valued functions with a trailing
|
You should name boolean-valued functions with a trailing
|
||||||
<code>"P"</code> or <code>"-P"</code>,
|
<code>"P"</code> or <code>"-P"</code>,
|
||||||
to indicate they are predicates.
|
to indicate they are predicates.
|
||||||
Generally, you should use
|
Generally, you should use
|
||||||
<code>"P"</code> when the rest of the function name is one word
|
<code>"P"</code> when the rest of the function name is one word
|
||||||
and <code>"-P"</code> when it is more than one word.
|
and <code>"-P"</code> when it is more than one word.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
A rationale for this convention is given in
|
||||||
|
<a href="http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node69.html">the CLtL2 chapter on predicates</a>.
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
For uniformity, you should follow the convention above,
|
For uniformity, you should follow the convention above,
|
||||||
and not one of the alternatives below.
|
and not one of the alternatives below.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Alternative rules used in some existing packages
|
An alternative rule used in some existing packages
|
||||||
is to always use <code>"-P"</code>,
|
is to always use <code>"-P"</code>.
|
||||||
or to always use <code>"?"</code>.
|
Another alternative rule used in some existing packages
|
||||||
|
is to always use <code>"?"</code>.
|
||||||
When you develop such a package,
|
When you develop such a package,
|
||||||
you must be consistent with the rest of the package.
|
you must be consistent with the rest of the package.
|
||||||
When you start a new package,
|
When you start a new package,
|
||||||
you should not use such an alternative rule
|
you should not use such an alternative rule
|
||||||
without a very good reason.
|
without a very good documented reason.
|
||||||
</p>
|
</p>
|
||||||
</BODY>
|
</BODY>
|
||||||
</STYLEPOINT>
|
</STYLEPOINT>
|
||||||
|
@ -1832,6 +1837,24 @@ François-René Rideau
|
||||||
Sure, use it for "helper" functions, but not API functions.
|
Sure, use it for "helper" functions, but not API functions.
|
||||||
</p>
|
</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
<p>
|
||||||
|
You should, however, use appropriate declarations
|
||||||
|
in internal low-level functions
|
||||||
|
where these declarations are used for optimization.
|
||||||
|
In addition to providing more speed in production,
|
||||||
|
declarations are more helpful than assertions
|
||||||
|
to find bugs at compile-time;
|
||||||
|
they can still help find dynamic errors
|
||||||
|
by setting optimization settings low while debugging.
|
||||||
|
You should not use such declarations
|
||||||
|
outside internal functions
|
||||||
|
where it is well-documented how unsafe it is
|
||||||
|
to use such functions with the wrong arguments;
|
||||||
|
and you must not call these functions in a way
|
||||||
|
that could possibly lead to their being passed wrong arguments.
|
||||||
|
Use <code>check-type</code> to sanitize any input being passed
|
||||||
|
to such function from uncontrolled sources.
|
||||||
|
</p>
|
||||||
</BODY>
|
</BODY>
|
||||||
</STYLEPOINT>
|
</STYLEPOINT>
|
||||||
<STYLEPOINT title="Macros">
|
<STYLEPOINT title="Macros">
|
||||||
|
@ -1966,8 +1989,22 @@ François-René Rideau
|
||||||
could have figure out all by itself,
|
could have figure out all by itself,
|
||||||
when the compiler isn't sufficiently-clever
|
when the compiler isn't sufficiently-clever
|
||||||
and the difference matters.
|
and the difference matters.
|
||||||
Consider using a <code>DEFCONSTANT</code> and its variants,
|
</p>
|
||||||
which would give the value a name explaining what it means.
|
<p>
|
||||||
|
Whenever you are going to use <code>#.</code>,
|
||||||
|
you should consider using <code>DEFCONSTANT</code> and its variants,
|
||||||
|
possibly in an <code>EVAL-WHEN</code>,
|
||||||
|
to give the value a name explaining what it means.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You should use normal computations inside an <code>EVAL-WHEN</code>
|
||||||
|
rather than <code>#.</code> whenever they are enough for the job.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you don't need the computation to happen at compile-time,
|
||||||
|
but only at some point before runtime,
|
||||||
|
you should use <code>LOAD-TIME-VALUE</code>
|
||||||
|
instead of read-time or compile-time computations.
|
||||||
</p>
|
</p>
|
||||||
</BODY>
|
</BODY>
|
||||||
</STYLEPOINT>
|
</STYLEPOINT>
|
||||||
|
@ -1990,12 +2027,12 @@ François-René Rideau
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
It is usually an error to omit the <code>:execute</code>,
|
It is usually an error to omit the <code>:execute</code>,
|
||||||
for it prevents <code>LOAD</code>ing the source rather than the fasl.
|
because it prevents <code>LOAD</code>ing the source rather than the fasl.
|
||||||
It is usually an error to omit the <code>:load-toplevel</code>
|
It is usually an error to omit the <code>:load-toplevel</code>
|
||||||
(except to modify e.g. readtables and compile-time settings),
|
(except to modify e.g. readtables and compile-time settings),
|
||||||
for it prevents <code>LOAD</code>ing future files
|
because it prevents <code>LOAD</code>ing future files
|
||||||
or interactively compiling code
|
or interactively compiling code
|
||||||
that depend on the effects that happen at compile-time
|
that depends on the effects that happen at compile-time,
|
||||||
unless the current file was <code>COMPILE-FILE</code>d
|
unless the current file was <code>COMPILE-FILE</code>d
|
||||||
within the same Lisp session.
|
within the same Lisp session.
|
||||||
</p>
|
</p>
|
||||||
|
@ -2038,8 +2075,8 @@ François-René Rideau
|
||||||
any sort of method combination that might be in effect for the slot.
|
any sort of method combination that might be in effect for the slot.
|
||||||
Rare exceptions include <code>INITIALIZE-INSTANCE</code>
|
Rare exceptions include <code>INITIALIZE-INSTANCE</code>
|
||||||
and <code>PRINT-OBJECT</code> methods and
|
and <code>PRINT-OBJECT</code> methods and
|
||||||
the initialization of Quake volatile slots
|
accessing normally hidden slots in the low-level implementation of
|
||||||
in <code>INITIALIZE-RECORD</code> methods.
|
methods that provide user-visible abstractions.
|
||||||
Otherwise, you should use accessors,
|
Otherwise, you should use accessors,
|
||||||
<code>WITH-ACCESSORS</code>
|
<code>WITH-ACCESSORS</code>
|
||||||
</p>
|
</p>
|
||||||
|
@ -2047,15 +2084,23 @@ François-René Rideau
|
||||||
<p>
|
<p>
|
||||||
Accessor names generally follow a convention of
|
Accessor names generally follow a convention of
|
||||||
<code><protocol-name>-<slot-name></code>,
|
<code><protocol-name>-<slot-name></code>,
|
||||||
where an "protocol" in this case loosely indicates
|
where a "protocol" in this case loosely indicates
|
||||||
a set of functions with well-defined behavior;
|
a set of functions with well-defined behavior.
|
||||||
a class can implement all or part of an interface
|
|
||||||
by defining some methods for (generic) functions in the protocol,
|
|
||||||
including readers and writers.
|
|
||||||
No implication of a formal "protocol" concept is intended.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
For example, if there were a "notional" protocol called
|
No implication of a formal "protocol" concept is necessarily intended,
|
||||||
|
much less first-class "protocol" objects.
|
||||||
|
However, there may indeed be an abstract CLOS class
|
||||||
|
or an
|
||||||
|
<a href="http://common-lisp.net/~frideau/lil-ilc2012/lil-ilc2012.html">Interface-Passing Style</a> interface
|
||||||
|
that embodies the protocol.
|
||||||
|
Further (sub)classes or (sub)interfaces may then implement
|
||||||
|
all or part of a protocol by defining
|
||||||
|
some methods for (generic) functions in the protocol,
|
||||||
|
including readers and writers.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For example, if there were a notional protocol called
|
||||||
is <code>pnr</code> with accessors <code>pnr-segments</code>
|
is <code>pnr</code> with accessors <code>pnr-segments</code>
|
||||||
and <code>pnr-passengers</code>, then
|
and <code>pnr-passengers</code>, then
|
||||||
the classes <code>air-pnr</code>, <code>hotel-pnr</code> and
|
the classes <code>air-pnr</code>, <code>hotel-pnr</code> and
|
||||||
|
@ -2085,7 +2130,7 @@ François-René Rideau
|
||||||
some specific class(es).
|
some specific class(es).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
You must not use generic functions where there is no "notional" protocol.
|
You must not use generic functions where there is no notional protocol.
|
||||||
To put it more concretely,
|
To put it more concretely,
|
||||||
if you have more than one generic function that specializes its Nth argument,
|
if you have more than one generic function that specializes its Nth argument,
|
||||||
the specializing classes should all be descendants of a single class.
|
the specializing classes should all be descendants of a single class.
|
||||||
|
@ -2324,7 +2369,7 @@ François-René Rideau
|
||||||
instead of using a combination of several list accessor functions.
|
instead of using a combination of several list accessor functions.
|
||||||
In this context, using <code>CAR</code> and <code>CDR</code>
|
In this context, using <code>CAR</code> and <code>CDR</code>
|
||||||
instead of <code>FIRST</code> and <code>REST</code> also makes sense.
|
instead of <code>FIRST</code> and <code>REST</code> also makes sense.
|
||||||
However, mind in such cases that it might be more appropriate
|
However, keep in mind that it might be more appropriate in such cases
|
||||||
to use higher-level constructs such as
|
to use higher-level constructs such as
|
||||||
<code>DESTRUCTURING-BIND</code> or <code>FARE-MATCHER:MATCH</code>.
|
<code>DESTRUCTURING-BIND</code> or <code>FARE-MATCHER:MATCH</code>.
|
||||||
</p>
|
</p>
|
||||||
|
@ -2518,6 +2563,28 @@ François-René Rideau
|
||||||
(define-constant +google-url+ "http://www.google.com/" :test #'string=)
|
(define-constant +google-url+ "http://www.google.com/" :test #'string=)
|
||||||
(define-constant +valid-colors+ '(red green blue))
|
(define-constant +valid-colors+ '(red green blue))
|
||||||
</CODE_SNIPPET>
|
</CODE_SNIPPET>
|
||||||
|
<p>
|
||||||
|
Note that with optimizing implementations, such as SBCL or CMUCL,
|
||||||
|
defining constants this way precludes any later redefinition
|
||||||
|
short of <code>UNINTERN</code>ing the symbol
|
||||||
|
and recompiling all its clients.
|
||||||
|
This may make it "interesting" to debug things at the REPL
|
||||||
|
or to deploy live code upgrades.
|
||||||
|
If there is a chance that your "constants" are not going to be constant
|
||||||
|
over the lifetime of your server processes
|
||||||
|
after taking into consideration scheduled and unscheduled code patches,
|
||||||
|
you should consider using
|
||||||
|
<code>DEFPARAMETER</code> or <code>DEFVAR</code> instead,
|
||||||
|
or possibly a variant of <code>DEFINE-CONSTANT</code>
|
||||||
|
that builds upon some future library implementing global lexicals
|
||||||
|
rather than <code>DEFCONSTANT</code>.
|
||||||
|
You may keep the <code>+plus+</code> convention in these cases
|
||||||
|
to document the intent of the parameter as a constant.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Also note that <code>LOAD-TIME-VALUE</code> may help you
|
||||||
|
avoid the need for defined constants.
|
||||||
|
</p>
|
||||||
</BODY>
|
</BODY>
|
||||||
</STYLEPOINT>
|
</STYLEPOINT>
|
||||||
<STYLEPOINT title="Defining Functions">
|
<STYLEPOINT title="Defining Functions">
|
||||||
|
@ -2720,9 +2787,10 @@ François-René Rideau
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
You must use <code>=</code> to compare numbers,
|
You must use <code>=</code> to compare numbers,
|
||||||
unless it's really okay for <code>0</code>,
|
unless you really mean for <code>0</code>,
|
||||||
<code>0.0</code> and <code>-0.0</code> to compare unequal!
|
<code>0.0</code> and <code>-0.0</code> to compare unequal,
|
||||||
But then again, you must not usually use exact comparison
|
in which case you should use <code>EQL</code>.
|
||||||
|
Then again, you must not usually use exact comparison
|
||||||
on floating point numbers.
|
on floating point numbers.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
@ -3036,7 +3104,7 @@ François-René Rideau
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
It is quite unlikely that the code will be changed
|
It is quite unlikely that the code will be changed
|
||||||
in ways that cause the declaration not to be true anymore.
|
in ways that cause the declaration to become false.
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p>
|
<p>
|
||||||
|
@ -3120,7 +3188,7 @@ François-René Rideau
|
||||||
is also <i>O(n^2)</i> unless you specify <code>:FROM-END T</code>.
|
is also <i>O(n^2)</i> unless you specify <code>:FROM-END T</code>.
|
||||||
In such cases, you must use proper abstractions
|
In such cases, you must use proper abstractions
|
||||||
that cover those cases instead of calling <code>REDUCE</code>,
|
that cover those cases instead of calling <code>REDUCE</code>,
|
||||||
first defining them in a suitable library if needs be.
|
first defining them in a suitable library if need be.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
</BODY>
|
</BODY>
|
||||||
|
@ -3198,7 +3266,7 @@ François-René Rideau
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
<p align="right">
|
<p align="right">
|
||||||
Revision 1.8
|
Revision 1.10
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
@ -3206,9 +3274,8 @@ Revision 1.8
|
||||||
Robert Brown
|
Robert Brown
|
||||||
</address>
|
</address>
|
||||||
|
|
||||||
|
|
||||||
<address>
|
<address>
|
||||||
François-René Rideau
|
<a HREF="mailto:tunes@google.com">François-René Rideau</a>
|
||||||
</address>
|
</address>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user