HTML sucks
+I’ve read about this on a few sites but now I’m sure: + HTML is stupid!!1 +
My first CSS-only redesign
+I’ve read about this on a few sites but today I’m actually + doing it: separating concerns and avoiding anything in the HTML of + my website that is presentational. +
It’s awesome! +-------------------------------------------------------------------- + +=== Entity References + + + +Do not use entity references. + +There is no need to use entity references like `—`, `”`, or `☺`, assuming the same encoding (UTF-8) is used for files and editors as well as among teams. + +The only exceptions apply to characters with special meaning in HTML (like `<` and `&`) as well as control or “invisible” characters (like no-break spaces). + +-------------------------------------------------------- + +The currency symbol for the Euro is “&eur;”. +-------------------------------------------------------- + +---------------------------------------- + +The currency symbol for the Euro is “€”. +---------------------------------------- + +=== Optional Tags + + + +Omit optional tags (optional). + +For file size optimization and scannability purposes, consider omitting optional tags. The http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#syntax-tag-omission[HTML5 specification] defines what tags can be omitted. + +(This approach may require a grace period to be established as a wider guideline as it’s significantly different from what web developers are typically taught. For consistency and simplicity reasons it’s best served omitting all optional tags, not just a selection.) + +------------------------------------------------- + + + +
+Sic.
+ + +------------------------------------------------- + +----------------------------------------- + + +Qed. +----------------------------------------- + +=== type Attributes + + + +Omit `type` attributes for style sheets and scripts. + +Do not use `type` attributes for style sheets (unless not using CSS) and scripts (unless not using JavaScript). + +Specifying `type` attributes in these contexts is not necessary as HTML5 implies http://www.whatwg.org/specs/web-apps/current-work/multipage/semantics.html#attr-style-type[`text/css`] and http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#attr-script-type[`text/javascript`] as defaults. This can be safely done even for older browsers. + +----------------------------------------------------------- + + +----------------------------------------------------------- + +------------------------------------------------------------ + + +------------------------------------------------------------ + +------------------------------------------------------------- + + +------------------------------------------------------------- + +----------------------------------------------------------------------- + + +----------------------------------------------------------------------- + +[[HTML_Formatting_Rules]] +== HTML Formatting Rules + +=== General Formatting + + + +Use a new line for every block, list, or table element, and indent every such child element. + +Independent of the styling of an element (as CSS allows elements to assume a different role per `display` property), put every block, list, or table element on a new line. + +Also, indent them if they are child elements of a block, list, or table element. + +(If you run into issues around whitespace between list items it’s acceptable to put all `li` elements in one line. A linter is encouraged to throw a warning instead of an error.) + +-------------------------------------------- +
++-------------------------------------------- + +----------- +Space, the final frontier.
+
-
+
- Moe +
- Larry +
- Curly +
Income + | Taxes + |
---|---|
$ 5.00 + | $ 4.50 + |
- - Revision 2.23 -
- -- Hooray! Now you know you can expand points to get more - details. Alternatively, there’s a “toggle all” at the - top of this document. -
- -- This document defines formatting and style rules for HTML and - CSS. It aims at improving collaboration, code quality, and - enabling supporting infrastructure. It applies to raw, - working files that use HTML and CSS, including GSS - files. Tools are free to obfuscate, minify, and compile as - long as the general code quality is maintained. -
- - -
- Omit the protocol portion (http:
,
- https:
) from URLs pointing to images and other
- media files, style sheets, and scripts unless the respective
- files are not available over both protocols.
-
- Omitting the protocol—which makes the URL - relative—prevents mixed content issues and results in - minor file size savings. -
-- Don’t use tabs or mix tabs and spaces for indentation. -
-
- All code has to be lowercase: This applies to HTML element names,
- attributes, attribute values (unless
- text/CDATA
), CSS selectors, properties, and
- property values (with the exception of strings).
-
- Trailing white spaces are unnecessary and can complicate - diffs. -
-- Make sure your editor uses UTF-8 as character encoding, - without a byte order mark. -
-
- Specify the encoding in HTML templates and documents via
- <meta charset="utf-8">
. Do not specify
- the encoding of style sheets as these assume UTF-8.
-
- (More on encodings and when and how to specify them can be - found in Handling - character encodings in HTML and CSS.) -
- -- Use comments to explain code: What does it cover, what - purpose does it serve, why is respective solution used or - preferred? -
-- (This item is optional as it is not deemed a realistic - expectation to always demand fully documented code. Mileage - may vary heavily for HTML and CSS code and depends on the - project’s complexity.) -
- -TODO
.
-
- Highlight todos by using the keyword TODO
only,
- not other common formats like @@
.
-
- Append a contact (username or mailing list) in parentheses
- as with the format TODO(contact)
.
-
- Append action items after a colon as in TODO: action
- item
.
-
- HTML5 (HTML syntax) is preferred for all HTML documents:
- <!DOCTYPE html>
.
-
- (It’s recommended to use HTML, as text/html
. Do not use
- XHTML. XHTML, as application/xhtml+xml
,
- lacks both browser and infrastructure support and offers
- less room for optimization than HTML.)
-
- Although fine with HTML, do not close void elements, i.e. write
- <br>
, not <br />
.
-
- Use valid HTML code unless that is not possible due to - otherwise unattainable performance goals regarding file size. -
- -- Use tools such as the W3C - HTML validator to test. -
-- Using valid HTML is a measurable baseline quality attribute - that contributes to learning about technical requirements - and constraints, and that ensures proper HTML usage. -
-
- Use elements (sometimes incorrectly called “tags”) for what
- they have been created for. For example, use heading
- elements for headings, p
elements for
- paragraphs, a
elements for anchors, etc.
-
- Using HTML according to its purpose is important for - accessibility, reuse, and code efficiency reasons. -
- -
- For multimedia, such as images, videos, animated objects via
- canvas
, make sure to offer alternative
- access. For images that means use of meaningful alternative
- text (alt
) and for video and audio transcripts
- and captions, if available.
-
- Providing alternative contents is important for
- accessibility reasons: A blind user has few cues to tell
- what an image is about without @alt
, and other
- users may have no way of understanding what video or audio
- contents are about either.
-
- (For images whose alt
attributes would
- introduce redundancy, and for images whose purpose is purely
- decorative which you cannot immediately use CSS for, use no
- alternative text, as in alt=""
.)
-
- Strictly keep structure (markup), presentation (styling), - and behavior (scripting) apart, and try to keep the - interaction between the three to an absolute minimum. -
-- That is, make sure documents and templates contain only HTML - and HTML that is solely serving structural purposes. Move - everything presentational into style sheets, and everything - behavioral into scripts. -
-- In addition, keep the contact area as small as possible by - linking as few style sheets and scripts as possible from - documents and templates. -
-- Separating structure from presentation from behavior is - important for maintenance reasons. It is always more - expensive to change HTML documents and templates than it is - to update style sheets and scripts. -
- -
- There is no need to use entity references like
- —
, ”
, or
- ☺
, assuming the same encoding
- (UTF-8) is used for files and editors as well as among
- teams.
-
- The only exceptions apply to characters with special meaning
- in HTML (like <
and &
) as
- well as control or “invisible” characters (like no-break
- spaces).
-
- For file size optimization and scannability purposes, - consider omitting optional tags. - The HTML5 - specification defines what tags can be omitted. -
-- (This approach may require a grace period to be established - as a wider guideline as it’s significantly different - from what web developers are typically taught. For - consistency and simplicity reasons it’s best served - omitting all optional tags, not just a selection.) -
-type
attributes for style sheets and scripts.
-
- Do not use type
attributes for style sheets
- (unless not using CSS) and scripts (unless not using
- JavaScript).
-
- Specifying type
attributes in these contexts is
- not necessary as HTML5 implies
- text/css
- and
- text/javascript
- as defaults. This can be safely done even for older browsers.
-
- Independent of the styling of an element (as CSS allows
- elements to assume a different role per display
- property), put every block, list, or table element on a new
- line.
-
- Also, indent them if they are child elements of a block, - list, or table element. -
-
- (If you run into issues around whitespace between list items
- it’s acceptable to put all li
elements in one
- line. A linter is encouraged to throw a warning instead of
- an error.)
-
- Use double (""
) rather than single quotation marks
- (''
) around attribute values.
-
- Unless dealing with CSS validator bugs or requiring - proprietary syntax, use valid CSS code. -
- -- Use tools such as the W3C - CSS validator to test. -
-- Using valid CSS is a measurable baseline quality attribute - that allows to spot CSS code that may not have any effect - and can be removed, and that ensures proper CSS usage. -
- -- Instead of presentational or cryptic names, always use ID - and class names that reflect the purpose of the element in - question, or that are otherwise generic. -
-- Names that are specific and reflect the purpose of the - element should be preferred as these are most understandable - and the least likely to change. -
-- Generic names are simply a fallback for elements that have no - particular or no meaning different from their siblings. They are - typically needed as “helpers.” -
-- Using functional or generic names reduces the probability of - unnecessary document or template changes. -
-- Try to convey what an ID or class is about while being as - brief as possible. -
-- Using ID and class names this way contributes to acceptable - levels of understandability and code efficiency. -
-Unless necessary (for example with helper classes), do not - use element names in conjunction with IDs or classes. -
-- Avoiding unnecessary ancestor selectors is useful for performance - reasons. -
-
- CSS offers a variety of shorthand
- properties (like font
)
- that should be used whenever possible, even in cases where
- only one value is explicitly set.
-
- Using shorthand properties is useful for code efficiency and - understandability. -
-
- Do not use units after 0
values unless they are
- required.
-
- Do not use put 0
s in front of values or lengths
- between -1 and 1.
-
- For color values that permit it, 3 character hexadecimal - notation is shorter and more succinct. -
-- In large projects as well as for code that gets embedded in - other projects or on external sites use prefixes (as - namespaces) for ID and class names. Use short, unique - identifiers followed by a dash. -
- - -- Using namespaces helps preventing naming conflicts and can - make maintenance easier, for example in search and replace - operations. -
-- Do not concatenate words and abbreviations in selectors by - any characters (including none at all) other than hyphens, - in order to improve understanding and scannability. -
-- It’s tempting to address styling differences over user - agent detection or special CSS filters, workarounds, and - hacks. Both approaches should be considered last resort in - order to achieve and maintain an efficient and manageable - code base. Put another way, giving detection and hacks a - free pass will hurt projects in the long run as projects - tend to take the way of least resistance. That is, allowing - and making it easy to use detection and hacks means using - detection and hacks more frequently—and more frequently - is too frequently. -
- - - -- Put declarations in alphabetical order in order to achieve - consistent code in a way that is easy to remember and - maintain. -
-- Ignore vendor-specific prefixes for sorting purposes. However, - multiple vendor-specific prefixes for a certain CSS property should - be kept sorted (e.g. -moz prefix comes before -webkit). -
-- Indent all block - content, that is rules within rules as well as declarations, so to - reflect hierarchy and improve understanding. -
-- End every declaration with a semicolon for consistency and - extensibility reasons. -
-- Always use a single space between property and value (but no - space between property and colon) for consistency reasons. -
-- Always use a single space between the last selector and the opening - brace that begins the declaration - block. -
-- The opening brace should be on the same line as the last selector in a - given rule. -
-- Always start a new line for each selector and declaration. -
-- Always put a blank line (two line breaks) between rules. -
-
- Use single (''
) rather than double (""
)
- quotation marks for attribute selectors or property values. Do not
- use quotation marks in URI values (url()
).
-
- Exception: If you do need to use the @charset
rule,
- use double quotation marks—single
- quotation marks are not permitted.
-
- If possible, group style sheet sections together by using - comments. Separate sections with new lines. -
-- Be consistent. -
-- If you’re editing code, take a few minutes to look at the code - around you and determine its style. If they use spaces around - all their arithmetic operators, you should too. If their - comments have little boxes of hash marks around them, make your - comments have little boxes of hash marks around them too. -
-- The point of having style guidelines is to have a common vocabulary - of coding so people can concentrate on what you’re saying rather - than on how you’re saying it. We present global style rules here so - people know the vocabulary, but local style is also important. If - code you add to a file looks drastically different from the existing - code around it, it throws readers out of their rhythm when they go to - read it. Avoid this. -
-- Revision 2.23 -
- -` immediately before the first word, with no space after. + +[[s7.1.3-javadoc-at-clauses]] +==== 7.1.3 At-clauses + +Any of the standard "at-clauses" that are used appear in the order `@param`, `@return`, `@throws`, `@deprecated`, and these four types never appear with an empty description. When an at-clause doesn't fit on a single line, continuation lines are indented four (or more) spaces from the position of the `@`. + +[[s7.2-summary-fragment]] +=== 7.2 The summary fragment + +The Javadoc for each class and member begins with a brief **summary fragment**. This fragment is very important: it is the only part of the text that appears in certain contexts such as class and method indexes. + +This is a fragment—a noun phrase or verb phrase, not a complete sentence. It does *not* begin with `A {@code Foo} is a...`, or `This method returns...`, nor does it form a complete imperative sentence like `Save the record.`. However, the fragment is capitalized and punctuated as if it were a complete sentence. + +*Tip:* A common mistake is to write simple Javadoc in the form `/** @return the customer ID */`. This is incorrect, and should be changed to `/** Returns the customer ID. */`. + +[[s7.3-javadoc-where-required]] +=== 7.3 Where Javadoc is used + +At the __minimum__, Javadoc is present for every `public` class, and every `public` or `protected` member of such a class, with a few exceptions noted below. + +Other classes and members still have Javadoc __as needed__. Whenever an implementation comment would be used to define the overall purpose or behavior of a class, method or field, that comment is written as Javadoc instead. (It's more uniform, and more tool-friendly.) + +[[s7.3.1-javadoc-exception-self-explanatory]] +==== 7.3.1 Exception: self-explanatory methods + +Javadoc is optional for "simple, obvious" methods like `getFoo`, in cases where there _really and truly_ is nothing else worthwhile to say but "Returns the foo". + +*Important:* it is not appropriate to cite this exception to justify omitting relevant information that a typical reader might need to know. For example, for a method named `getCanonicalName`, don't omit its documentation (with the rationale that it would say only `/** Returns the canonical name. */`) if a typical reader may have no idea what the term "canonical name" means! + +[[s7.3.2-javadoc-exception-overrides]] +==== 7.3.2 Exception: overrides + +Javadoc is not always present on a method that overrides a supertype method. + +''''' + +Last changed: March 21, 2014 diff --git a/javaguide.css b/javaguide.css deleted file mode 100644 index c42ba83..0000000 --- a/javaguide.css +++ /dev/null @@ -1,515 +0,0 @@ -table { - border-collapse: collapse; -} - -td, th { - border: 1px solid #ccc; - padding: 2px 12px; - font-size: 10pt; -} - -code, samp, var { - color: #060; -} - -pre { - font-size: 10pt; - display: block; - color: #060; - background-color: #e8fff6; - border-color: #f0fff0; - border-style: solid; - border-top-width: 1px; - border-bottom-width: 1px; - border-right-width: 1px; - border-left-width: 5px; - padding-left: 12px; - padding-right: 12px; - padding-top: 4px; - padding-bottom: 4px; -} - -pre.badcode { - color: #c00; - background-color: #ffe6d8; - border-color: #fff0f0; -} - -hr { - margin-top: 3.5em; - border-width: 1px; - color: #fff; -} - -html { - margin-top:2em; - margin-left:10%; - margin-right:10%; - padding:0; -} - -.bp-reset-element, -body, -h1, -h2, -h3, -h4, -h5, -h6, -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section, -summary, -blockquote, -q, -th, -td, -caption, -table, -div, -span, -object, -iframe, -p, -pre, -a, -abbr, -acronym, -address, -code, -del, -dfn, -em, -img, -dl, -dt, -dd, -ol, -ul, -li, -fieldset, -form, -label, -legend, -caption, -tbody, -tfoot, -thead, -tr { - margin:0; - padding:0; - border:0; - font-weight:inherit; - font-style:inherit; - font-size:100%; - font-family:inherit; - vertical-align:baseline; -} - -body { - font-family:'Arial', sans-serif; - font-size:81.25%; - color:#222; - background-color:#fff; - line-height:1.67; - overflow: auto; -} - -.change { - text-align: right; - margin-bottom:1em; -} - -em { - font-style: italic -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-weight:bold; -} - -h1 { - margin-bottom:.50em; - text-align: center -} - -h2, -h3, -h4, -h5, -h6 { - margin-top:1.5em; - margin-bottom:.75em; -} - -h1 {font-size:200%;} -h2 {font-size:167%;} -h3 {font-size:133%;} -h4 {font-size:120%;} -h5 {font-size:110%;} - -p { - margin:0 0 1.5em; -} - -a[href=''] { - cursor:default; -} - -h1 img, -h2 img, -h3 img, -h4 img, -h5 img, -h6 img { - margin:0; -} - -a img { - border:none; -} - -pre { - margin:1.5em 0; - white-space:pre; -} - -pre, -code, -kbd, -tt { - font:1em 'Droid Sans Mono', monospace; - line-height:1.5; -} - -dl { - margin:0 0 1.5em 0; -} - -dl dt { - font-weight:bold; -} - -dd { - margin-left:1.5em; -} - -dd.toc3 { - margin-left:3em; -} - -hr { - height:0; - border:0; - border-top:1px solid #ccc; - background-color:#ccc; -} - -table { - border:1px solid #bbb; - border-spacing:0; - border-collapse:collapse; - margin:0 0 1.5em; - vertical-align:middle; - width:100%; -} - -table.unlined, -table.unlined th, -table.unlined tr, -table.unlined td { - border:0; -} - -th, -td, -caption { - float:none !important; - text-align:left; - font-weight:normal; - vertical-align:middle; - padding:4px; -} - -caption { - padding:0; -} - -td { - border:1px solid #bbb; - vertical-align:top; -} - -th { - border:0; - border-bottom:1px solid black; - font-weight:bold; - background:rgb(229, 236, 249); -} - -table th code { - background-color:inherit; - color:inherit; -} - -table tfoot th { - border:1px solid #bbb; -} - -tfoot { - font-style:italic; -} - -caption { - background:#eee; -} - -table[border='0'] { - border:none; -} - -table[border='0']>tbody>tr>td, -table[border='0']>tr>td { - border:none; -} - -tr.alt td, -td.alt { - background-color:#efefef; -} - -table.striped tr:nth-child(even) td, -table tr.even td { - background:#efefef; -} - -table.columns { - border:none; -} - -table.columns>tbody>tr>td, -table.columns>tr>td { - border:none; - padding:0 3em 0 0; -} - -table.columns>tbody>tr>td:last-child, -table.columns>tr>td:last-child { - border:none; - padding:0; -} - -ul, -ol { - margin:0 1.5em 1.5em 0; - padding-left:2em; -} - -li ul, -li ol { - margin:0; -} - -ul { - list-style-type:disc; -} - -ol { - list-style-type:decimal; -} - -ul { - list-style-type:disc; -} - -ul ul { - list-style-type:circle; -} - -ul ul ul { - list-style-type:square; -} - -ul.disc { - list-style-type:disc; -} - -ul.circle { - list-style-type:circle; -} - -ul.square { - list-style-type:square; -} - -ol { - list-style-type:decimal; -} - -ol ol { - list-style-type:lower-alpha; -} - -ol ol ol { - list-style-type:lower-roman; -} - -ol ul { - list-style-type:circle; -} - -ol.decimal { - list-style-type:decimal; -} - -ol.upper-alpha { - list-style-type:upper-alpha; -} - -ol.lower-alpha { - list-style-type:lower-alpha; -} - -ol.upper-roman { - list-style-type:upper-roman; -} - -ol.lower-roman { - list-style-type:lower-roman; -} - -ol.nolist, -ul.nolist { - padding-left:0; - list-style-image:none; - list-style-type:none; - margin-left:0; -} - -.center { - text-align:center; -} - -code, -kbd, -pre { - color:#009900; -} - -kbd { - font-weight: bold; -} - -table.striped code { - background-color:inherit; -} - -pre { - padding:6px 10px; - background-color:#FAFAFA; - border:1px solid #bbb; - overflow:auto; -} - -pre.prettyprint { - padding:6px 10px !important; - border:1px solid #bbb !important; -} - -code.bad, code.badcode { - color: magenta; -} -pre.bad, pre.badcode { - background-color:#ffe6d8; - border-top:1px inset #a03; - border-left:1px inset #a03; -} - -.tip { - background-color:#fffbd9; - padding:6px 8px 6px 10px; - border-left:6px solid #ffef70; -} - -.note { - background-color:#e5ecf9; - padding:6px 8px 6px 10px; - border-left:6px solid #36c; -} - -@media print { - - .str { - color:#060; - } - - .kwd { - color:#006; - font-weight:bold; - } - - .com { - color:#600; - font-style:italic; - } - - .typ { - color:#404; - font-weight:bold; - } - - .lit { - color:#044; - } - - .pun, - .opn, - .clo { - color:#440; - } - - .pln { - color:#000; - } - - .tag { - color:#006; - font-weight:bold; - } - - .atn { - color:#404; - } - - .atv { - color:#060; - } - - h1 { - font-style:italic; - } -} - -ol.linenums { - margin-top:0; - margin-bottom:0; -} - -code { - background-color:#FAFAFA; - padding: 0.25em 0.5em; - white-space: nowrap -} diff --git a/javaguide.html b/javaguide.html deleted file mode 100644 index 74bfbad..0000000 --- a/javaguide.html +++ /dev/null @@ -1,793 +0,0 @@ - -
- - - - -Google Java Style
-1 Introduction
-This document serves as the complete definition of Google's coding standards for -source code in the Java™ Programming Language. A Java source file is described as being in -Google Style if and only if it adheres to the rules herein.
Like other programming style guides, the issues covered span not only aesthetic issues of -formatting, but other types of conventions or coding standards as well. However, this document -focuses primarily on the hard-and-fast rules that we follow universally, and -avoids giving advice that isn't clearly enforceable (whether by human or tool). -
-1.1 Terminology notes
-In this document, unless otherwise clarified:
- The term class is used inclusively to mean an "ordinary" class, enum class,
- interface or annotation type (
@interface
). - The term comment always refers to implementation comments. We do not - use the phrase "documentation comments", instead using the common term "Javadoc."
Other "terminology notes" will appear occasionally throughout the document.
-1.2 Guide notes
-Example code in this document is non-normative. That is, while the examples -are in Google Style, they may not illustrate the only stylish way to represent the -code. Optional formatting choices made in examples should not be enforced as rules.
-2 Source file basics
- -2.1 File name
-The source file name consists of the case-sensitive name of the top-level class it contains,
-plus the .java
extension.
2.2 File encoding: UTF-8
-Source files are encoded in UTF-8.
-2.3 Special characters
- -2.3.1 Whitespace characters
-Aside from the line terminator sequence, the ASCII horizontal space -character (0x20) is the only whitespace character that appears -anywhere in a source file. This implies that:
- All other whitespace characters in string and character literals are escaped.
- Tab characters are not used for indentation.
2.3.2 Special escape sequences
-For any character that has a special escape sequence
-(\b
,
-\t
,
-\n
,
-\f
,
-\r
,
-\"
,
-\'
and
-\\
), that sequence
-is used rather than the corresponding octal
-(e.g. \012
) or Unicode
-(e.g. \u000a
) escape.
2.3.3 Non-ASCII characters
-For the remaining non-ASCII characters, either the actual Unicode character
-(e.g. ∞
) or the equivalent Unicode escape
-(e.g. \u221e
) is used, depending only on which
-makes the code easier to read and understand.
Tip: In the Unicode escape case, and occasionally even when actual -Unicode characters are used, an explanatory comment can be very helpful.
Examples:
Example | Discussion |
---|---|
String unitAbbrev = "μs"; | Best: perfectly clear even without a comment. |
String unitAbbrev = "\u03bcs"; // "μs" | Allowed, but there's no reason to do this. |
String unitAbbrev = "\u03bcs";
- // Greek letter mu, "s" | Allowed, but awkward and prone to mistakes. |
String unitAbbrev = "\u03bcs"; | Poor: the reader has no idea what this is. |
return '\ufeff' + content;
- // byte order mark | Good: use escapes for non-printable characters, and comment if necessary. |
Tip: Never make your code less readable simply out of fear that -some programs might not handle non-ASCII characters properly. If that should happen, those -programs are broken and they must be fixed.
-3 Source file structure
-A source file consists of, in order:
- License or copyright information, if present
- Package statement
- Import statements
- Exactly one top-level class
Exactly one blank line separates each section that is present.
-3.1 License or copyright information, if present
-If license or copyright information belongs in a file, it belongs here.
-3.2 Package statement
-The package statement is not line-wrapped. The column limit (Section 4.4, -Column limit: 80 or 100) does not apply to package statements.
-3.3 Import statements
- -3.3.1 No wildcard imports
-Wildcard imports, static or otherwise, are not used.
-3.3.2 No line-wrapping
-Import statements are not line-wrapped. The column limit (Section 4.4, -Column limit: 80 or 100) does not apply to import -statements.
-3.3.3 Ordering and spacing
-Import statements are divided into the following groups, in this order, with each group -separated by a single blank line:
- All static imports in a single group
com.google
imports - (only if this source file is in thecom.google
package - space)- Third-party imports, one group per top-level package, in ASCII sort order
-
- for example:
android
,com
,junit
,org
, -sun
- for example:
java
importsjavax
imports
Within a group there are no blank lines, and the imported names appear in ASCII sort -order. (Note: this is not the same as the import statements being in -ASCII sort order; the presence of semicolons warps the result.)
-3.4 Class declaration
- -3.4.1 Exactly one top-level class declaration
-Each top-level class resides in a source file of its own.
-3.4.2 Class member ordering
-The ordering of the members of a class can have a great effect on learnability, but there is -no single correct recipe for how to do it. Different classes may order their members -differently.
What is important is that each class order its members in some logical -order, which its maintainer could explain if asked. For example, new methods are not -just habitually added to the end of the class, as that would yield "chronological by date -added" ordering, which is not a logical ordering.
-3.4.2.1 Overloads: never split
-When a class has multiple constructors, or multiple methods with the same name, these appear -sequentially, with no intervening members.
-4 Formatting
-Terminology Note: block-like construct refers to -the body of a class, method or constructor. Note that, by Section 4.8.3.1 on -array initializers, any array initializer -may optionally be treated as if it were a block-like construct.
-4.1 Braces
- -4.1.1 Braces are used where optional
-Braces are used with
-if
,
-else
,
-for
,
-do
and
-while
statements, even when the
-body is empty or contains only a single statement.
4.1.2 Nonempty blocks: K & R style
-Braces follow the Kernighan and Ritchie style -("Egyptian brackets") -for nonempty blocks and block-like constructs:
- No line break before the opening brace.
- Line break after the opening brace.
- Line break before the closing brace.
- Line break after the closing brace if that brace terminates a statement or the body
- of a method, constructor or named class. For example, there is no line break
- after the brace if it is followed by
else
or a - comma.
Example:
-return new MyClass() { - @Override public void method() { - if (condition()) { - try { - something(); - } catch (ProblemException e) { - recover(); - } - } - } -}; -
A few exceptions for enum classes are given in Section 4.8.1, -Enum classes.
-4.1.3 Empty blocks: may be concise
-An empty block or block-like construct may be closed immediately after it is
-opened, with no characters or line break in between
-({}
), unless it is part of a
-multi-block statement (one that directly contains multiple blocks:
-if/else-if/else
or
-try/catch/finally
).
Example:
- void doNothing() {} --
4.2 Block indentation: +2 spaces
-Each time a new block or block-like construct is opened, the indent increases by two -spaces. When the block ends, the indent returns to the previous indent level. The indent level -applies to both code and comments throughout the block. (See the example in Section 4.1.2, -Nonempty blocks: K & R Style.)
-4.3 One statement per line
-Each statement is followed by a line-break.
-4.4 Column limit: 80 or 100
-- Projects are free to choose a column limit of either 80 or 100 characters. - -Except as noted below, any line that would exceed this limit must be line-wrapped, as explained in -Section 4.5, Line-wrapping. -
Exceptions:
- Lines where obeying the column limit is not possible (for example, a long URL in Javadoc, - or a long JSNI method reference).
package
and -import
statements (see Sections - 3.2 Package statement and - 3.3 Import statements).- Command lines in a comment that may be cut-and-pasted into a shell.
4.5 Line-wrapping
-Terminology Note: When code that might otherwise legally -occupy a single line is divided into multiple lines, typically to avoid overflowing the column -limit, this activity is called -line-wrapping.
There is no comprehensive, deterministic formula showing exactly how to line-wrap in -every situation. Very often there are several valid ways to line-wrap the same piece of code.
Tip: Extracting a method or local variable may solve the problem -without the need to line-wrap.
-4.5.1 Where to break
-The prime directive of line-wrapping is: prefer to break at a -higher syntactic level. Also:
- When a line is broken at a non-assignment operator the break comes before
- the symbol. (Note that this is not the same practice used in Google style for other languages,
- such as C++ and JavaScript.)
-
- This also applies to the following "operator-like" symbols: the dot separator
- (
.
), the ampersand in type bounds - (<T extends Foo & Bar>
), and the pipe in - catch blocks - (catch (FooException | BarException e)
).
- This also applies to the following "operator-like" symbols: the dot separator
- (
- When a line is broken at an assignment operator the break typically comes
- after the symbol, but either way is acceptable.
-
- This also applies to the "assignment-operator-like" colon in an enhanced
-
for
("foreach") statement.
- This also applies to the "assignment-operator-like" colon in an enhanced
-
- A method or constructor name stays attached to the open parenthesis
- (
(
) that follows it. - A comma (
,
) stays attached to the token that - precedes it.
4.5.2 Indent continuation lines at least +4 spaces
-When line-wrapping, each line after the first (each continuation line) is indented -at least +4 from the original line.
When there are multiple continuation lines, indentation may be varied beyond +4 as -desired. In general, two continuation lines use the same indentation level if and only if they -begin with syntactically parallel elements.
Section 4.6.3 on Horizontal alignment addresses -the discouraged practice of using a variable number of spaces to align certain tokens with -previous lines.
-4.6 Whitespace
- -4.6.1 Vertical Whitespace
-A single blank line appears:
- Between consecutive members (or initializers) of a class: fields, constructors,
- methods, nested classes, static initializers, instance initializers.
-
- Exception: A blank line between two consecutive - fields (having no other code between them) is optional. Such blank lines are used as needed to - create logical groupings of fields.
- Within method bodies, as needed to create logical groupings of statements.
- Optionally before the first member or after the last member of the class (neither - encouraged nor discouraged).
- As required by other sections of this document (such as Section 3.3, - Import statements).
Multiple consecutive blank lines are permitted, but never required (or encouraged).
-4.6.2 Horizontal whitespace
-Beyond where required by the language or other style rules, and apart from literals, comments and -Javadoc, a single ASCII space also appears in the following places only.
- Separating any reserved word, such as
-
if
, -for
or -catch
, from an open parenthesis - ((
) - that follows it on that line - Separating any reserved word, such as
-
else
or -catch
, from a closing curly brace - (}
) that precedes it on that line - Before any open curly brace
- (
{
), with two exceptions: -@SomeAnnotation({a, b})
(no space is used)String[][] x = {{"foo"}};
(no space is required - between{{
, by item 8 below)
- On both sides of any binary or ternary operator. This also applies to the following
- "operator-like" symbols:
-
- the ampersand in a conjunctive type bound:
-
<T extends Foo & Bar>
- the pipe for a catch block that handles multiple exceptions:
-
catch (FooException | BarException e)
- the colon (
:
) in an enhanced -for
("foreach") statement
- the ampersand in a conjunctive type bound:
-
- After
,:;
or the closing parenthesis - ()
) of a cast - On both sides of the double slash (
//
) that - begins an end-of-line comment. Here, multiple spaces are allowed, but not required. - Between the type and variable of a declaration:
-
List<String> list
- Optional just inside both braces of an array initializer
-
new int[] {5, 6}
and -new int[] { 5, 6 }
are both valid
Note: This rule never requires or forbids additional space at the -start or end of a line, only interior space.
-4.6.3 Horizontal alignment: never required
-Terminology Note: Horizontal alignment is the -practice of adding a variable number of additional spaces in your code with the goal of making -certain tokens appear directly below certain other tokens on previous lines.
This practice is permitted, but is never required by Google Style. It is not -even required to maintain horizontal alignment in places where it was already used.
Here is an example without alignment, then using alignment:
-private int x; // this is fine -private Color color; // this too - -private int x; // permitted, but future edits -private Color color; // may leave it unaligned -
Tip: Alignment can aid readability, but it creates problems for -future maintenance. Consider a future change that needs to touch just one line. This change may -leave the formerly-pleasing formatting mangled, and that is allowed. More often -it prompts the coder (perhaps you) to adjust whitespace on nearby lines as well, possibly -triggering a cascading series of reformattings. That one-line change now has a "blast radius." -This can at worst result in pointless busywork, but at best it still corrupts version history -information, slows down reviewers and exacerbates merge conflicts.
-4.7 Grouping parentheses: recommended
-Optional grouping parentheses are omitted only when author and reviewer agree that there is no -reasonable chance the code will be misinterpreted without them, nor would they have made the code -easier to read. It is not reasonable to assume that every reader has the entire Java -operator precedence table memorized.
-4.8 Specific constructs
- -4.8.1 Enum classes
-After each comma that follows an enum constant, a line-break is optional.
An enum class with no methods and no documentation on its constants may optionally be formatted -as if it were an array initializer (see Section 4.8.3.1 on -array initializers).
-private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS } -
Since enum classes are classes, all other rules for formatting classes apply.
-4.8.2 Variable declarations
- -4.8.2.1 One variable per declaration
-Every variable declaration (field or local) declares only one variable: declarations such as
-int a, b;
are not used.
4.8.2.2 Declared when needed, initialized as soon as -possible
-Local variables are not habitually declared at the start of their containing -block or block-like construct. Instead, local variables are declared close to the point they are -first used (within reason), to minimize their scope. Local variable declarations typically have -initializers, or are initialized immediately after declaration.
-4.8.3 Arrays
- -4.8.3.1 Array initializers: can be "block-like"
-Any array initializer may optionally be formatted as if it were a "block-like -construct." For example, the following are all valid (not an exhaustive -list):
-new int[] { new int[] { - 0, 1, 2, 3 0, -} 1, - 2, -new int[] { 3, - 0, 1, } - 2, 3 -} new int[] - {0, 1, 2, 3} --
4.8.3.2 No C-style array declarations
-The square brackets form a part of the type, not the variable:
-String[] args
, not
-String args[]
.
4.8.4 Switch statements
-Terminology Note: Inside the braces of a
-switch block are one or more statement groups. Each statement group consists of
-one or more switch labels (either case FOO:
or
-default:
), followed by one or more statements.
4.8.4.1 Indentation
-As with any other block, the contents of a switch block are indented +2.
After a switch label, a newline appears, and the indentation level is increased +2, exactly as -if a block were being opened. The following switch label returns to the previous indentation -level, as if a block had been closed.
-4.8.4.2 Fall-through: commented
-Within a switch block, each statement group either terminates abruptly (with a
-break
,
-continue
,
-return
or thrown exception), or is marked with a comment
-to indicate that execution will or might continue into the next statement group. Any
-comment that communicates the idea of fall-through is sufficient (typically
-// fall through
). This special comment is not required in
-the last statement group of the switch block. Example:
-switch (input) { - case 1: - case 2: - prepareOneOrTwo(); - // fall through - case 3: - handleOneTwoOrThree(); - break; - default: - handleLargeNumber(input); -} --
4.8.4.3 The default case is present
-Each switch statement includes a default
statement
-group, even if it contains no code.
4.8.5 Annotations
-Annotations applying to a class, method or constructor appear immediately after the -documentation block, and each annotation is listed on a line of its own (that is, one annotation -per line). These line breaks do not constitute line-wrapping (Section -4.5, Line-wrapping), so the indentation level is not -increased. Example:
-@Override -@Nullable -public String getNameIfPresent() { ... } -
Exception: A single parameterless annotation -may instead appear together with the first line of the signature, for example:
-@Override public int hashCode() { ... } -
Annotations applying to a field also appear immediately after the documentation block, but in -this case, multiple annotations (possibly parameterized) may be listed on the same line; -for example:
-@Partial @Mock DataLoader loader; -
There are no specific rules for formatting parameter and local variable annotations.
-4.8.6 Comments
- -4.8.6.1 Block comment style
-Block comments are indented at the same level as the surrounding code. They may be in
-/* ... */
style or
-// ...
style. For multi-line
-/* ... */
comments, subsequent lines must start with
-*
aligned with the *
on the previous line.
-/* - * This is // And so /* Or you can - * okay. // is this. * even do this. */ - */ -
Comments are not enclosed in boxes drawn with asterisks or other characters.
Tip: When writing multi-line comments, use the
-/* ... */
style if you want automatic code formatters to
-re-wrap the lines when necessary (paragraph-style). Most formatters don't re-wrap lines in
-// ...
style comment blocks.
4.8.7 Modifiers
-Class and member modifiers, when present, appear in the order -recommended by the Java Language Specification: -
-public protected private abstract static final transient volatile synchronized native strictfp --
4.8.8 Numeric Literals
-long
-valued integer literals use an uppercase L
suffix, never
-lowercase (to avoid confusion with the digit 1
). For example, 3000000000L
-rather than 3000000000l
.
5 Naming
- -5.1 Rules common to all identifiers
-Identifiers use only ASCII letters and digits, and in two cases noted below, underscores. Thus
-each valid identifier name is matched by the regular expression \w+
.
In Google Style special prefixes or
-suffixes, like those seen in the examples name_
,
-mName
, s_name
and
-kName
, are not used.
5.2 Rules by identifier type
- -5.2.1 Package names
-Package names are all lowercase, with consecutive words simply concatenated together (no
-underscores). For example, com.example.deepspace
, not
-com.example.deepSpace
or
-com.example.deep_space
.
5.2.2 Class names
-Class names are written in UpperCamelCase.
Class names are typically nouns or noun phrases. For example,
-Character
or
-ImmutableList
. Interface names may also be nouns or
-noun phrases (for example, List
), but may sometimes be
-adjectives or adjective phrases instead (for example,
-Readable
).
There are no specific rules or even well-established conventions for naming annotation types.
Test classes are named starting with the name of the class they are testing, and ending
-with Test
. For example,
-HashTest
or
-HashIntegrationTest
.
5.2.3 Method names
-Method names are written in lowerCamelCase.
Method names are typically verbs or verb phrases. For example,
-sendMessage
or
-stop
.
Underscores may appear in JUnit test method names to separate logical components of the
-name. One typical pattern is test<MethodUnderTest>_<state>
,
-for example testPop_emptyStack
. There is no One Correct
-Way to name test methods.
5.2.4 Constant names
-Constant names use CONSTANT_CASE
: all uppercase
-letters, with words separated by underscores. But what is a constant, exactly?
Every constant is a static final field, but not all static final fields are constants. Before -choosing constant case, consider whether the field really feels like a constant. For -example, if any of that instance's observable state can change, it is almost certainly not a -constant. Merely intending to never mutate the object is generally not -enough. Examples:
-// Constants -static final int NUMBER = 5; -static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann"); -static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable -static final SomeMutableType[] EMPTY_ARRAY = {}; -enum SomeEnum { ENUM_CONSTANT } - -// Not constants -static String nonFinal = "non-final"; -final String nonStatic = "non-static"; -static final Set<String> mutableCollection = new HashSet<String>(); -static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable); -static final Logger logger = Logger.getLogger(MyClass.getName()); -static final String[] nonEmptyArray = {"these", "can", "change"}; -
These names are typically nouns or noun phrases.
-5.2.5 Non-constant field names
-Non-constant field names (static or otherwise) are written -in lowerCamelCase.
These names are typically nouns or noun phrases. For example,
-computedValues
or
-index
.
5.2.6 Parameter names
-Parameter names are written in lowerCamelCase.
One-character parameter names should be avoided.
-5.2.7 Local variable names
-Local variable names are written in lowerCamelCase, and can be -abbreviated more liberally than other types of names.
However, one-character names should be avoided, except for temporary and looping variables.
Even when final and immutable, local variables are not considered to be constants, and should not -be styled as constants.
-5.2.8 Type variable names
-Each type variable is named in one of two styles:
- A single capital letter, optionally followed by a single numeral (such as
-
E
,T
, -X
,T2
) - - A name in the form used for classes (see Section 5.2.2,
- Class names), followed by the capital letter
-
T
(examples: -RequestT
, -FooBarT
).
5.3 Camel case: defined
-Sometimes there is more than one reasonable way to convert an English phrase into camel case, -such as when acronyms or unusual constructs like "IPv6" or "iOS" are present. To improve -predictability, Google Style specifies the following (nearly) deterministic scheme.
Beginning with the prose form of the name:
- Convert the phrase to plain ASCII and remove any apostrophes. For example, "Müller's - algorithm" might become "Muellers algorithm".
- Divide this result into words, splitting on spaces and any remaining punctuation (typically
- hyphens).
-
-
- Recommended: if any word already has a conventional camel-case appearance in common - usage, split this into its constituent parts (e.g., "AdWords" becomes "ad words"). Note - that a word such as "iOS" is not really in camel case per se; it defies any - convention, so this recommendation does not apply.
- Now lowercase everything (including acronyms), then uppercase only the first
- character of:
-
- ... each word, to yield upper camel case, or
- ... each word except the first, to yield lower camel case
- Finally, join all the words into a single identifier.
Note that the casing of the original words is almost entirely disregarded. Examples:
Prose form | Correct | Incorrect |
---|---|---|
"XML HTTP request" | XmlHttpRequest | XMLHTTPRequest |
"new customer ID" | newCustomerId | newCustomerID |
"inner stopwatch" | innerStopwatch | innerStopWatch |
"supports IPv6 on iOS?" | supportsIpv6OnIos | supportsIPv6OnIOS |
"YouTube importer" | YouTubeImporter YoutubeImporter * |
*Acceptable, but not recommended.
Note: Some words are ambiguously hyphenated in the English
-language: for example "nonempty" and "non-empty" are both correct, so the method names
-checkNonempty
and
-checkNonEmpty
are likewise both correct.
6 Programming Practices
- -6.1 @Override: always used
-A method is marked with the @Override
annotation
-whenever it is legal. This includes a class method overriding a superclass method, a class method
-implementing an interface method, and an interface method respecifying a superinterface
-method.
Exception:@Override
may be omitted when the parent method is
-@Deprecated
.
6.2 Caught exceptions: not ignored
-Except as noted below, it is very rarely correct to do nothing in response to a caught
-exception. (Typical responses are to log it, or if it is considered "impossible", rethrow it as an
-AssertionError
.)
When it truly is appropriate to take no action whatsoever in a catch block, the reason this is -justified is explained in a comment.
-try { - int i = Integer.parseInt(response); - return handleNumericResponse(i); -} catch (NumberFormatException ok) { - // it's not numeric; that's fine, just continue -} -return handleTextResponse(response); -
Exception: In tests, a caught exception may be ignored
-without comment if it is named expected
. The
-following is a very common idiom for ensuring that the method under test does throw an
-exception of the expected type, so a comment is unnecessary here.
-try { - emptyStack.pop(); - fail(); -} catch (NoSuchElementException expected) { -} --
6.3 Static members: qualified using class
-When a reference to a static class member must be qualified, it is qualified with that class's -name, not with a reference or expression of that class's type.
-Foo aFoo = ...; -Foo.aStaticMethod(); // good -aFoo.aStaticMethod(); // bad -somethingThatYieldsAFoo().aStaticMethod(); // very bad --
6.4 Finalizers: not used
-It is extremely rare to override Object.finalize
.
Tip: Don't do it. If you absolutely must, first read and understand -Effective Java -Item 7, "Avoid Finalizers," very carefully, and then don't do it.
-7 Javadoc
- -7.1 Formatting
- -7.1.1 General form
-The basic formatting of Javadoc blocks is as seen in this example:
-/** - * Multiple lines of Javadoc text are written here, - * wrapped normally... - */ -public int method(String p1) { ... } -
... or in this single-line example:
-/** An especially short bit of Javadoc. */ -
The basic form is always acceptable. The single-line form may be substituted when there are no -at-clauses present, and the entirety of the Javadoc block (including comment markers) can fit on a -single line.
-7.1.2 Paragraphs
-One blank line—that is, a line containing only the aligned leading asterisk
-(*
)—appears between paragraphs, and before the group of "at-clauses" if
-present. Each paragraph but the first has <p>
immediately before the first word,
-with no space after.
7.1.3 At-clauses
-Any of the standard "at-clauses" that are used appear in the order @param
,
-@return
, @throws
, @deprecated
, and these four types never
-appear with an empty description. When an at-clause doesn't fit on a single line, continuation lines
-are indented four (or more) spaces from the position of the @
.
-
7.2 The summary fragment
-The Javadoc for each class and member begins with a brief summary fragment. This -fragment is very important: it is the only part of the text that appears in certain contexts such as -class and method indexes.
This is a fragment—a noun phrase or verb phrase, not a complete sentence. It does
-not begin with A {@code Foo} is a...
, or
-This method returns...
, nor does it form a complete imperative sentence
-like Save the record.
. However, the fragment is capitalized and
-punctuated as if it were a complete sentence.
Tip: A common mistake is to write simple Javadoc in the form
-/** @return the customer ID */
. This is incorrect, and should be
-changed to /** Returns the customer ID. */
.
7.3 Where Javadoc is used
-At the minimum, Javadoc is present for every
-public
class, and every
-public
or
-protected
member of such a class, with a few exceptions
-noted below.
Other classes and members still have Javadoc as needed. Whenever an implementation -comment would be used to define the overall purpose or behavior of a class, method or field, that -comment is written as Javadoc instead. (It's more uniform, and more tool-friendly.)
-7.3.1 Exception: self-explanatory methods
-Javadoc is optional for "simple, obvious" methods like
-getFoo
, in cases where there really and truly is
-nothing else worthwhile to say but "Returns the foo".
Important: it is not appropriate to cite this exception to justify
-omitting relevant information that a typical reader might need to know. For example, for a method
-named getCanonicalName
, don't omit its documentation
-(with the rationale that it would say only
-/** Returns the canonical name. */
) if a typical reader may have no idea
-what the term "canonical name" means!
7.3.2 Exception: overrides
-Javadoc is not always present on a method that overrides a supertype method. -
-
, , , , , , - , , and others.
+
+This means that plaintext formatting is not respected. So, don't rely on whitespace to format JSDoc:
+
+------------------------------------------
+/**
+ * Computes weight based on three factors:
+ * items sent
+ * items received
+ * last timestamp
+ */
+------------------------------------------
+
+It'll come out like this:
+
+--------------------------------------------------------------------------------
+Computes weight based on three factors: items sent items received last timestamp
+--------------------------------------------------------------------------------
+
+Instead, do this:
+
+------------------------------------------
+/**
+ * Computes weight based on three factors:
+ *
+ * - items sent
+ *
- items received
+ *
- last timestamp
+ *
+ */
+------------------------------------------
+
+The http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html[JavaDoc] style guide is a useful resource on how to write well-formed doc comments.
+
+Top/File-Level Comments
+
+A link:copyright.html[copyright notice] and author information are optional. File overviews are generally recommended whenever a file consists of more than a single class definition. The top level comment is designed to orient readers unfamiliar with the code to what is in this file. If present, it should provide a description of the file's contents and any dependencies or compatibility information. As an example:
+
+--------------------------------------------------------------
+/**
+ * @fileoverview Description of file, its uses and information
+ * about its dependencies.
+ */
+--------------------------------------------------------------
+
+Class Comments
+
+Classes must be documented with a description and a link:#constructor-tag[type tag that identifies the constructor].
+
+---------------------------------------------------------------------
+/**
+ * Class making something fun and easy.
+ * @param {string} arg1 An argument that makes this more interesting.
+ * @param {Array.} arg2 List of numbers to be processed.
+ * @constructor
+ * @extends {goog.Disposable}
+ */
+project.MyClass = function(arg1, arg2) {
+ // ...
+};
+goog.inherits(project.MyClass, goog.Disposable);
+---------------------------------------------------------------------
+
+Method and Function Comments
+
+Parameter and return types should be documented. The method description may be omitted if it is obvious from the parameter or return type descriptions. Method descriptions should start with a sentence written in the third person declarative voice.
+
+-------------------------------------------------------------------------
+/**
+ * Operates on an instance of MyClass and returns something.
+ * @param {project.MyClass} obj Instance of MyClass which leads to a long
+ * comment that needs to be wrapped to two lines.
+ * @return {boolean} Whether something occurred.
+ */
+function PR_someMethod(obj) {
+ // ...
+}
+-------------------------------------------------------------------------
+
+Property Comments
+
+---------------------------------------
+/** @constructor */
+project.MyClass = function() {
+ /**
+ * Maximum number of things per pane.
+ * @type {number}
+ */
+ this.someProperty = 4;
+}
+---------------------------------------
+
+JSDoc Tag Reference
+
+Tag
+
+Template & Examples
+
+Description
+
+@author
+
+`@author username@google.com (first last)`
+
+_For example:_
+
+--------------------------------------------------
+/**
+ * @fileoverview Utilities for handling textareas.
+ * @author kuth@google.com (Uthur Pendragon)
+ */
+--------------------------------------------------
+
+Document the author of a file or the owner of a test, generally only used in the `@fileoverview` comment.
+
+@code
+
+`{@code ...}`
+
+_For example:_
+
+----------------------------------------------------
+/**
+ * Moves to the next position in the selection.
+ * Throws {@code goog.iter.StopIteration} when it
+ * passes the end of the range.
+ * @return {Node} The node at the next position.
+ */
+goog.dom.RangeIterator.prototype.next = function() {
+ // ...
+};
+----------------------------------------------------
+
+Indicates that a term in a JSDoc description is code so it may be correctly formatted in generated documentation.
+
+@const
+
+`@const` +
+ `@const {type}`
+
+_For example:_
+
+-------------------------------------------------------
+/** @const */ var MY_BEER = 'stout';
+
+/**
+ * My namespace's favorite kind of beer.
+ * @const {string}
+ */
+mynamespace.MY_BEER = 'stout';
+
+/** @const */ MyClass.MY_BEER = 'stout';
+
+/**
+ * Initializes the request.
+ * @const
+ */
+mynamespace.Request.prototype.initialize = function() {
+ // This method cannot be overridden in a subclass.
+};
+-------------------------------------------------------
+
+Marks a variable (or property) as read-only and suitable for inlining.
+
+A `@const` variable is an immutable pointer to a value. If a variable or property marked as `@const` is overwritten, JSCompiler will give warnings.
+
+The type declaration of a constant value can be omitted if it can be clearly inferred. An additional comment about the variable is optional.
+
+When `@const` is applied to a method, it implies the method is not only not overwritable, but also that the method is _finalized_ — not overridable in subclasses.
+
+For more on `@const`, see the link:#constants[Constants] section.
+
+@constructor
+
+`@constructor`
+
+_For example:_
+
+--------------------
+/**
+ * A rectangle.
+ * @constructor
+ */
+function GM_Rect() {
+ ...
+}
+--------------------
+
+Used in a class's documentation to indicate the constructor.
+
+@define
+
+`@define {Type} description`
+
+_For example:_
+
+---------------------------------------------------------
+/** @define {boolean} */
+var TR_FLAGS_ENABLE_DEBUG = true;
+
+/**
+ * @define {boolean} Whether we know at compile-time that
+ * the browser is IE.
+ */
+goog.userAgent.ASSUME_IE = false;
+---------------------------------------------------------
+
+Indicates a constant that can be overridden by the compiler at compile-time. In the example, the compiler flag `--define='goog.userAgent.ASSUME_IE=true'` could be specified in the BUILD file to indicate that the constant `goog.userAgent.ASSUME_IE` should be replaced with `true`.
+
+@deprecated
+
+`@deprecated Description`
+
+_For example:_
+
+-------------------------------------------------
+/**
+ * Determines whether a node is a field.
+ * @return {boolean} True if the contents of
+ * the element are editable, but the element
+ * itself is not.
+ * @deprecated Use isField().
+ */
+BN_EditUtil.isTopEditableField = function(node) {
+ // ...
+};
+-------------------------------------------------
+
+Used to tell that a function, method or property should not be used any more. Always provide instructions on what callers should use instead.
+
+@dict
+
+`@dict Description`
+
+_For example:_
+
+--------------------------------------------
+/**
+ * @constructor
+ * @dict
+ */
+function Foo(x) {
+ this['x'] = x;
+}
+var obj = new Foo(123);
+var num = obj.x; // warning
+
+(/** @dict */ { x: 1 }).x = 123; // warning
+--------------------------------------------
+
+When a constructor (`Foo` in the example) is annotated with `@dict`, you can only use the bracket notation to access the properties of `Foo` objects. The annotation can also be used directly on object literals.
+
+@enum
+
+`@enum {Type}`
+
+_For example:_
+
+-----------------------------
+/**
+ * Enum for tri-state values.
+ * @enum {number}
+ */
+project.TriState = {
+ TRUE: 1,
+ FALSE: -1,
+ MAYBE: 0
+};
+-----------------------------
+
+@export
+
+`@export`
+
+_For example:_
+
+---------------------------------------------------------
+/** @export */
+foo.MyPublicClass.prototype.myPublicMethod = function() {
+ // ...
+};
+---------------------------------------------------------
+
+Given the code on the left, when the compiler is run with the `--generate_exports` flag, it will generate the code:
+
+---------------------------------------------------------------
+goog.exportSymbol('foo.MyPublicClass.prototype.myPublicMethod',
+ foo.MyPublicClass.prototype.myPublicMethod);
+---------------------------------------------------------------
+
+which will export the symbols to uncompiled code. Code that uses the `@export` annotation must either
+
+1. include `//javascript/closure/base.js`, or
+2. define both `goog.exportSymbol` and `goog.exportProperty` with the same method signature in their own codebase.
+
+@expose
+
+`@expose`
+
+_For example:_
+
+--------------------------------------
+/** @expose */
+MyClass.prototype.exposedProperty = 3;
+--------------------------------------
+
+Declares an exposed property. Exposed properties will not be removed, or renamed, or collapsed, or optimized in any way by the compiler. No properties with the same name will be able to be optimized either.
+
+`@expose` should never be used in library code, because it will prevent that property from ever getting removed.
+
+@extends
+
+` @extends Type @extends {Type} `
+
+_For example:_
+
+------------------------------------
+/**
+ * Immutable empty node list.
+ * @constructor
+ * @extends goog.ds.BasicNodeList
+ */
+goog.ds.EmptyNodeList = function() {
+ ...
+};
+------------------------------------
+
+Used with `@constructor` to indicate that a class inherits from another class. Curly braces around the type are optional.
+
+@externs
+
+`@externs`
+
+_For example:_
+
+-----------------------------------------
+/**
+ * @fileoverview This is an externs file.
+ * @externs
+ */
+
+var document;
+-----------------------------------------
+
+Declares an externs file.
+
+@fileoverview
+
+`@fileoverview Description`
+
+_For example:_
+
+-----------------------------------------------------------------------
+/**
+ * @fileoverview Utilities for doing things that require this very long
+ * but not indented comment.
+ * @author kuth@google.com (Uthur Pendragon)
+ */
+-----------------------------------------------------------------------
+
+Makes the comment block provide file level information.
+
+@implements
+
+` @implements Type @implements {Type} `
+
+_For example:_
+
+-------------------------------------
+/**
+ * A shape.
+ * @interface
+ */
+function Shape() {};
+Shape.prototype.draw = function() {};
+
+/**
+ * @constructor
+ * @implements {Shape}
+ */
+function Square() {};
+Square.prototype.draw = function() {
+ ...
+};
+-------------------------------------
+
+Used with `@constructor` to indicate that a class implements an interface. Curly braces around the type are optional.
+
+@inheritDoc
+
+`@inheritDoc`
+
+_For example:_
+
+---------------------------------------
+/** @inheritDoc */
+project.SubClass.prototype.toString() {
+ // ...
+};
+---------------------------------------
+
+Deprecated. Use `@override` instead.
+
+Indicates that a method or property of a subclass intentionally hides a method or property of the superclass, and has exactly the same documentation. Notice that `@inheritDoc` implies `@override`
+
+@interface
+
+`@interface`
+
+_For example:_
+
+-------------------------------------------
+/**
+ * A shape.
+ * @interface
+ */
+function Shape() {};
+Shape.prototype.draw = function() {};
+
+/**
+ * A polygon.
+ * @interface
+ * @extends {Shape}
+ */
+function Polygon() {};
+Polygon.prototype.getSides = function() {};
+-------------------------------------------
+
+Used to indicate that the function defines an interface.
+
+@lends
+
+`@lends objectName` +
+ `@lends {objectName}`
+
+_For example:_
+
+-------------------------------------------
+goog.object.extend(
+ Button.prototype,
+ /** @lends {Button.prototype} */ {
+ isButton: function() { return true; }
+ });
+-------------------------------------------
+
+Indicates that the keys of an object literal should be treated as properties of some other object. This annotation should only appear on object literals.
+
+Notice that the name in braces is not a type name like in other annotations. It's an object name. It names the object on which the properties are "lent". For example, `@type {Foo}` means "an instance of Foo", but `@lends {Foo}` means "the constructor Foo".
+
+The http://code.google.com/p/jsdoc-toolkit/wiki/TagLends[JSDoc Toolkit docs] have more information on this annotation.
+
+@license or @preserve
+
+`@license Description`
+
+_For example:_
+
+--------------------------------------------------------------
+/**
+ * @preserve Copyright 2009 SomeThirdParty.
+ * Here is the full license text and copyright
+ * notice for this file. Note that the notice can span several
+ * lines and is only terminated by the closing star and slash:
+ */
+--------------------------------------------------------------
+
+Anything marked by `@license` or `@preserve` will be retained by the compiler and output at the top of the compiled code for that file. This annotation allows important notices (such as legal licenses or copyright text) to survive compilation unchanged. Line breaks are preserved.
+
+@noalias
+
+`@noalias`
+
+_For example:_
+
+-------------------
+/** @noalias */
+function Range() {}
+-------------------
+
+Used in an externs file to indicate to the compiler that the variable or function should not be aliased as part of the alias externals pass of the compiler.
+
+@nocompile
+
+`@nocompile`
+
+_For example:_
+
+------------------
+/** @nocompile */
+
+// JavaScript code
+------------------
+
+Used at the top of a file to tell the compiler to parse this file but not compile it. Code that is not meant for compilation and should be omitted from compilation tests (such as bootstrap code) uses this annotation. Use sparingly.
+
+@nosideeffects
+
+`@nosideeffects`
+
+_For example:_
+
+-------------------------------------------
+/** @nosideeffects */
+function noSideEffectsFn1() {
+ // ...
+}
+
+/** @nosideeffects */
+var noSideEffectsFn2 = function() {
+ // ...
+};
+
+/** @nosideeffects */
+a.prototype.noSideEffectsFn3 = function() {
+ // ...
+};
+-------------------------------------------
+
+This annotation can be used as part of function and constructor declarations to indicate that calls to the declared function have no side-effects. This annotation allows the compiler to remove calls to these functions if the return value is not used.
+
+@override
+
+`@override`
+
+_For example:_
+
+----------------------------------------------------------------------
+/**
+ * @return {string} Human-readable representation of project.SubClass.
+ * @override
+ */
+project.SubClass.prototype.toString = function() {
+ // ...
+};
+----------------------------------------------------------------------
+
+Indicates that a method or property of a subclass intentionally hides a method or property of the superclass. If no other documentation is included, the method or property also inherits documentation from its superclass.
+
+@param
+
+`@param {Type} varname Description`
+
+_For example:_
+
+-----------------------------------------------------
+/**
+ * Queries a Baz for items.
+ * @param {number} groupNum Subgroup id to query.
+ * @param {string|number|null} term An itemName,
+ * or itemId, or null to search everything.
+ */
+goog.Baz.prototype.query = function(groupNum, term) {
+ // ...
+};
+-----------------------------------------------------
+
+Used with method, function and constructor calls to document the arguments of a function.
+
+link:#jstypes[Type] names must be enclosed in curly braces. If the type is omitted, the compiler will not type-check the parameter.
+
+@private
+
+`@private` +
+ `@private {type}`
+
+_For example:_
+
+----------------------------------------------
+/**
+ * Handlers that are listening to this logger.
+ * @private {!Array.}
+ */
+this.handlers_ = [];
+----------------------------------------------
+
+Used in conjunction with a trailing underscore on the method or property name to indicate that the member is link:#visibility--private-and-protected-fields[private] and final.
+
+@protected
+
+`@protected` +
+ `@protected {type}`
+
+_For example:_
+
+--------------------------------------------------------------------
+/**
+ * Sets the component's root element to the given element.
+ * @param {Element} element Root element for the component.
+ * @protected
+ */
+goog.ui.Component.prototype.setElementInternal = function(element) {
+ // ...
+};
+--------------------------------------------------------------------
+
+Used to indicate that the member or property is link:#visibility--private-and-protected-fields[protected]. Should be used in conjunction with names with no trailing underscore.
+
+@public
+
+`@public` +
+ `@public {type}`
+
+_For example:_
+
+--------------------------------------------------------------------------
+/**
+ * Whether to cancel the event in internal capture/bubble processing.
+ * @public {boolean}
+ * @suppress {visiblity} Referencing this outside this package is strongly
+ * discouraged.
+ */
+ goog.events.Event.prototype.propagationStopped_ = false;
+--------------------------------------------------------------------------
+
+Used to indicate that the member or property is public. Variables and properties are public by default, so this annotation is rarely necessary. Should only be used in legacy code that cannot be easily changed to override the visibility of members that were named as private variables.
+
+@return
+
+`@return {Type} Description`
+
+_For example:_
+
+------------------------------------------------
+/**
+ * @return {string} The hex ID of the last item.
+ */
+goog.Baz.prototype.getLastId = function() {
+ // ...
+ return id;
+};
+------------------------------------------------
+
+Used with method and function calls to document the return type. When writing descriptions for boolean parameters, prefer "Whether the component is visible" to "True if the component is visible, false otherwise". If there is no return value, do not use an `@return` tag.
+
+link:#jstypes[Type] names must be enclosed in curly braces. If the type is omitted, the compiler will not type-check the return value.
+
+@see
+
+`@see Link`
+
+_For example:_
+
+----------------------------------
+/**
+ * Adds a single item, recklessly.
+ * @see #addSafely
+ * @see goog.Collect
+ * @see goog.RecklessAdder#add
+ ...
+----------------------------------
+
+Reference a lookup to another class function or method.
+
+@struct
+
+`@struct Description`
+
+_For example:_
+
+--------------------------------------------------
+/**
+ * @constructor
+ * @struct
+ */
+function Foo(x) {
+ this.x = x;
+}
+var obj = new Foo(123);
+var num = obj['x']; // warning
+obj.y = "asdf"; // warning
+
+Foo.prototype = /** @struct */ {
+ method1: function() {}
+};
+Foo.prototype.method2 = function() {}; // warning
+--------------------------------------------------
+
+When a constructor (`Foo` in the example) is annotated with `@struct`, you can only use the dot notation to access the properties of `Foo` objects. Also, you cannot add new properties to `Foo` objects after they have been created. The annotation can also be used directly on object literals.
+
+@supported
+
+`@supported Description`
+
+_For example:_
+
+--------------------------------------------
+/**
+ * @fileoverview Event Manager
+ * Provides an abstracted interface to the
+ * browsers' event systems.
+ * @supported So far tested in IE6 and FF1.5
+ */
+--------------------------------------------
+
+Used in a fileoverview to indicate what browsers are supported by the file.
+
+@suppress
+
+` @suppress {warning1|warning2} ` ` @suppress {warning1,warning2} `
+
+_For example:_
+
+-------------------------
+/**
+ * @suppress {deprecated}
+ */
+function f() {
+ deprecatedVersionOfF();
+}
+-------------------------
+
+Suppresses warnings from tools. Warning categories are separated by `|` or `,`.
+
+@template
+
+`@template`
+
+_For example:_
+
+---------------------------------------------
+/**
+ * @param {function(this:T, ...)} fn
+ * @param {T} thisObj
+ * @param {...*} var_args
+ * @template T
+ */
+goog.bind = function(fn, thisObj, var_args) {
+ ...
+};
+---------------------------------------------
+
+This annotation can be used to declare a link:#template-types[template typename].
+
+@this
+
+` @this Type @this {Type} `
+
+_For example:_
+
+--------------------------------------------------
+pinto.chat.RosterWidget.extern('getRosterElement',
+/**
+ * Returns the roster widget element.
+ * @this pinto.chat.RosterWidget
+ * @return {Element}
+ */
+function() {
+ return this.getWrappedComponent_().getElement();
+});
+--------------------------------------------------
+
+The type of the object in whose context a particular method is called. Required when the `this` keyword is referenced from a function that is not a prototype method.
+
+@type
+
+` @type Type @type {Type} `
+
+_For example:_
+
+----------------------
+/**
+ * The message hex ID.
+ * @type {string}
+ */
+var hexId = hexId;
+----------------------
+
+Identifies the link:#jstypes[type] of a variable, property, or expression. Curly braces are not required around most types, but some projects mandate them for all types, for consistency.
+
+@typedef
+
+`@typedef`
+
+_For example:_
+
+-------------------------------------------------------
+/** @typedef {(string|number)} */
+goog.NumberLike;
+
+/** @param {goog.NumberLike} x A number or a string. */
+goog.readNumber = function(x) {
+ ...
+}
+-------------------------------------------------------
+
+This annotation can be used to declare an alias of a more link:#typedefs[complex type].
+
+You may also see other types of JSDoc annotations in third-party code. These annotations appear in the http://code.google.com/p/jsdoc-toolkit/wiki/TagReference[JSDoc Toolkit Tag Reference] but are currently discouraged in Google code. You should consider them "reserved" names for future use. These include:
+
+* @augments
+* @argument
+* @borrows
+* @class
+* @constant
+* @constructs
+* @default
+* @event
+* @example
+* @field
+* @function
+* @ignore
+* @inner
+* @link
+* @memberOf
+* @name
+* @namespace
+* @property
+* @public
+* @requires
+* @returns
+* @since
+* @static
+* @version
+
+=== Providing Dependencies With goog.provide
+
+
+
+Only provide top-level symbols.
+
+All members defined on a class should be in the same file. So, only top-level classes should be provided in a file that contains multiple members defined on the same class (e.g. enums, inner classes, etc).
+
+Do this:
+
+----------------------------------
+goog.provide('namespace.MyClass');
+----------------------------------
+
+Not this:
+
+-----------------------------------------------
+goog.provide('namespace.MyClass');
+goog.provide('namespace.MyClass.Enum');
+goog.provide('namespace.MyClass.InnerClass');
+goog.provide('namespace.MyClass.TypeDef');
+goog.provide('namespace.MyClass.CONSTANT');
+goog.provide('namespace.MyClass.staticMethod');
+-----------------------------------------------
+
+Members on namespaces may also be provided:
+
+---------------------------------
+goog.provide('foo.bar');
+goog.provide('foo.bar.method');
+goog.provide('foo.bar.CONSTANT');
+---------------------------------
+
+=== Compiling
+
+
+
+Required
+
+Use of JS compilers such as the http://code.google.com/closure/compiler/[Closure Compiler] is required for all customer-facing code.
+
+=== Tips and Tricks
+
+
+
+JavaScript tidbits
+
+True and False Boolean Expressions
+
+The following are all false in boolean expressions:
+
+* `null`
+* `undefined`
+* `''` the empty string
+* `0` the number
+
+But be careful, because these are all true:
+
+* `'0'` the string
+* `[]` the empty array
+* `{}` the empty object
+
+This means that instead of this:
+
+-------------------
+while (x != null) {
+-------------------
+
+you can write this shorter code (as long as you don't expect x to be 0, or the empty string, or false):
+
+-----------
+while (x) {
+-----------
+
+And if you want to check a string to see if it is null or empty, you could do this:
+
+---------------------------
+if (y != null && y != '') {
+---------------------------
+
+But this is shorter and nicer:
+
+--------
+if (y) {
+--------
+
+Caution: There are many unintuitive things about boolean expressions. Here are some of them:
+
+* ` Boolean('0') == true '0' != true`
+* ` 0 != null 0 == [] 0 == false`
+* ` Boolean(null) == false null != true null != false`
+* ` Boolean(undefined) == false undefined != true undefined != false`
+* ` Boolean([]) == true [] != true [] == false`
+* ` Boolean({}) == true {} != true {} != false`
+
+Conditional (Ternary) Operator (?:)
+
+Instead of this:
+
+---------------
+if (val) {
+ return foo();
+} else {
+ return bar();
+}
+---------------
+
+you can write this:
+
+---------------------------
+return val ? foo() : bar();
+---------------------------
+
+The ternary conditional is also useful when generating HTML:
+
+-------------------------------------
+var html = '';
+-------------------------------------
+
+&& and ||
+
+These binary boolean operators are short-circuited, and evaluate to the last evaluated term.
+
+"||" has been called the 'default' operator, because instead of writing this:
+
+--------------------------
+/** @param {*=} opt_win */
+function foo(opt_win) {
+ var win;
+ if (opt_win) {
+ win = opt_win;
+ } else {
+ win = window;
+ }
+ // ...
+}
+--------------------------
+
+you can write this:
+
+------------------------------
+/** @param {*=} opt_win */
+function foo(opt_win) {
+ var win = opt_win || window;
+ // ...
+}
+------------------------------
+
+"&&" is also useful for shortening code. For instance, instead of this:
+
+----------------------------
+if (node) {
+ if (node.kids) {
+ if (node.kids[index]) {
+ foo(node.kids[index]);
+ }
+ }
+}
+----------------------------
+
+you could do this:
+
+--------------------------------------------
+if (node && node.kids && node.kids[index]) {
+ foo(node.kids[index]);
+}
+--------------------------------------------
+
+or this:
+
+------------------------------------------------
+var kid = node && node.kids && node.kids[index];
+if (kid) {
+ foo(kid);
+}
+------------------------------------------------
+
+However, this is going a little too far:
+
+---------------------------------------------------------------
+node && node.kids && node.kids[index] && foo(node.kids[index]);
+---------------------------------------------------------------
+
+Iterating over Node Lists
+
+Node lists are often implemented as node iterators with a filter. This means that getting a property like length is O(n), and iterating over the list by re-checking the length will be O(n^2).
+
+----------------------------------------------------
+var paragraphs = document.getElementsByTagName('p');
+for (var i = 0; i < paragraphs.length; i++) {
+ doSomething(paragraphs[i]);
+}
+----------------------------------------------------
+
+It is better to do this instead:
+
+------------------------------------------------------------
+var paragraphs = document.getElementsByTagName('p');
+for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {
+ doSomething(paragraph);
+}
+------------------------------------------------------------
+
+This works well for all collections and arrays as long as the array does not contain things that are treated as boolean false.
+
+In cases where you are iterating over the childNodes you can also use the firstChild and nextSibling properties.
+
+---------------------------------------------------------------------------
+var parentNode = document.getElementById('foo');
+for (var child = parentNode.firstChild; child; child = child.nextSibling) {
+ doSomething(child);
+}
+---------------------------------------------------------------------------
+
+== Parting Words
+
+__BE CONSISTENT__.
+
+If you're editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around all their arithmetic operators, you should too. If their comments have little boxes of hash marks around them, make your comments have little boxes of hash marks around them too.
+
+The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you're saying rather than on how you're saying it. We present global style rules here so people know the vocabulary, but local style is also important. If code you add to a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Avoid this.
+
+Revision 2.93
+
+Aaron Whyte +
+ Bob Jervis +
+ Dan Pupius +
+ Erik Arvidsson +
+ Fritz Schneider +
+ Robby Walker +
diff --git a/javascriptguide.xml b/javascriptguide.xml
deleted file mode 100644
index a80a032..0000000
--- a/javascriptguide.xml
+++ /dev/null
@@ -1,3627 +0,0 @@
-
-
-
-
-
- Revision 2.93
-
-
-
- Aaron Whyte
- Bob Jervis
- Dan Pupius
- Erik Arvidsson
- Fritz Schneider
- Robby Walker
-
-
-
-
-
- This style guide contains many details that are initially
- hidden from view. They are marked by the triangle icon, which you
- see here on your left. Click it now.
- You should see "Hooray" appear below.
-
-
-
- Hooray! Now you know you can expand points to get more
- details. Alternatively, there's a "toggle all" at the
- top of this document.
-
-
-
-
-
-
- JavaScript is the main client-side scripting language used
-
- by many of Google's open-source
- projects.
- This style guide is a list of dos and don'ts for
- JavaScript programs.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Declarations with var
: Always
-
-
-
- When you fail to specify var
,
- the variable gets placed in the global context, potentially clobbering
- existing values. Also, if there's no declaration, it's hard to tell in
- what scope a variable lives (e.g., it could be in the Document or
- Window just as easily as in the local scope). So always declare with
- var
.
-
-
-
-
-
-
-
- - Use
NAMES_LIKE_THIS
for constant values.
- - Use
@const
to indicate a constant (non-overwritable)
- pointer (a variable or property).
- - Never use the
-
-
const
keyword
- as it's not supported in Internet Explorer.
-
-
-
-
-
-
- If a value is intended to be constant
- and immutable, it should be given a name
- in CONSTANT_VALUE_CASE
.
- ALL_CAPS
additionally implies @const
- (that the value is not overwritable).
-
-
- Primitive types (number
, string
,
- boolean
) are constant values.
-
- Objects
'
- immutability is more subjective — objects should be
- considered immutable only if they do not demonstrate observable
- state change. This is not enforced by the compiler.
-
-
-
-
-
- The @const
annotation on a variable or property
- implies that it is not overwritable. This is enforced by the
- compiler at build time. This behavior is consistent with the
-
- const
keyword (which we do not use due to the
- lack of support in Internet Explorer).
-
- A @const
annotation on a method additionally
- implies that the method cannot not be overridden in subclasses.
-
-
- A @const
annotation on a constructor implies the
- class cannot be subclassed (akin to final
in Java).
-
-
-
-
-
-
- Note that @const
does not necessarily imply
- CONSTANT_VALUES_CASE
.
-
- However, CONSTANT_VALUES_CASE
- does imply @const
.
-
-
-
- /**
- * Request timeout in milliseconds.
- * @type {number}
- */
- goog.example.TIMEOUT_IN_MILLISECONDS = 60;
-
-
- The number of seconds in a minute never changes. It is a
- constant value. ALL_CAPS
- also implies @const
, so the constant cannot be
- overwritten.
-
-
- The open source compiler will allow the symbol to be
- overwritten because the constant is
- not marked as @const
.
-
-
- /**
- * Map of URL to response string.
- * @const
- */
- MyClass.fetchedUrlCache_ = new goog.structs.Map();
-
-
-
- /**
- * Class that cannot be subclassed.
- * @const
- * @constructor
- */
- sloth.MyFinalClass = function() {};
-
-
- In this case, the pointer can never be overwritten, but
- value is highly mutable and not constant (and thus in
- camelCase
, not ALL_CAPS
).
-
-
-
-
-
-
-
-
- Always use semicolons.
-
-
- Relying on implicit insertion can cause subtle, hard to debug
- problems. Don't do it. You're better than that.
- There are a couple places where missing semicolons are particularly
- dangerous:
-
- // 1.
- MyClass.prototype.myMethod = function() {
- return 42;
- } // No semicolon here.
-
- (function() {
- // Some initialization code wrapped in a function to create a scope for locals.
- })();
-
-
- var x = {
- 'i': 1,
- 'j': 2
- } // No semicolon here.
-
- // 2. Trying to do one thing on Internet Explorer and another on Firefox.
- // I know you'd never write code like this, but throw me a bone.
- [ffVersion, ieVersion][isIE]();
-
-
- var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here.
-
- // 3. conditional execution a la bash
- -1 == resultOfOperation() || die();
-
-
-
- - JavaScript error - first the function returning 42 is called
- with the second function as a parameter, then the number 42 is
- "called" resulting in an error.
- - You will most likely get a 'no such property in undefined'
- error at runtime as it tries to call
-
x[ffVersion, ieVersion][isIE]()
.
- die
is always called since the array minus 1 is
- NaN
which is never equal to anything (not even if
- resultOfOperation()
returns NaN
) and
- THINGS_TO_EAT
gets assigned the result of
- die()
.
-
-
-
- JavaScript requires statements to end with a semicolon, except when
- it thinks it can safely infer their existence. In each of these
- examples, a function declaration or object or array literal is used
- inside a statement. The closing brackets are not enough to signal
- the end of the statement. Javascript never ends a statement if the
- next token is an infix or bracket operator.
- This has really surprised people, so make sure your assignments end
- with semicolons.
-
-
- Semicolons should be included at the end of function expressions,
- but not at the end of function declarations. The distinction is
- best illustrated with an example:
-
- var foo = function() {
- return true;
- }; // semicolon here.
-
- function foo() {
- return true;
- } // no semicolon here.
-
-
-
-
-
-
- Yes
-
- Nested functions can be very useful, for example in the creation of
- continuations and for the task of hiding helper functions. Feel free
- to use them.
-
-
-
-
- No
-
- Do not do this:
-
- if (x) {
- function foo() {}
- }
-
-
- While most script engines support Function Declarations within blocks
- it is not part of ECMAScript (see
- ECMA-262,
- clause 13 and 14). Worse implementations are inconsistent with each
- other and with future EcmaScript proposals. ECMAScript only allows for
- Function Declarations in the root statement list of a script or
- function. Instead use a variable initialized with a Function
- Expression to define a function within a block:
-
- if (x) {
- var foo = function() {};
- }
-
-
-
-
-
- Yes
-
- You basically can't avoid exceptions if you're doing something
- non-trivial (using an application development framework, etc.).
- Go for it.
-
-
-
-
- Yes
-
- Without custom exceptions, returning error information from a
- function that also returns a value can be tricky, not to mention
- inelegant. Bad solutions include passing in a reference type to hold
- error information or always returning Objects with a potential
- error member. These basically amount to a primitive exception
- handling hack. Feel free to use custom exceptions when
- appropriate.
-
-
-
-
- Always preferred over non-standards features
-
- For maximum portability and compatibility, always prefer standards
- features over non-standards features (e.g.,
- string.charAt(3)
over string[3]
and element
- access with DOM functions instead of using an application-specific
- shorthand).
-
-
-
-
- No
-
- There's no reason to use wrapper objects for primitive types, plus
- they're dangerous:
-
- var x = new Boolean(false);
- if (x) {
- alert('hi'); // Shows 'hi'.
- }
-
- Don't do it!
- However type casting is fine.
-
- var x = Boolean(0);
- if (x) {
- alert('hi'); // This will never be alerted.
- }
- typeof Boolean(0) == 'boolean';
- typeof new Boolean(0) == 'object';
-
- This is very useful for casting things to
- number
, string
and boolean
.
-
-
-
-
- Not preferred
-
- Multi-level prototype hierarchies are how JavaScript implements
- inheritance. You have a multi-level hierarchy if you have a
- user-defined class D with another user-defined class B as its
- prototype. These hierarchies are much harder to get right than they
- first appear!
-
- For that reason, it is best to use goog.inherits()
from
-
- the Closure Library
-
- or a similar library function.
-
-
- function D() {
- goog.base(this)
- }
- goog.inherits(D, B);
-
- D.prototype.method = function() {
- ...
- };
-
-
-
-
-
- /** @constructor */
- function SomeConstructor() {
- this.someProperty = 1;
- }
- Foo.prototype.someMethod = function() { ... };
-
- While there are several ways to attach methods and properties to an
- object created via "new", the preferred style for methods
- is:
-
- Foo.prototype.bar = function() {
- /* ... */
- };
-
- The preferred style for other properties is to initialize the field
- in the constructor:
-
- /** @constructor */
- function Foo() {
- this.bar = value;
- }
-
-
- Current JavaScript engines optimize based on the "shape"
- of an object,
- adding a property to an object (including overriding
- a value set on the prototype) changes the shape and can degrade
- performance.
-
-
-
-
-
- Prefer this.foo = null
.
-
-
- Foo.prototype.dispose = function() {
- this.property_ = null;
- };
-
- Instead of:
-
- Foo.prototype.dispose = function() {
- delete this.property_;
- };
-
- In modern JavaScript engines, changing the number of properties on an
- object is much slower than reassigning the values. The delete keyword
- should be avoided except when it is necessary to remove a property
- from an object's iterated list of keys, or to change the result of
- if (key in obj)
.
-
-
-
-
- Yes, but be careful.
-
- The ability to create closures is perhaps the most useful and often
- overlooked feature of JS. Here is
-
- a good description of how closures work.
- One thing to keep in mind, however, is that a closure keeps a pointer
- to its enclosing scope. As a result, attaching a closure to a DOM
- element can create a circular reference and thus, a memory leak. For
- example, in the following code:
-
- function foo(element, a, b) {
- element.onclick = function() { /* uses a and b */ };
- }
-
- the function closure keeps a reference to element
,
- a
, and b
even if it never uses
- element
. Since element
also keeps a
- reference to the closure, we have a cycle that won't be cleaned up by
- garbage collection. In these situations, the code can be structured
- as follows:
-
- function foo(element, a, b) {
- element.onclick = bar(a, b);
- }
-
- function bar(a, b) {
- return function() { /* uses a and b */ };
- }
-
-
-
-
-
-
- Only for code loaders and REPL (Read–eval–print loop)
-
-
- eval()
makes for confusing semantics and is dangerous
- to use if the string being eval()
'd contains user input.
- There's usually a better, clearer, and safer way to write your code,
- so its use is generally not permitted.
-
- For RPC you can always use JSON and read the result using
- JSON.parse()
instead of eval()
.
-
- Let's assume we have a server that returns something like this:
-
-
- {
- "name": "Alice",
- "id": 31502,
- "email": "looking_glass@example.com"
- }
-
-
-
- var userInfo = eval(feed);
- var email = userInfo['email'];
-
-
- If the feed was modified to include malicious JavaScript code, then
- if we use eval
then that code will be executed.
-
-
- var userInfo = JSON.parse(feed);
- var email = userInfo['email'];
-
-
- With JSON.parse
, invalid JSON (including all executable
- JavaScript) will cause an exception to be thrown.
-
-
-
-
-
- No
-
- Using with
clouds the semantics of your program.
- Because the object of the with
can have properties that
- collide with local variables, it can drastically change the meaning
- of your program. For example, what does this do?
-
- with (foo) {
- var x = 3;
- return x;
- }
-
- Answer: anything. The local variable x
could be
- clobbered by a property of foo
and perhaps it even has
- a setter, in which case assigning 3
could cause lots of
- other code to execute. Don't use with
.
-
-
-
-
-
- Only in object constructors, methods, and in setting up closures
-
-
- The semantics of this
can be tricky. At times it refers
- to the global object (in most places), the scope of the caller (in
- eval
), a node in the DOM tree (when attached using an
- event handler HTML attribute), a newly created object (in a
- constructor), or some other object (if function was
- call()
ed or apply()
ed).
- Because this is so easy to get wrong, limit its use to those places
- where it is required:
-
- - in constructors
- - in methods of objects (including in the creation of closures)
-
-
-
-
-
-
- Only for iterating over keys in an object/map/hash
-
-
- for-in
loops are often incorrectly used to loop over
- the elements in an Array
. This is however very error
- prone because it does not loop from 0
to
- length - 1
but over all the present keys in the object
- and its prototype chain. Here are a few cases where it fails:
-
- function printArray(arr) {
- for (var key in arr) {
- print(arr[key]);
- }
- }
-
- printArray([0,1,2,3]); // This works.
-
- var a = new Array(10);
- printArray(a); // This is wrong.
-
- a = document.getElementsByTagName('*');
- printArray(a); // This is wrong.
-
- a = [0,1,2,3];
- a.buhu = 'wine';
- printArray(a); // This is wrong again.
-
- a = new Array;
- a[3] = 3;
- printArray(a); // This is wrong again.
-
- Always use normal for loops when using arrays.
-
- function printArray(arr) {
- var l = arr.length;
- for (var i = 0; i < l; i++) {
- print(arr[i]);
- }
- }
-
-
-
-
-
-
- Never use Array
as a map/hash/associative array
-
-
- Associative Array
s are not allowed... or more precisely
- you are not allowed to use non number indexes for arrays. If you need
- a map/hash use Object
instead of Array
in
- these cases because the features that you want are actually features
- of Object
and not of Array
.
- Array
just happens to extend Object
(like
- any other object in JS and therefore you might as well have used
- Date
, RegExp
or String
).
-
-
-
-
- No
-
- Do not do this:
-
- var myString = 'A rather long string of English text, an error message \
- actually that just keeps going and going -- an error \
- message to make the Energizer bunny blush (right through \
- those Schwarzenegger shades)! Where was I? Oh yes, \
- you\'ve got an error and all the extraneous whitespace is \
- just gravy. Have a nice day.';
-
- The whitespace at the beginning of each line can't be safely stripped
- at compile time; whitespace after the slash will result in tricky
- errors; and while most script engines support this, it is not part
- of ECMAScript.
- Use string concatenation instead:
-
- var myString = 'A rather long string of English text, an error message ' +
- 'actually that just keeps going and going -- an error ' +
- 'message to make the Energizer bunny blush (right through ' +
- 'those Schwarzenegger shades)! Where was I? Oh yes, ' +
- 'you\'ve got an error and all the extraneous whitespace is ' +
- 'just gravy. Have a nice day.';
-
-
-
-
-
- Yes
-
- Use Array
and Object
literals instead of
- Array
and Object
constructors.
- Array constructors are error-prone due to their arguments.
-
- // Length is 3.
- var a1 = new Array(x1, x2, x3);
-
- // Length is 2.
- var a2 = new Array(x1, x2);
-
- // If x1 is a number and it is a natural number the length will be x1.
- // If x1 is a number but not a natural number this will throw an exception.
- // Otherwise the array will have one element with x1 as its value.
- var a3 = new Array(x1);
-
- // Length is 0.
- var a4 = new Array();
-
- Because of this, if someone changes the code to pass 1 argument
- instead of 2 arguments, the array might not have the expected
- length.
- To avoid these kinds of weird cases, always use the more readable
- array literal.
-
- var a = [x1, x2, x3];
- var a2 = [x1, x2];
- var a3 = [x1];
- var a4 = [];
-
- Object constructors don't have the same problems, but for readability
- and consistency object literals should be used.
-
- var o = new Object();
-
- var o2 = new Object();
- o2.a = 0;
- o2.b = 1;
- o2.c = 2;
- o2['strange key'] = 3;
-
- Should be written as:
-
- var o = {};
-
- var o2 = {
- a: 0,
- b: 1,
- c: 2,
- 'strange key': 3
- };
-
-
-
-
-
- No
-
- Modifying builtins like Object.prototype
and
- Array.prototype
are strictly forbidden. Modifying other
- builtins like Function.prototype
is less dangerous but
- still leads to hard to debug issues in production and should be
- avoided.
-
-
-
-
- No
-
- Don't do this:
-
- var f = function () {
- /*@cc_on if (@_jscript) { return 2* @*/ 3; /*@ } @*/
- };
-
- Conditional Comments hinder automated tools as they can vary the
- JavaScript syntax tree at runtime.
-
-
-
-
-
-
-
- In general, use
- functionNamesLikeThis
,
- variableNamesLikeThis
,
- ClassNamesLikeThis
,
- EnumNamesLikeThis
,
- methodNamesLikeThis
,
- CONSTANT_VALUES_LIKE_THIS
,
- foo.namespaceNamesLikeThis.bar
, and
- filenameslikethis.js
.
-
-
-
-
-
- - Private properties and methods should be named with a
- trailing underscore.
-
- - Protected properties and methods should be
- named without a trailing underscore (like public ones).
-
- For more information on private and protected,
- read the section on
-
- visibility.
-
-
-
-
-
-
-
-
- Optional function arguments start with opt_
.
- Functions that take a variable number of arguments should have the
- last argument named var_args
. You may not refer to
- var_args
in the code; use the arguments
- array.
- Optional and variable arguments can also be specified in
- @param
annotations. Although either convention is
- acceptable to the compiler, using both together is preferred.
-
-
-
-
- EcmaScript 5 getters and setters for properties are discouraged.
- However, if they are used, then getters must not change observable
- state.
-
- /**
- * WRONG -- Do NOT do this.
- */
- var foo = { get next() { return this.nextId++; } };
-
-
-
-
- Getters and setters methods for properties are not required.
- However, if they are used, then getters must be named
- getFoo()
and setters must be named
- setFoo(value)
. (For boolean getters,
- isFoo()
is also acceptable, and often sounds more
- natural.)
-
-
-
- JavaScript has no inherent packaging or namespacing support.
- Global name conflicts are difficult to debug, and can cause
- intractable problems when two projects try to integrate. In order
- to make it possible to share common JavaScript code, we've adopted
- conventions to prevent collisions.
-
- ALWAYS prefix identifiers in the global scope with a
- unique pseudo namespace related to the project or library. If you
- are working on "Project Sloth", a reasonable pseudo namespace
- would be sloth.*
.
-
- var sloth = {};
-
- sloth.sleep = function() {
- ...
- };
-
-
-
- Many JavaScript libraries, including
-
- the Closure Library
-
- and
-
- Dojo toolkit
-
- give you high-level functions for declaring your namespaces.
- Be consistent about how you declare your namespaces.
-
- goog.provide('sloth');
-
- sloth.sleep = function() {
- ...
- };
-
-
-
- When choosing a child-namespace, make sure that the owners of the
- parent namespace know what you are doing. If you start a project
- that creates hats for sloths, make sure that the Sloth team knows
- that you're using sloth.hats
.
-
-
-
- "External code" is code that comes from outside your codebase,
- and is compiled independently. Internal and external names should
- be kept strictly separate. If you're using an external library
- that makes things available in foo.hats.*
, your
- internal code should not define all its symbols in
- foo.hats.*
, because it will break if the other
- team defines new symbols.
-
- foo.require('foo.hats');
-
- /**
- * WRONG -- Do NOT do this.
- * @constructor
- * @extends {foo.hats.RoundHat}
- */
- foo.hats.BowlerHat = function() {
- };
-
- If you need to define new APIs on an external namespace, then you
- should explicitly export the public API functions, and only those
- functions. Your internal code should call the internal APIs by
- their internal names, for consistency and so that the compiler
- can optimize them better.
-
- foo.provide('googleyhats.BowlerHat');
-
- foo.require('foo.hats');
-
- /**
- * @constructor
- * @extends {foo.hats.RoundHat}
- */
- googleyhats.BowlerHat = function() {
- ...
- };
-
- goog.exportSymbol('foo.hats.BowlerHat', googleyhats.BowlerHat);
-
-
-
-
-
- Use local aliases for fully-qualified types if doing so improves
- readability. The name of a local alias should match the last part
- of the type.
-
- /**
- * @constructor
- */
- some.long.namespace.MyClass = function() {
- };
-
- /**
- * @param {some.long.namespace.MyClass} a
- */
- some.long.namespace.MyClass.staticHelper = function(a) {
- ...
- };
-
- myapp.main = function() {
- var MyClass = some.long.namespace.MyClass;
- var staticHelper = some.long.namespace.MyClass.staticHelper;
- staticHelper(new MyClass());
- };
-
- Do not create local aliases of namespaces. Namespaces should only
- be aliased using goog.scope.
-
- myapp.main = function() {
- var namespace = some.long.namespace;
- namespace.MyClass.staticHelper(new namespace.MyClass());
- };
-
- Avoid accessing properties of an aliased type, unless it is an
- enum.
-
- /** @enum {string} */
- some.long.namespace.Fruit = {
- APPLE: 'a',
- BANANA: 'b'
- };
-
- myapp.main = function() {
- var Fruit = some.long.namespace.Fruit;
- switch (fruit) {
- case Fruit.APPLE:
- ...
- case Fruit.BANANA:
- ...
- }
- };
-
-
- myapp.main = function() {
- var MyClass = some.long.namespace.MyClass;
- MyClass.staticHelper(null);
- };
-
- Never create aliases in the global scope. Use them only in
- function blocks.
-
-
-
- Filenames should be all lowercase in order to avoid confusion on
- case-sensitive platforms. Filenames should end in .js
,
- and should contain no punctuation except for -
or
- _
(prefer -
to _
).
-
-
-
-
-
-
-
- Must always succeed without side effects.
-
-
- You can control how your objects string-ify themselves by defining a
- custom toString()
method. This is fine, but you need
- to ensure that your method (1) always succeeds and (2) does not have
- side-effects. If your method doesn't meet these criteria, it's very
- easy to run into serious problems. For example, if
- toString()
calls a method that does an
- assert
, assert
might try to output the name
- of the object in which it failed, which of course requires calling
- toString()
.
-
-
-
-
- OK
-
- It isn't always possible to initialize variables at the point of
- declaration, so deferred initialization is fine.
-
-
-
-
- Always
-
- Always use explicit scope - doing so increases portability and
- clarity. For example, don't rely on window
being in the
- scope chain. You might want to use your function in another
- application for which window
is not the content
- window.
-
-
-
-
- Expand for more information.
-
- We follow the C++ formatting
- rules in spirit, with the following additional clarifications.
-
- Because of implicit semicolon insertion, always start your curly
- braces on the same line as whatever they're opening. For
- example:
-
- if (something) {
- // ...
- } else {
- // ...
- }
-
-
-
- Single-line array and object initializers are allowed when they
- fit on a line:
-
- var arr = [1, 2, 3]; // No space after [ or before ].
- var obj = {a: 1, b: 2, c: 3}; // No space after { or before }.
-
- Multiline array initializers and object initializers are indented
- 2 spaces, with the braces on their own line, just like blocks.
-
- // Object initializer.
- var inset = {
- top: 10,
- right: 20,
- bottom: 15,
- left: 12
- };
-
- // Array initializer.
- this.rows_ = [
- '"Slartibartfast" <fjordmaster@magrathea.com>',
- '"Zaphod Beeblebrox" <theprez@universe.gov>',
- '"Ford Prefect" <ford@theguide.com>',
- '"Arthur Dent" <has.no.tea@gmail.com>',
- '"Marvin the Paranoid Android" <marv@googlemail.com>',
- 'the.mice@magrathea.com'
- ];
-
- // Used in a method call.
- goog.dom.createDom(goog.dom.TagName.DIV, {
- id: 'foo',
- className: 'some-css-class',
- style: 'display:none'
- }, 'Hello, world!');
-
- Long identifiers or values present problems for aligned
- initialization lists, so always prefer non-aligned initialization.
- For example:
-
- CORRECT_Object.prototype = {
- a: 0,
- b: 1,
- lengthyName: 2
- };
-
- Not like this:
-
- WRONG_Object.prototype = {
- a : 0,
- b : 1,
- lengthyName: 2
- };
-
-
-
- When possible, all function arguments should be listed on the same
- line. If doing so would exceed the 80-column limit, the arguments
- must be line-wrapped in a readable way. To save space, you may wrap
- as close to 80 as possible, or put each argument on its own line to
- enhance readability. The indentation may be either four spaces, or
- aligned to the parenthesis. Below are the most common patterns for
- argument wrapping:
-
- // Four-space, wrap at 80. Works with very long function names, survives
- // renaming without reindenting, low on space.
- goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
- veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
- tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
- // ...
- };
-
- // Four-space, one argument per line. Works with long function names,
- // survives renaming, and emphasizes each argument.
- goog.foo.bar.doThingThatIsVeryDifficultToExplain = function(
- veryDescriptiveArgumentNumberOne,
- veryDescriptiveArgumentTwo,
- tableModelEventHandlerProxy,
- artichokeDescriptorAdapterIterator) {
- // ...
- };
-
- // Parenthesis-aligned indentation, wrap at 80. Visually groups arguments,
- // low on space.
- function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo,
- tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) {
- // ...
- }
-
- // Parenthesis-aligned, one argument per line. Emphasizes each
- // individual argument.
- function bar(veryDescriptiveArgumentNumberOne,
- veryDescriptiveArgumentTwo,
- tableModelEventHandlerProxy,
- artichokeDescriptorAdapterIterator) {
- // ...
- }
-
- When the function call is itself indented, you're free to start the
- 4-space indent relative to the beginning of the original statement
- or relative to the beginning of the current function call.
- The following are all acceptable indentation styles.
-
- if (veryLongFunctionNameA(
- veryLongArgumentName) ||
- veryLongFunctionNameB(
- veryLongArgumentName)) {
- veryLongFunctionNameC(veryLongFunctionNameD(
- veryLongFunctioNameE(
- veryLongFunctionNameF)));
- }
-
-
-
- When declaring an anonymous function in the list of arguments for
- a function call, the body of the function is indented two spaces
- from the left edge of the statement, or two spaces from the left
- edge of the function keyword. This is to make the body of the
- anonymous function easier to read (i.e. not be all squished up into
- the right half of the screen).
-
- prefix.something.reallyLongFunctionName('whatever', function(a1, a2) {
- if (a1.equals(a2)) {
- someOtherLongFunctionName(a1);
- } else {
- andNowForSomethingCompletelyDifferent(a2.parrot);
- }
- });
-
- var names = prefix.something.myExcellentMapFunction(
- verboselyNamedCollectionOfItems,
- function(item) {
- return item.name;
- });
-
-
-
-
-
- goog.scope
- may be used to shorten references to
- namespaced symbols in programs using
- the Closure
- Library.
- Only one goog.scope
invocation may be added per
- file. Always place it in the global scope.
- The opening goog.scope(function() {
invocation
- must be preceded by exactly one blank line and follow any
- goog.provide
statements, goog.require
- statements, or top-level comments. The invocation must be closed on
- the last line in the file. Append // goog.scope
to the
- closing statement of the scope. Separate the comment from the
- semicolon by two spaces.
- Similar to C++ namespaces, do not indent under goog.scope
- declarations. Instead, continue from the 0 column.
- Only alias names that will not be re-assigned to another object
- (e.g., most constructors, enums, and namespaces). Do not do
- this (see below for how to alias a constructor):
-
-
- goog.scope(function() {
- var Button = goog.ui.Button;
-
- Button = function() { ... };
- ...
-
-
- Names must be the same as the last property of the global that they
- are aliasing.
-
-
- goog.provide('my.module.SomeType');
-
- goog.require('goog.dom');
- goog.require('goog.ui.Button');
-
- goog.scope(function() {
- var Button = goog.ui.Button;
- var dom = goog.dom;
-
- // Alias new types after the constructor declaration.
- my.module.SomeType = function() { ... };
- var SomeType = my.module.SomeType;
-
- // Declare methods on the prototype as usual:
- SomeType.prototype.findButton = function() {
- // Button as aliased above.
- this.button = new Button(dom.getElement('my-button'));
- };
- ...
- }); // goog.scope
-
-
-
- Except for array literals,
- object literals, and anonymous functions, all wrapped lines
- should be indented either left-aligned to a sibling expression
- above, or four spaces (not two spaces) deeper than a parent
- expression (where "sibling" and "parent" refer to parenthesis
- nesting level).
-
-
-
- someWonderfulHtml = '' +
- getEvenMoreHtml(someReallyInterestingValues, moreValues,
- evenMoreParams, 'a duck', true, 72,
- slightlyMoreMonkeys(0xfff)) +
- '';
-
- thisIsAVeryLongVariableName =
- hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine();
-
- thisIsAVeryLongVariableName = siblingOne + siblingTwo + siblingThree +
- siblingFour + siblingFive + siblingSix + siblingSeven +
- moreSiblingExpressions + allAtTheSameIndentationLevel;
-
- thisIsAVeryLongVariableName = operandOne + operandTwo + operandThree +
- operandFour + operandFive * (
- aNestedChildExpression + shouldBeIndentedMore);
-
- someValue = this.foo(
- shortArg,
- 'Some really long string arg - this is a pretty common case, actually.',
- shorty2,
- this.bar());
-
- if (searchableCollection(allYourStuff).contains(theStuffYouWant) &&
- !ambientNotification.isActive() && (client.isAmbientSupported() ||
- client.alwaysTryAmbientAnyways())) {
- ambientNotification.activate();
- }
-
-
-
- Use newlines to group logically related pieces of code.
- For example:
-
- doSomethingTo(x);
- doSomethingElseTo(x);
- andThen(x);
-
- nowDoSomethingWith(y);
-
- andNowWith(z);
-
-
-
- Always put the operator on the preceding line. Otherwise,
- line breaks and indentation follow the same rules as in other
- Google style guides. This operator placement was initially agreed
- upon out of concerns about automatic semicolon insertion. In fact,
- semicolon insertion cannot happen before a binary operator, but new
- code should stick to this style for consistency.
-
- var x = a ? b : c; // All on one line if it will fit.
-
- // Indentation +4 is OK.
- var y = a ?
- longButSimpleOperandB : longButSimpleOperandC;
-
- // Indenting to the line position of the first operand is also OK.
- var z = a ?
- moreComplicatedB :
- moreComplicatedC;
-
- This includes the dot operator.
-
- var x = foo.bar().
- doSomething().
- doSomethingElse();
-
-
-
-
-
-
- Only where required
-
- Use sparingly and in general only where required by the syntax
- and semantics.
- Never use parentheses for unary operators such as
- delete
, typeof
and void
or
- after keywords such as return
, throw
as
- well as others (case
, in
or
- new
).
-
-
-
-
- Prefer ' over "
-
- For consistency single-quotes (') are preferred to double-quotes (").
- This is helpful when creating strings that include HTML:
-
- var msg = 'This is some HTML';
-
-
-
-
-
- Encouraged, use JSDoc annotations @private
and
- @protected
-
- We recommend the use of the JSDoc annotations @private
and
- @protected
to indicate visibility levels for classes,
- functions, and properties.
- The --jscomp_warning=visibility compiler flag turns on compiler
- warnings for visibility violations. See
-
- Closure Compiler
- Warnings.
-
- @private
global variables and functions are only
- accessible to code in the same file.
- Constructors marked @private
may only be instantiated by
- code in the same file and by their static and instance members.
- @private
constructors may also be accessed anywhere in the
- same file for their public static properties and by the
- instanceof
operator.
- Global variables, functions, and constructors should never be
- annotated @protected
.
-
- // File 1.
- // AA_PrivateClass_ and AA_init_ are accessible because they are global
- // and in the same file.
-
- /**
- * @private
- * @constructor
- */
- AA_PrivateClass_ = function() {
- };
-
- /** @private */
- function AA_init_() {
- return new AA_PrivateClass_();
- }
-
- AA_init_();
-
- @private
properties are accessible to all code in the
- same file, plus all static methods and instance methods of that class
- that "owns" the property, if the property belongs to a class. They
- cannot be accessed or overridden from a subclass in a different file.
- @protected
properties are accessible to all code in the
- same file, plus any static methods and instance methods of any subclass
- of a class that "owns" the property.
- Note that these semantics differ from those of C++ and Java, in that
- they grant private and protected access to all code in the same file,
- not just in the same class or class hierarchy. Also, unlike in C++,
- private properties cannot be overridden by a subclass.
-
-
- // File 1.
-
- /** @constructor */
- AA_PublicClass = function() {
- /** @private */
- this.privateProp_ = 2;
-
- /** @protected */
- this.protectedProp = 4;
- };
-
- /** @private */
- AA_PublicClass.staticPrivateProp_ = 1;
-
- /** @protected */
- AA_PublicClass.staticProtectedProp = 31;
-
- /** @private */
- AA_PublicClass.prototype.privateMethod_ = function() {};
-
- /** @protected */
- AA_PublicClass.prototype.protectedMethod = function() {};
-
- // File 2.
-
- /**
- * @return {number} The number of ducks we've arranged in a row.
- */
- AA_PublicClass.prototype.method = function() {
- // Legal accesses of these two properties.
- return this.privateProp_ + AA_PublicClass.staticPrivateProp_;
- };
-
- // File 3.
-
- /**
- * @constructor
- * @extends {AA_PublicClass}
- */
- AA_SubClass = function() {
- // Legal access of a protected static property.
- AA_PublicClass.staticProtectedProp = this.method();
- };
- goog.inherits(AA_SubClass, AA_PublicClass);
-
- /**
- * @return {number} The number of ducks we've arranged in a row.
- */
- AA_SubClass.prototype.method = function() {
- // Legal access of a protected instance property.
- return this.protectedProp;
- };
-
-
- Notice that in JavaScript, there is no distinction between a type
- (like AA_PrivateClass_
) and the constructor for that
- type. There is no way to express both that a type is public and its
- constructor is private (because the constructor could easily be aliased
- in a way that would defeat the privacy check).
-
-
-
-
- Encouraged and enforced by the compiler.
-
-
- When documenting a type in JSDoc, be as specific and accurate as
- possible. The types we support are based on the
-
- EcmaScript 4 spec.
-
- The ES4 proposal contained a language for specifying JavaScript
- types. We use this language in JsDoc to express the types of
- function parameters and return values.
-
- As the ES4 proposal has evolved, this language has changed. The
- compiler still supports old syntaxes for types, but those syntaxes
- are deprecated.
-
-
-
-
-
- Syntax Name
- Syntax
- Description
- Deprecated Syntaxes
-
-
-
-
- Primitive Type
-
- There are 5 primitive types in JavaScript:
- {null}
,
- {undefined}
,
- {boolean}
,
- {number}
, and
- {string}
.
-
- Simply the name of a type.
-
-
-
-
- Instance Type
-
- {Object}
- An instance of Object or null.
- {Function}
- An instance of Function or null.
- {EventTarget}
- An instance of a constructor that implements the EventTarget
- interface, or null.
-
- An instance of a constructor or interface function.
-
- Constructor functions are functions defined with the
- @constructor
JSDoc tag.
- Interface functions are functions defined with the
- @interface
JSDoc tag.
-
- By default, instance types will accept null. This is the only
- type syntax that makes the type nullable. Other type syntaxes
- in this table will not accept null.
-
-
-
-
-
- Enum Type
-
- {goog.events.EventType}
- One of the properties of the object literal initializer
- of goog.events.EventType
.
-
- An enum must be initialized as an object literal, or as
- an alias of another enum, annotated with the @enum
- JSDoc tag. The properties of this literal are the instances
- of the enum. The syntax of the enum is defined
- below.
-
- Note that this is one of the few things in our type system
- that were not in the ES4 spec.
-
-
-
-
-
- Type Application
-
- {Array.<string>}
An array of strings.
- {Object.<string, number>}
-
An object in which the keys are strings and the values
- are numbers.
-
- Parameterizes a type, by applying a set of type arguments
- to that type. The idea is analogous to generics in Java.
-
-
-
-
-
- Type Union
-
- {(number|boolean)}
A number or a boolean.
-
- Indicates that a value might have type A OR type B.
-
- The parentheses may be omitted at the top-level
- expression, but the parentheses should be included in
- sub-expressions to avoid ambiguity.
- {number|boolean}
- {function(): (number|boolean)}
-
-
- {(number,boolean)}
,
- {(number||boolean)}
-
-
-
-
- Nullable type
-
- {?number}
A number or null.
-
- Shorthand for the union of the null type with any
- other type. This is just syntactic sugar.
-
-
- {number?}
-
-
-
-
- Non-nullable type
-
- {!Object}
An Object, but never the
- null
value.
-
- Filters null out of nullable types. Most often used
- with instance types, which are nullable by default.
-
-
- {Object!}
-
-
-
-
- Record Type
-
- {{myNum: number, myObject}}
-
An anonymous type with the given type members.
-
-
- Indicates that the value has the specified members with the
- specified types. In this case, myNum
with a
- type number
and myObject
with any
- type.
- Notice that the braces are part of the type syntax. For
- example, to denote an Array
of objects that
- have a length
property, you might write
- Array.<{length}>
.
-
-
-
-
-
- Function Type
-
- {function(string, boolean)}
- A function that takes two arguments (a string and a boolean),
- and has an unknown return value.
-
- Specifies a function.
-
-
-
-
- Function Return Type
-
- {function(): number}
- A function that takes no arguments and returns a number.
-
- Specifies a function return type.
-
-
-
-
- Function this
Type
-
- {function(this:goog.ui.Menu, string)}
- A function that takes one argument (a string), and executes
- in the context of a goog.ui.Menu.
-
- Specifies the context type of a function type.
-
-
-
-
- Function new
Type
-
- {function(new:goog.ui.Menu, string)}
- A constructor that takes one argument (a string), and
- creates a new instance of goog.ui.Menu when called
- with the 'new' keyword.
-
- Specifies the constructed type of a constructor.
-
-
-
-
- Variable arguments
-
- {function(string, ...[number]): number}
- A function that takes one argument (a string), and then a
- variable number of arguments that must be numbers.
-
- Specifies variable arguments to a function.
-
-
-
-
-
-
- Variable arguments (in @param
annotations)
-
-
- @param {...number} var_args
- A variable number of arguments to an annotated function.
-
-
- Specifies that the annotated function accepts a variable
- number of arguments.
-
-
-
-
-
- Function optional arguments
-
- {function(?string=, number=)}
- A function that takes one optional, nullable string and one
- optional number as arguments. The =
syntax is
- only for function
type declarations.
-
- Specifies optional arguments to a function.
-
-
-
-
-
-
- Function optional arguments
- (in @param
annotations)
-
-
- @param {number=} opt_argument
- An optional parameter of type number
.
-
- Specifies that the annotated function accepts an optional
- argument.
-
-
-
-
- The ALL type
- {*}
- Indicates that the variable can take on any type.
-
-
-
-
- The UNKNOWN type
- {?}
- Indicates that the variable can take on any type,
- and the compiler should not type-check any uses of it.
-
-
-
-
-
-
-
-
-
-
- Type Example
- Value Examples
- Description
-
-
-
-
-
- number
-
-
- 1
- 1.0
- -5
- 1e5
- Math.PI
-
-
-
-
-
-
- Number
-
-
- new Number(true)
-
-
-
-
- Number object
-
-
-
-
-
- string
-
-
- 'Hello'
- "World"
- String(42)
-
-
-
- String value
-
-
-
-
- String
-
-
- new String('Hello')
- new String(42)
-
-
-
-
- String object
-
-
-
-
-
- boolean
-
-
- true
- false
- Boolean(0)
-
-
-
- Boolean value
-
-
-
-
- Boolean
-
-
- new Boolean(true)
-
-
-
-
- Boolean object
-
-
-
-
-
- RegExp
-
-
- new RegExp('hello')
- /world/g
-
-
-
-
-
- Date
-
-
- new Date
- new Date()
-
-
-
-
-
-
-
- null
-
-
-
-
- null
-
-
-
-
-
-
-
-
- undefined
-
-
-
-
- undefined
-
-
-
-
-
-
- void
-
-
- function f() {
- return;
- }
-
-
- No return value
-
-
-
- Array
-
-
- ['foo', 0.3, null]
- []
-
-
- Untyped Array
-
-
-
- Array.<number>
-
-
- [11, 22, 33]
-
-
-
- An Array of numbers
-
-
-
-
- Array.<Array.<string>>
-
-
- [['one', 'two', 'three'], ['foo', 'bar']]
-
-
- Array of Arrays of strings
-
-
-
- Object
-
-
- {}
- {foo: 'abc', bar: 123, baz: null}
-
-
-
-
-
-
- Object.<string>
-
-
- {'foo': 'bar'}
-
-
-
- An Object in which the values are strings.
-
-
-
-
- Object.<number, string>
-
-
- var obj = {};
- obj[1] = 'bar';
-
-
-
- An Object in which the keys are numbers and the values are
- strings. Note that in JavaScript, the keys are always
- implicitly converted to strings, so
- obj['1'] == obj[1]
.
- So the key will always be a string in for...in loops. But the
- compiler will verify the type of the key when indexing into
- the object.
-
-
-
-
- Function
-
-
- function(x, y) {
- return x * y;
- }
-
-
-
-
- Function object
-
-
-
-
-
- function(number, number): number
-
-
- function(x, y) {
- return x * y;
- }
-
-
- function value
-
-
-
- SomeClass
-
-
- /** @constructor */
- function SomeClass() {}
-
- new SomeClass();
-
-
-
-
-
-
- SomeInterface
-
-
- /** @interface */
- function SomeInterface() {}
-
- SomeInterface.prototype.draw = function() {};
-
-
-
-
-
-
- project.MyClass
-
-
- /** @constructor */
- project.MyClass = function () {}
-
- new project.MyClass()
-
-
-
-
-
-
- project.MyEnum
-
-
- /** @enum {string} */
- project.MyEnum = {
- /** The color blue. */
- BLUE: '#0000dd',
- /** The color red. */
- RED: '#dd0000'
- };
-
-
- Enumeration
- JSDoc comments on enum values are optional.
-
-
-
-
- Element
-
-
- document.createElement('div')
-
-
- Elements in the DOM.
-
-
-
- Node
-
-
- document.body.firstChild
-
-
- Nodes in the DOM.
-
-
-
- HTMLInputElement
-
-
- htmlDocument.getElementsByTagName('input')[0]
-
-
- A specific type of DOM element.
-
-
-
-
-
-
- In cases where type-checking doesn't accurately infer the type of
- an expression, it is possible to add a type cast comment by adding a
- type annotation comment and enclosing the expression in
- parentheses. The parentheses are required.
-
-
- /** @type {number} */ (x)
-
-
-
-
-
- Because JavaScript is a loosely-typed language, it is very
- important to understand the subtle differences between optional,
- nullable, and undefined function parameters and class
- properties.
-
- Instances of classes and interfaces are nullable by default.
- For example, the following declaration
-
-
- /**
- * Some class, initialized with a value.
- * @param {Object} value Some value.
- * @constructor
- */
- function MyClass(value) {
- /**
- * Some value.
- * @type {Object}
- * @private
- */
- this.myValue_ = value;
- }
-
-
- tells the compiler that the myValue_
property holds
- either an Object or null. If myValue_
must never be
- null, it should be declared like this:
-
-
- /**
- * Some class, initialized with a non-null value.
- * @param {!Object} value Some value.
- * @constructor
- */
- function MyClass(value) {
- /**
- * Some value.
- * @type {!Object}
- * @private
- */
- this.myValue_ = value;
- }
-
-
- This way, if the compiler can determine that somewhere in the code
- MyClass
is initialized with a null value, it will issue
- a warning.
-
-
-
- Optional parameters to functions may be undefined at runtime, so if
- they are assigned to class properties, those properties must be
- declared accordingly:
-
-
- /**
- * Some class, initialized with an optional value.
- * @param {Object=} opt_value Some value (optional).
- * @constructor
- */
- function MyClass(opt_value) {
- /**
- * Some value.
- * @type {Object|undefined}
- * @private
- */
- this.myValue_ = opt_value;
- }
-
-
- This tells the compiler that myValue_
may hold an
- Object, null, or remain undefined.
-
- Note that the optional parameter opt_value
is declared
- to be of type {Object=}
, not
- {Object|undefined}
. This is because optional
- parameters may, by definition, be undefined. While there is no harm
- in explicitly declaring an optional parameter as possibly undefined,
- it is both unnecessary and makes the code harder to read.
-
- Finally, note that being nullable and being optional are orthogonal
- properties. The following four declarations are all different:
-
-
- /**
- * Takes four arguments, two of which are nullable, and two of which are
- * optional.
- * @param {!Object} nonNull Mandatory (must not be undefined), must not be null.
- * @param {Object} mayBeNull Mandatory (must not be undefined), may be null.
- * @param {!Object=} opt_nonNull Optional (may be undefined), but if present,
- * must not be null!
- * @param {Object=} opt_mayBeNull Optional (may be undefined), may be null.
- */
- function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) {
- // ...
- };
-
-
-
-
-
- Sometimes types can get complicated. A function that accepts
- content for an Element might look like:
-
-
- /**
- * @param {string} tagName
- * @param {(string|Element|Text|Array.<Element>|Array.<Text>)} contents
- * @return {!Element}
- */
- goog.createElement = function(tagName, contents) {
- ...
- };
-
-
- You can define commonly used type expressions with a
- @typedef
tag. For example,
-
-
- /** @typedef {(string|Element|Text|Array.<Element>|Array.<Text>)} */
- goog.ElementContent;
-
- /**
- * @param {string} tagName
- * @param {goog.ElementContent} contents
- * @return {!Element}
- */
- goog.createElement = function(tagName, contents) {
- ...
- };
-
-
-
-
-
- The compiler has limited support for template types. It can only
- infer the type of this
inside an anonymous function
- literal from the type of the this
argument and whether the
- this
argument is missing.
-
-
- /**
- * @param {function(this:T, ...)} fn
- * @param {T} thisObj
- * @param {...*} var_args
- * @template T
- */
- goog.bind = function(fn, thisObj, var_args) {
- ...
- };
- // Possibly generates a missing property warning.
- goog.bind(function() { this.someProperty; }, new SomeClass());
- // Generates an undefined this warning.
- goog.bind(function() { this.someProperty; });
-
-
-
-
-
-
- Use JSDoc
-
-
- We follow the
-
- C++ style for comments in spirit.
-
-
- All files, classes, methods and properties should be documented with
- JSDoc
- comments with the appropriate tags
- and types. Textual descriptions for properties,
- methods, method parameters and method return values should be included
- unless obvious from the property, method, or parameter name.
-
-
- Inline comments should be of the //
variety.
-
- Complete sentences are recommended but not required.
- Complete sentences should use appropriate capitalization
- and punctuation.
-
-
- The JSDoc syntax is based on
-
- JavaDoc. Many tools extract metadata from JSDoc comments to
- perform code validation and optimizations. These comments must be
- well-formed.
-
-
- /**
- * A JSDoc comment should begin with a slash and 2 asterisks.
- * Inline tags should be enclosed in braces like {@code this}.
- * @desc Block tags should always start on their own line.
- */
-
-
-
-
- If you have to line break a block tag, you should treat this as
- breaking a code statement and indent it four spaces.
-
-
- /**
- * Illustrates line wrapping for long param/return descriptions.
- * @param {string} foo This is a param with a description too long to fit in
- * one line.
- * @return {number} This returns something that has a description too long to
- * fit in one line.
- */
- project.MyClass.prototype.method = function(foo) {
- return 5;
- };
-
-
- You should not indent the @fileoverview
command. You do not have to
- indent the @desc
command.
-
- Even though it is not preferred, it is also acceptable to line up
- the description.
-
-
- /**
- * This is NOT the preferred indentation method.
- * @param {string} foo This is a param with a description too long to fit in
- * one line.
- * @return {number} This returns something that has a description too long to
- * fit in one line.
- */
- project.MyClass.prototype.method = function(foo) {
- return 5;
- };
-
-
-
-
- Like JavaDoc, JSDoc supports many HTML tags, like <code>,
- <pre>, <tt>, <strong>, <ul>, <ol>,
- <li>, <a>, and others.
-
- This means that plaintext formatting is not respected. So, don't
- rely on whitespace to format JSDoc:
-
-
- /**
- * Computes weight based on three factors:
- * items sent
- * items received
- * last timestamp
- */
-
-
- It'll come out like this:
-
-
- Computes weight based on three factors: items sent items received last timestamp
-
-
- Instead, do this:
-
-
- /**
- * Computes weight based on three factors:
- * <ul>
- * <li>items sent
- * <li>items received
- * <li>last timestamp
- * </ul>
- */
-
-
- The
- JavaDoc style guide is a useful resource on how to write
- well-formed doc comments.
-
-
-
-
-
- A copyright notice and author information are optional.
- File overviews are generally recommended whenever a file consists of
- more than a single class definition. The top level comment is
- designed to orient readers unfamiliar with the code to what is in
- this file. If present, it should provide a description of the
- file's contents and any dependencies or compatibility information.
- As an example:
-
-
-
- /**
- * @fileoverview Description of file, its uses and information
- * about its dependencies.
- */
-
-
-
-
-
-
- Classes must be documented with a description and a
- type tag that
- identifies the constructor.
-
-
-
- /**
- * Class making something fun and easy.
- * @param {string} arg1 An argument that makes this more interesting.
- * @param {Array.<number>} arg2 List of numbers to be processed.
- * @constructor
- * @extends {goog.Disposable}
- */
- project.MyClass = function(arg1, arg2) {
- // ...
- };
- goog.inherits(project.MyClass, goog.Disposable);
-
-
-
-
- Parameter and return types should be documented. The method
- description may be omitted if it is obvious from the parameter
- or return type descriptions. Method descriptions should start
- with a sentence written in the third person declarative voice.
-
- /**
- * Operates on an instance of MyClass and returns something.
- * @param {project.MyClass} obj Instance of MyClass which leads to a long
- * comment that needs to be wrapped to two lines.
- * @return {boolean} Whether something occurred.
- */
- function PR_someMethod(obj) {
- // ...
- }
-
-
-
-
-
- /** @constructor */
- project.MyClass = function() {
- /**
- * Maximum number of things per pane.
- * @type {number}
- */
- this.someProperty = 4;
- }
-
-
-
-
-
-
-
-
-
- Tag
- Template & Examples
- Description
-
-
-
-
-
- @author
-
-
-
- @author username@google.com (first last)
- For example:
-
- /**
- * @fileoverview Utilities for handling textareas.
- * @author kuth@google.com (Uthur Pendragon)
- */
-
-
-
- Document the author of a file or the owner of a test,
- generally only used in the @fileoverview
comment.
-
-
-
-
-
-
-
- @code
-
- {@code ...}
- For example:
-
- /**
- * Moves to the next position in the selection.
- * Throws {@code goog.iter.StopIteration} when it
- * passes the end of the range.
- * @return {Node} The node at the next position.
- */
- goog.dom.RangeIterator.prototype.next = function() {
- // ...
- };
-
-
-
- Indicates that a term in a JSDoc description is code so it may
- be correctly formatted in generated documentation.
-
-
-
-
- @const
-
- @const
- @const {type}
- For example:
-
- /** @const */ var MY_BEER = 'stout';
-
- /**
- * My namespace's favorite kind of beer.
- * @const {string}
- */
- mynamespace.MY_BEER = 'stout';
-
- /** @const */ MyClass.MY_BEER = 'stout';
-
- /**
- * Initializes the request.
- * @const
- */
- mynamespace.Request.prototype.initialize = function() {
- // This method cannot be overridden in a subclass.
- };
-
-
-
- Marks a variable (or property) as read-only and suitable
- for inlining.
-
- A @const
variable is an immutable pointer to
- a value. If a variable or property marked as
- @const
is overwritten, JSCompiler will give
- warnings.
-
- The type declaration of a constant value can be omitted
- if it can be clearly inferred. An additional comment about
- the variable is optional.
-
- When @const
is applied to a method, it
- implies the method is not only not overwritable, but also
- that the method is finalized —
- not overridable in subclasses.
-
- For more on @const
, see the
- Constants section.
-
-
-
-
-
- @constructor
-
- @constructor
- For example:
-
- /**
- * A rectangle.
- * @constructor
- */
- function GM_Rect() {
- ...
- }
-
-
-
- Used in a class's documentation to indicate the constructor.
-
-
-
-
- @define
-
- @define {Type} description
- For example:
-
- /** @define {boolean} */
- var TR_FLAGS_ENABLE_DEBUG = true;
-
- /**
- * @define {boolean} Whether we know at compile-time that
- * the browser is IE.
- */
- goog.userAgent.ASSUME_IE = false;
-
-
-
- Indicates a constant that can be overridden by the compiler at
- compile-time. In the example, the compiler flag
- --define='goog.userAgent.ASSUME_IE=true'
- could be specified in the BUILD file to indicate that the
- constant goog.userAgent.ASSUME_IE
should be replaced
- with true
.
-
-
-
-
- @deprecated
-
- @deprecated Description
- For example:
-
- /**
- * Determines whether a node is a field.
- * @return {boolean} True if the contents of
- * the element are editable, but the element
- * itself is not.
- * @deprecated Use isField().
- */
- BN_EditUtil.isTopEditableField = function(node) {
- // ...
- };
-
-
-
- Used to tell that a function, method or property should not be
- used any more. Always provide instructions on what callers
- should use instead.
-
-
-
-
- @dict
-
- @dict Description
- For example:
-
- /**
- * @constructor
- * @dict
- */
- function Foo(x) {
- this['x'] = x;
- }
- var obj = new Foo(123);
- var num = obj.x; // warning
-
- (/** @dict */ { x: 1 }).x = 123; // warning
-
-
-
- When a constructor (Foo
in the example) is
- annotated with @dict
, you can only use the
- bracket notation to access the properties of Foo
- objects.
- The annotation can also be used directly on object literals.
-
-
-
-
- @enum
-
- @enum {Type}
- For example:
-
- /**
- * Enum for tri-state values.
- * @enum {number}
- */
- project.TriState = {
- TRUE: 1,
- FALSE: -1,
- MAYBE: 0
- };
-
-
-
-
-
- @export
-
- @export
- For example:
-
- /** @export */
- foo.MyPublicClass.prototype.myPublicMethod = function() {
- // ...
- };
-
-
-
- Given the code on the left, when the compiler is run with
- the --generate_exports
flag, it will generate the
- code:
-
- goog.exportSymbol('foo.MyPublicClass.prototype.myPublicMethod',
- foo.MyPublicClass.prototype.myPublicMethod);
-
- which will export the symbols to uncompiled code.
- Code that uses the @export
annotation must either
-
- - include
//javascript/closure/base.js
, or
- - define both
goog.exportSymbol
and
- goog.exportProperty
with the same method
- signature in their own codebase.
-
-
-
-
-
- @expose
-
- @expose
- For example:
-
- /** @expose */
- MyClass.prototype.exposedProperty = 3;
-
-
-
-
- Declares an exposed property. Exposed properties
- will not be removed, or renamed, or collapsed,
- or optimized in any way by the compiler. No properties
- with the same name will be able to be optimized either.
-
-
-
- @expose
should never be used in library code,
- because it will prevent that property from ever getting
- removed.
-
-
-
-
-
- @extends
-
-
- @extends Type
- @extends {Type}
-
- For example:
-
- /**
- * Immutable empty node list.
- * @constructor
- * @extends goog.ds.BasicNodeList
- */
- goog.ds.EmptyNodeList = function() {
- ...
- };
-
-
-
- Used with @constructor
to indicate that a class
- inherits from another class. Curly braces around the type are
- optional.
-
-
-
-
- @externs
-
- @externs
- For example:
-
- /**
- * @fileoverview This is an externs file.
- * @externs
- */
-
- var document;
-
-
-
-
- Declares an
-
- externs file.
-
-
-
-
-
-
-
- @fileoverview
-
- @fileoverview Description
- For example:
-
- /**
- * @fileoverview Utilities for doing things that require this very long
- * but not indented comment.
- * @author kuth@google.com (Uthur Pendragon)
- */
-
-
- Makes the comment block provide file level information.
-
-
-
- @implements
-
-
- @implements Type
- @implements {Type}
-
- For example:
-
- /**
- * A shape.
- * @interface
- */
- function Shape() {};
- Shape.prototype.draw = function() {};
-
- /**
- * @constructor
- * @implements {Shape}
- */
- function Square() {};
- Square.prototype.draw = function() {
- ...
- };
-
-
-
- Used with @constructor
to indicate that a class
- implements an interface. Curly braces around the type are
- optional.
-
-
-
-
- @inheritDoc
-
- @inheritDoc
- For example:
-
- /** @inheritDoc */
- project.SubClass.prototype.toString() {
- // ...
- };
-
-
-
- Deprecated. Use
- @override
instead.
-
- Indicates that a method or property of a subclass
- intentionally hides a method or property of the superclass,
- and has exactly the same documentation. Notice that
- @inheritDoc
implies @override
-
-
-
-
- @interface
-
- @interface
- For example:
-
- /**
- * A shape.
- * @interface
- */
- function Shape() {};
- Shape.prototype.draw = function() {};
-
- /**
- * A polygon.
- * @interface
- * @extends {Shape}
- */
- function Polygon() {};
- Polygon.prototype.getSides = function() {};
-
-
-
- Used to indicate that the function defines an interface.
-
-
-
-
- @lends
-
- @lends objectName
- @lends {objectName}
- For example:
-
- goog.object.extend(
- Button.prototype,
- /** @lends {Button.prototype} */ {
- isButton: function() { return true; }
- });
-
-
-
- Indicates that the keys of an object literal should
- be treated as properties of some other object. This annotation
- should only appear on object literals.
-
- Notice that the name in braces is not a type name like
- in other annotations. It's an object name. It names
- the object on which the properties are "lent".
- For example, @type {Foo}
means "an instance of Foo",
- but @lends {Foo}
means "the constructor Foo".
-
- The
- JSDoc Toolkit docs have more information on this
- annotation.
-
-
-
-
- @license or
- @preserve
-
- @license Description
- For example:
-
- /**
- * @preserve Copyright 2009 SomeThirdParty.
- * Here is the full license text and copyright
- * notice for this file. Note that the notice can span several
- * lines and is only terminated by the closing star and slash:
- */
-
-
-
- Anything marked by @license
or
- @preserve
will be retained by the compiler and
- output at the top of the compiled code for that file. This
- annotation allows important notices (such as legal licenses or
- copyright text) to survive compilation unchanged. Line breaks
- are preserved.
-
-
-
-
-
-
-
-
- @noalias
-
- @noalias
- For example:
-
- /** @noalias */
- function Range() {}
-
-
-
- Used in an externs file to indicate to the compiler that the
- variable or function should not be aliased as part of the
- alias externals pass of the compiler.
-
-
-
-
- @nocompile
-
- @nocompile
- For example:
-
- /** @nocompile */
-
- // JavaScript code
-
-
-
- Used at the top of a file to tell the compiler to parse this
- file but not compile it.
- Code that is not meant for compilation and should be omitted
- from compilation tests (such as bootstrap code) uses this
- annotation.
- Use sparingly.
-
-
-
-
- @nosideeffects
-
- @nosideeffects
- For example:
-
- /** @nosideeffects */
- function noSideEffectsFn1() {
- // ...
- }
-
- /** @nosideeffects */
- var noSideEffectsFn2 = function() {
- // ...
- };
-
- /** @nosideeffects */
- a.prototype.noSideEffectsFn3 = function() {
- // ...
- };
-
-
-
- This annotation can be used as part of function and
- constructor declarations to indicate that calls to the
- declared function have no side-effects. This annotation
- allows the compiler to remove calls to these functions if the
- return value is not used.
-
-
-
-
- @override
-
- @override
- For example:
-
- /**
- * @return {string} Human-readable representation of project.SubClass.
- * @override
- */
- project.SubClass.prototype.toString = function() {
- // ...
- };
-
-
-
- Indicates that a method or property of a subclass
- intentionally hides a method or property of the superclass. If
- no other documentation is included, the method or property
- also inherits documentation from its superclass.
-
-
-
-
- @param
-
- @param {Type} varname Description
- For example:
-
- /**
- * Queries a Baz for items.
- * @param {number} groupNum Subgroup id to query.
- * @param {string|number|null} term An itemName,
- * or itemId, or null to search everything.
- */
- goog.Baz.prototype.query = function(groupNum, term) {
- // ...
- };
-
-
-
- Used with method, function and constructor calls to document
- the arguments of a function.
-
- Type
- names must be enclosed in curly braces. If the type
- is omitted, the compiler will not type-check the parameter.
-
-
-
-
- @private
-
- @private
- @private {type}
- For example:
-
- /**
- * Handlers that are listening to this logger.
- * @private {!Array.<Function>}
- */
- this.handlers_ = [];
-
-
-
- Used in conjunction with a trailing underscore on the method
- or property name to indicate that the member is
- private and final.
-
-
-
-
- @protected
-
- @protected
- @protected {type}
- For example:
-
- /**
- * Sets the component's root element to the given element.
- * @param {Element} element Root element for the component.
- * @protected
- */
- goog.ui.Component.prototype.setElementInternal = function(element) {
- // ...
- };
-
-
-
- Used to indicate that the member or property is
- protected.
- Should be used in conjunction with names with no trailing
- underscore.
-
-
-
-
- @public
-
- @public
- @public {type}
- For example:
-
- /**
- * Whether to cancel the event in internal capture/bubble processing.
- * @public {boolean}
- * @suppress {visiblity} Referencing this outside this package is strongly
- * discouraged.
- */
- goog.events.Event.prototype.propagationStopped_ = false;
-
-
-
- Used to indicate that the member or property is public. Variables and
- properties are public by default, so this annotation is rarely necessary.
- Should only be used in legacy code that cannot be easily changed to
- override the visibility of members that were named as private variables.
-
-
-
-
- @return
-
- @return {Type} Description
- For example:
-
- /**
- * @return {string} The hex ID of the last item.
- */
- goog.Baz.prototype.getLastId = function() {
- // ...
- return id;
- };
-
-
-
- Used with method and function calls to document the return
- type. When writing descriptions for boolean parameters,
- prefer "Whether the component is visible" to "True if the
- component is visible, false otherwise". If there is no return
- value, do not use an @return
tag.
-
- Type
- names must be enclosed in curly braces. If the type
- is omitted, the compiler will not type-check the return value.
-
-
-
-
- @see
-
- @see Link
- For example:
-
- /**
- * Adds a single item, recklessly.
- * @see #addSafely
- * @see goog.Collect
- * @see goog.RecklessAdder#add
- ...
-
-
- Reference a lookup to another class function or method.
-
-
-
- @struct
-
- @struct Description
- For example:
-
- /**
- * @constructor
- * @struct
- */
- function Foo(x) {
- this.x = x;
- }
- var obj = new Foo(123);
- var num = obj['x']; // warning
- obj.y = "asdf"; // warning
-
- Foo.prototype = /** @struct */ {
- method1: function() {}
- };
- Foo.prototype.method2 = function() {}; // warning
-
-
-
- When a constructor (Foo
in the example) is
- annotated with @struct
, you can only use the dot
- notation to access the properties of Foo
objects.
- Also, you cannot add new properties to Foo
- objects after they have been created.
- The annotation can also be used directly on object literals.
-
-
-
-
- @supported
-
- @supported Description
- For example:
-
- /**
- * @fileoverview Event Manager
- * Provides an abstracted interface to the
- * browsers' event systems.
- * @supported So far tested in IE6 and FF1.5
- */
-
-
-
- Used in a fileoverview to indicate what browsers are supported
- by the file.
-
-
-
-
- @suppress
-
-
- @suppress {warning1|warning2}
-
-
- @suppress {warning1,warning2}
-
- For example:
-
- /**
- * @suppress {deprecated}
- */
- function f() {
- deprecatedVersionOfF();
- }
-
-
-
- Suppresses warnings from tools. Warning categories are
- separated by |
or ,
.
-
-
-
-
-
- @template
-
- @template
- For example:
-
- /**
- * @param {function(this:T, ...)} fn
- * @param {T} thisObj
- * @param {...*} var_args
- * @template T
- */
- goog.bind = function(fn, thisObj, var_args) {
- ...
- };
-
-
-
- This annotation can be used to declare a
- template typename.
-
-
-
-
- @this
-
-
- @this Type
- @this {Type}
-
- For example:
-
- pinto.chat.RosterWidget.extern('getRosterElement',
- /**
- * Returns the roster widget element.
- * @this pinto.chat.RosterWidget
- * @return {Element}
- */
- function() {
- return this.getWrappedComponent_().getElement();
- });
-
-
-
- The type of the object in whose context a particular method is
- called. Required when the this
keyword is referenced
- from a function that is not a prototype method.
-
-
-
-
- @type
-
-
- @type Type
- @type {Type}
-
- For example:
-
- /**
- * The message hex ID.
- * @type {string}
- */
- var hexId = hexId;
-
-
-
- Identifies the type of a variable,
- property, or expression. Curly braces are not required around
- most types, but some projects mandate them for all types, for
- consistency.
-
-
-
-
- @typedef
-
- @typedef
- For example:
-
- /** @typedef {(string|number)} */
- goog.NumberLike;
-
- /** @param {goog.NumberLike} x A number or a string. */
- goog.readNumber = function(x) {
- ...
- }
-
-
-
- This annotation can be used to declare an alias of a more
- complex type.
-
-
-
-
-
-
-
-
-
-
-
- You may also see other types of JSDoc annotations in third-party
- code. These annotations appear in the
-
- JSDoc Toolkit Tag Reference
-
- but are currently discouraged in Google code. You should consider
- them "reserved" names for future use. These include:
-
- - @augments
- - @argument
- - @borrows
- - @class
- - @constant
- - @constructs
- - @default
- - @event
- - @example
- - @field
- - @function
- - @ignore
- - @inner
- - @link
- - @memberOf
- - @name
- - @namespace
- - @property
- - @public
- - @requires
- - @returns
- - @since
- - @static
- - @version
-
-
-
-
-
-
-
-
- Only provide top-level symbols.
-
-
-
- All members defined on a class should be in the same file. So, only
- top-level classes should be provided in a file that contains multiple
- members defined on the same class (e.g. enums, inner classes, etc).
-
- Do this:
-
- goog.provide('namespace.MyClass');
-
- Not this:
-
- goog.provide('namespace.MyClass');
- goog.provide('namespace.MyClass.Enum');
- goog.provide('namespace.MyClass.InnerClass');
- goog.provide('namespace.MyClass.TypeDef');
- goog.provide('namespace.MyClass.CONSTANT');
- goog.provide('namespace.MyClass.staticMethod');
-
-
- Members on namespaces may also be provided:
-
-
- goog.provide('foo.bar');
- goog.provide('foo.bar.method');
- goog.provide('foo.bar.CONSTANT');
-
-
-
-
-
- Required
-
-
-
- Use of JS compilers such as the
- Closure Compiler
- is required for all customer-facing code.
-
-
-
-
-
-
-
-
- JavaScript tidbits
-
-
- The following are all false in boolean expressions:
-
- null
- undefined
- ''
the empty string
- 0
the number
-
- But be careful, because these are all true:
-
- '0'
the string
- []
the empty array
- {}
the empty object
-
-
- This means that instead of this:
-
- while (x != null) {
-
- you can write this shorter code (as long as you don't expect x to
- be 0, or the empty string, or false):
-
- while (x) {
-
-
- And if you want to check a string to see if it is null or empty,
- you could do this:
-
- if (y != null && y != '') {
-
- But this is shorter and nicer:
-
- if (y) {
-
-
- Caution: There are many unintuitive things about
- boolean expressions. Here are some of them:
-
-
- Boolean('0') == true
- '0' != true
-
- 0 != null
- 0 == []
- 0 == false
-
- Boolean(null) == false
- null != true
- null != false
-
- Boolean(undefined) == false
- undefined != true
- undefined != false
-
- Boolean([]) == true
- [] != true
- [] == false
-
- Boolean({}) == true
- {} != true
- {} != false
-
-
-
-
- Instead of this:
-
- if (val) {
- return foo();
- } else {
- return bar();
- }
-
- you can write this:
-
- return val ? foo() : bar();
-
-
- The ternary conditional is also useful when generating HTML:
-
- var html = '<input type="checkbox"' +
- (isChecked ? ' checked' : '') +
- (isEnabled ? '' : ' disabled') +
- ' name="foo">';
-
-
-
-
- These binary boolean operators are short-circuited, and evaluate
- to the last evaluated term.
-
- "||" has been called the 'default' operator, because instead of
- writing this:
-
- /** @param {*=} opt_win */
- function foo(opt_win) {
- var win;
- if (opt_win) {
- win = opt_win;
- } else {
- win = window;
- }
- // ...
- }
-
- you can write this:
-
- /** @param {*=} opt_win */
- function foo(opt_win) {
- var win = opt_win || window;
- // ...
- }
-
-
- "&&" is also useful for shortening code. For instance,
- instead of this:
-
- if (node) {
- if (node.kids) {
- if (node.kids[index]) {
- foo(node.kids[index]);
- }
- }
- }
-
-
- you could do this:
-
- if (node && node.kids && node.kids[index]) {
- foo(node.kids[index]);
- }
-
-
- or this:
-
- var kid = node && node.kids && node.kids[index];
- if (kid) {
- foo(kid);
- }
-
-
- However, this is going a little too far:
-
- node && node.kids && node.kids[index] && foo(node.kids[index]);
-
-
-
-
- Node lists are often implemented as node iterators with a filter.
- This means that getting a property like length is O(n), and
- iterating over the list by re-checking the length will be
- O(n^2).
-
- var paragraphs = document.getElementsByTagName('p');
- for (var i = 0; i < paragraphs.length; i++) {
- doSomething(paragraphs[i]);
- }
-
-
- It is better to do this instead:
-
- var paragraphs = document.getElementsByTagName('p');
- for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) {
- doSomething(paragraph);
- }
-
-
- This works well for all collections and arrays as long as the array
- does not contain things that are treated as boolean false.
-
- In cases where you are iterating over the childNodes you can also
- use the firstChild and nextSibling properties.
-
- var parentNode = document.getElementById('foo');
- for (var child = parentNode.firstChild; child; child = child.nextSibling) {
- doSomething(child);
- }
-
-
-
-
-
-
-
-
-
-
- BE CONSISTENT.
-
-
-
- If you're editing code, take a few minutes to look at the code
- around you and determine its style. If they use spaces around
- all their arithmetic operators, you should too. If their
- comments have little boxes of hash marks around them, make your
- comments have little boxes of hash marks around them too.
-
-
-
- The point of having style guidelines is to have a common vocabulary
- of coding so people can concentrate on what you're saying rather
- than on how you're saying it. We present global style rules here so
- people know the vocabulary, but local style is also important. If
- code you add to a file looks drastically different from the existing
- code around it, it throws readers out of their rhythm when they go to
- read it. Avoid this.
-
-
-
-
-
- Revision 2.93
-
-
-
-
- Aaron Whyte
- Bob Jervis
- Dan Pupius
- Erik Arvidsson
- Fritz Schneider
- Robby Walker
-
-
diff --git a/jsoncstyleguide.asciidoc b/jsoncstyleguide.asciidoc
new file mode 100644
index 0000000..8a72725
--- /dev/null
+++ b/jsoncstyleguide.asciidoc
@@ -0,0 +1,1478 @@
+= Google JSON Style Guide
+
+Revision 0.9
+
+
+
+
+
+Table of Contents
+
+[width="100%",cols="50%,50%",]
+|======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
+a|
+link:#general-guidelines[General Guidelines]
+
+ a|
+link:#comments[Comments] link:#double-quotes[Double Quotes] link:#flattened-data-vs-structured-hierarchy[Flattened data vs Structured Hierarchy]
+
+a|
+link:#property-name-guidelines[Property Name Guidelines]
+
+ a|
+link:#property-name-format[Property Name Format] link:#key-names-in-json-maps[Key Names in JSON Maps] link:#reserved-property-names[Reserved Property Names] link:#singular-vs-plural-property-names[Singular vs Plural Property Names] link:#naming-conflicts[Naming Conflicts]
+
+a|
+link:#property-value-guidelines[Property Value Guidelines]
+
+ a|
+link:#property-value-format[Property Value Format] link:#empty-null-property-values[Empty/Null Property Values] link:#enum-values[Enum Values]
+
+a|
+link:#property-value-data-types[Property Value Data Types]
+
+ a|
+link:#date-property-values[Date Property Values] link:#time-duration-property-values[Time Duration Property Values] link:#latitude-longitude-property-values[Latitude/Longitude Property Values]
+
+a|
+link:#json-structure-reserved-property-names[JSON Structure & Reserved Property Names]
+
+ a|
+a|
+link:#Top-Level_Reserved_Property_Names[Top-Level Reserved Property Names]
+
+ a|
+link:#apiversion[apiVersion] link:#context[context] link:#id[id] link:#method[method] link:#params[params] link:#data[data] link:#error[error]
+
+a|
+link:#reserved-property-names-in-the-data-object[Reserved Property Names in the data object]
+
+ a|
+link:#data-kind[data.kind] link:#data-fields[data.fields] link:#data-etag[data.etag] link:#data-id[data.id] link:#data-lang[data.lang] link:#data-updated[data.updated] link:#data-deleted[data.deleted] link:#data-items[data.items]
+
+a|
+link:#reserved-property-names-for-paging[Reserved Property Names for Paging]
+
+ a|
+link:#data-currentitemcount[data.currentItemCount] link:#data-itemsperpage[data.itemsPerPage] link:#data-startindex[data.startIndex] link:#data-totalitems[data.totalItems] link:#data-paginglinktemplate[data.pagingLinkTemplate] link:#data-pageindex[data.pageIndex] link:#data-totalpages[data.totalPages]
+
+a|
+link:#reserved-property-names-for-links[Reserved Property Names for Links]
+
+ a|
+link:#data-self-data-selflink[data.self / data.selfLink] link:#data-edit-data-editlink[data.edit / data.editLink] link:#data-next-data-nextlink[data.next / data.nextLink] link:#data-previous-data-previouslink[data.previous / data.previousLink]
+
+a|
+link:#reserved-property-names-in-the-error-object[Reserved Property Names in the error object]
+
+ a|
+link:#error-code[error.code] link:#error-message[error.message] link:#error-errors[error.errors] link:#error-errors-domain[error.errors[\].domain] link:#error-errors-reason[error.errors[\].reason] link:#error-errors-message[error.errors[\].message] link:#error-errors-location[error.errors[\].location] link:#error-errors-locationtype[error.errors[\].locationType] link:#error-errors-extendedhelp[error.errors[\].extendedHelp] link:#error-errors-sendreport[error.errors[\].sendReport]
+
+a|
+link:#property-ordering[Property Ordering]
+
+ a|
+link:#kind-property[Kind Property] link:#items-property[Items Property] link:#property-ordering-example[Property Ordering Example]
+
+a|
+link:#examples[Examples]
+
+ a|
+link:#youtube-json-api[YouTube JSON API] link:#paging-example[Paging Example]
+
+a|
+link:#appendix[Appendix]
+
+ a|
+#Appendix_A:_Reserved_JavaScript_Words[Appendix A: Reserved JavaScript Words]
+
+|======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
+
+[[Important_Note]]
+== Important Note
+
+=== Display Hidden Details in this Guide
+
+
+
+This style guide contains many details that are initially hidden from view. They are marked by the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear below.
+
+Hooray! Now you know you can expand points to get more details. Alternatively, there's an "expand all" at the top of this document.
+
+[[Introduction]]
+== Introduction
+
+This style guide documents guidelines and recommendations for building JSON APIs at Google. In general, JSON APIs should follow the spec found at http://www.json.org[JSON.org]. This style guide clarifies and standardizes specific cases so that JSON APIs from Google have a standard look and feel. These guidelines are applicable to JSON requests and responses in both RPC-based and REST-based APIs.
+
+[[Definitions]]
+== Definitions
+
+For the purposes of this style guide, we define the following terms:
+
+
+* property - a name/value pair inside a JSON object.
+
+* property name - the name (or key) portion of the property.
+
+* property value - the value portion of the property.
+
+--------------------------------------------------
+{
+ // The name/value pair together is a "property".
+ "propertyName": "propertyValue"
+}
+--------------------------------------------------
+
+Javascript's `number` type encompasses all floating-point numbers, which is a broad designation. In this guide, `number` will refer to JavaScript's `number` type, while `integer` will refer to integers.
+
+[[General_Guidelines]]
+== General Guidelines
+
+=== Comments
+
+
+
+No comments in JSON objects.
+
+Comments should not be included in JSON objects. Some of the examples in this style guide include comments. However this is only to clarify the examples.
+
+------------------------------------------------
+{
+ // You may see comments in the examples below,
+ // But don't include comments in your JSON.
+ "propertyName": "propertyValue"
+}
+------------------------------------------------
+
+=== Double Quotes
+
+
+
+Use double quotes.
+
+If a property requires quotes, double quotes must be used. All property names must be surrounded by double quotes. Property values of type string must be surrounded by double quotes. Other value types (like boolean or number) should not be surrounded by double quotes.
+
+=== Flattened data vs Structured Hierarchy
+
+
+
+Data should not be arbitrarily grouped for convenience.
+
+Data elements should be "flattened" in the JSON representation. Data should not be arbitrarily grouped for convenience.
+
+In some cases, such as a collection of properties that represents a single structure, it may make sense to keep the structured hierarchy. These cases should be carefully considered, and only used if it makes semantic sense. For example, an address could be represented two ways, but the structured way probably makes more sense for developers:
+
+Flattened Address:
+
+--------------------------------------
+{
+ "company": "Google",
+ "website": "http://www.google.com/",
+ "addressLine1": "111 8th Ave",
+ "addressLine2": "4th Floor",
+ "state": "NY",
+ "city": "New York",
+ "zip": "10011"
+}
+--------------------------------------
+
+Structured Address:
+
+--------------------------------------
+{
+ "company": "Google",
+ "website": "http://www.google.com/",
+ "address": {
+ "line1": "111 8th Ave",
+ "line2": "4th Floor",
+ "state": "NY",
+ "city": "New York",
+ "zip": "10011"
+ }
+}
+--------------------------------------
+
+[[Property_Name_Guidelines]]
+== Property Name Guidelines
+
+=== Property Name Format
+
+
+
+Choose meaningful property names.
+
+Property names must conform to the following guidelines:
+
+
+* Property names should be meaningful names with defined semantics.
+
+* Property names must be camel-cased, ascii strings.
+
+* The first character must be a letter, an underscore (_) or a dollar sign ($).
+
+* Subsequent characters can be a letter, a digit, an underscore, or a dollar sign.
+
+* Reserved JavaScript keywords should be avoided (A list of reserved JavaScript keywords can be found below).
+
+These guidelines mirror the guidelines for naming JavaScript identifiers. This allows JavaScript clients to access properties using dot notation. (for example, `result.thisIsAnInstanceVariable`). Here's an example of an object with one property:
+
+--------------------------------------------------
+{
+ "thisPropertyIsAnIdentifier": "identifier value"
+}
+--------------------------------------------------
+
+=== Key Names in JSON Maps
+
+
+
+JSON maps can use any Unicode character in key names.
+
+The property name naming rules do not apply when a JSON object is used as a map. A map (also referred to as an associative array) is a data type with arbitrary key/value pairs that use the keys to access the corresponding values. JSON objects and JSON maps look the same at runtime; this distinction is relevant to the design of the API. The API documentation should indicate when JSON objects are used as maps.
+
+The keys of a map do not have to obey the naming guidelines for property names. Map keys may contain any Unicode characters. Clients can access these properties using the square bracket notation familiar for maps (for example, `result.thumbnails["72"]`).
+
+----------------------------------------------------
+{
+ // The "address" property is a sub-object
+ // holding the parts of an address.
+ "address": {
+ "addressLine1": "123 Anystreet",
+ "city": "Anytown",
+ "state": "XX",
+ "zip": "00000"
+ },
+ // The "thumbnails" property is a map that maps
+ // a pixel size to the thumbnail url of that size.
+ "thumbnails": {
+ "72": "http://url.to.72px.thumbnail",
+ "144": "http://url.to.144px.thumbnail"
+ }
+}
+----------------------------------------------------
+
+=== Reserved Property Names
+
+
+
+Certain property names are reserved for consistent use across services.
+
+Details about reserved property names, along with the full list, can be found later on in this guide. Services should avoid using these property names for anything other than their defined semantics.
+
+=== Singular vs Plural Property Names
+
+
+
+Array types should have plural property names. All other property names should be singular.
+
+Arrays usually contain multiple items, and a plural property name reflects this. An example of this can be seen in the reserved names below. The `items` property name is plural because it represents an array of item objects. Most of the other fields are singular.
+
+There may be exceptions to this, especially when referring to numeric property values. For example, in the reserved names, `totalItems` makes more sense than `totalItem`. However, technically, this is not violating the style guide, since `totalItems` can be viewed as `totalOfItems`, where `total` is singular (as per the style guide), and `OfItems` serves to qualify the total. The field name could also be changed to `itemCount` to look singular.
+
+------------------------------------
+{
+ // Singular
+ "author": "lisa",
+ // An array of siblings, plural
+ "siblings": [ "bart", "maggie"],
+ // "totalItem" doesn't sound right
+ "totalItems": 10,
+ // But maybe "itemCount" is better
+ "itemCount": 10,
+}
+------------------------------------
+
+=== Naming Conflicts
+
+
+
+Avoid naming conflicts by choosing a new property name or versioning the API.
+
+New properties may be added to the reserved list in the future. There is no concept of JSON namespacing. If there is a naming conflict, these can usually be resolved by choosing a new property name or by versioning. For example, suppose we start with the following JSON object:
+
+----------------------------------------------------
+{
+ "apiVersion": "1.0",
+ "data": {
+ "recipeName": "pizza",
+ "ingredients": ["tomatoes", "cheese", "sausage"]
+ }
+}
+----------------------------------------------------
+
+If in the future we wish to make `ingredients` a reserved word, we can do one of two things:
+
+\1) Choose a different name:
+
+----------------------------------------------------
+{
+ "apiVersion": "1.0",
+ "data": {
+ "recipeName": "pizza",
+ "ingredientsData": "Some new property",
+ "ingredients": ["tomatoes", "cheese", "sausage"]
+ }
+}
+----------------------------------------------------
+
+\2) Rename the property on a major version boundary:
+
+---------------------------------------------------------
+{
+ "apiVersion": "2.0",
+ "data": {
+ "recipeName": "pizza",
+ "ingredients": "Some new property",
+ "recipeIngredients": ["tomatos", "cheese", "sausage"]
+ }
+}
+---------------------------------------------------------
+
+[[Property_Value_Guidelines]]
+== Property Value Guidelines
+
+=== Property Value Format
+
+
+
+Property values must be Unicode booleans, numbers, strings, objects, arrays, or `null`.
+
+The spec at http://www.json.org[JSON.org] specifies exactly what type of data is allowed in a property value. This includes Unicode booleans, numbers, strings, objects, arrays, and `null`. JavaScript expressions are not allowed. APIs should support that spec for all values, and should choose the data type most appropriate for a particular property (numbers to represent numbers, etc.).
+
+Good:
+
+------------------------------------
+{
+ "canPigsFly": null, // null
+ "areWeThereYet": false, // boolean
+ "answerToLife": 42, // number
+ "name": "Bart", // string
+ "moreData": {}, // object
+ "things": [] // array
+}
+------------------------------------
+
+Bad:
+
+------------------------------------------------------------------------
+{
+ "aVariableName": aVariableName, // Bad - JavaScript identifier
+ "functionFoo": function() { return 1; } // Bad - JavaScript function
+}
+------------------------------------------------------------------------
+
+=== Empty/Null Property Values
+
+
+
+Consider removing empty or `null` values.
+
+If a property is optional or has an empty or `null` value, consider dropping the property from the JSON, unless there's a strong semantic reason for its existence.
+
+------------------------------------------------------------------------------
+{
+ "volume": 10,
+
+ // Even though the "balance" property's value is zero, it should be left in,
+ // since "0" signifies "even balance" (the value could be "-1" for left
+ // balance and "+1" for right balance.
+ "balance": 0,
+
+ // The "currentlyPlaying" property can be left out since it is null.
+ // "currentlyPlaying": null
+}
+------------------------------------------------------------------------------
+
+=== Enum Values
+
+
+
+Enum values should be represented as strings.
+
+As APIs grow, enum values may be added, removed or changed. Using strings as enum values ensures that downstream clients can gracefully handle changes to enum values.
+
+Java code:
+
+-------------------
+public enum Color {
+ WHITE,
+ BLACK,
+ RED,
+ YELLOW,
+ BLUE
+}
+-------------------
+
+JSON object:
+
+------------------
+{
+ "color": "WHITE"
+}
+------------------
+
+[[Property_Value_Data_Types]]
+== Property Value Data Types
+
+As mentioned above, property value types must be booleans, numbers, strings, objects, arrays, or `null`. However, it is useful define a set of standard data types when dealing with certain values. These data types will always be strings, but they will be formatted in a specific manner so that they can be easily parsed.
+
+=== Date Property Values
+
+
+
+Dates should be formatted as recommended by RFC 3339.
+
+Dates should be strings formatted as recommended by http://www.ietf.org/rfc/rfc3339.txt[RFC 3339]
+
+------------------------------------------
+{
+ "lastUpdate": "2007-11-06T16:34:41.000Z"
+}
+------------------------------------------
+
+=== Time Duration Property Values
+
+
+
+Time durations should be formatted as recommended by ISO 8601.
+
+Time duration values should be strings formatted as recommended by http://en.wikipedia.org/wiki/ISO_8601#Durations[ISO 8601].
+
+------------------------------------------------------
+{
+ // three years, six months, four days, twelve hours,
+ // thirty minutes, and five seconds
+ "duration": "P3Y6M4DT12H30M5S"
+}
+------------------------------------------------------
+
+=== Latitude/Longitude Property Values
+
+
+
+Latitudes/Longitudes should be formatted as recommended by ISO 6709.
+
+Latitude/Longitude should be strings formatted as recommended by http://en.wikipedia.org/wiki/ISO_6709[ISO 6709]. Furthermore, they should favor the ±DD.DDDD±DDD.DDDD degrees format.
+
+--------------------------------------------------------------
+{
+ // The latitude/longitude location of the statue of liberty.
+ "statueOfLiberty": "+40.6894-074.0447"
+}
+--------------------------------------------------------------
+
+[[JSON_Structure_Reserved_Property_Names]]
+== JSON Structure & Reserved Property Names
+
+In order to maintain a consistent interface across APIs, JSON objects should follow the structure outlined below. This structure applies to both requests and responses made with JSON. Within this structure, there are certain property names that are reserved for specific uses. These properties are NOT required; in other words, each reserved property may appear zero or one times. But if a service needs these properties, this naming convention is recommend. Here is a schema of the JSON structure, represented in http://www.google.com/url?sa=D&q=http%3A%2F%2Forderly-json.org%2F[Orderly] format (which in turn can be compiled into a http://www.google.com/url?sa=D&q=http%3A%2F%2Fjson-schema.org%2F[JSONSchema]). You can few examples of the JSON structure at the end of this guide.
+
+----------------------------------------------
+object {
+ string apiVersion?;
+ string context?;
+ string id?;
+ string method?;
+ object {
+ string id?
+ }* params?;
+ object {
+ string kind?;
+ string fields?;
+ string etag?;
+ string id?;
+ string lang?;
+ string updated?; # date formatted RFC 3339
+ boolean deleted?;
+ integer currentItemCount?;
+ integer itemsPerPage?;
+ integer startIndex?;
+ integer totalItems?;
+ integer pageIndex?;
+ integer totalPages?;
+ string pageLinkTemplate /^https?:/ ?;
+ object {}* next?;
+ string nextLink?;
+ object {}* previous?;
+ string previousLink?;
+ object {}* self?;
+ string selfLink?;
+ object {}* edit?;
+ string editLink?;
+ array [
+ object {}*;
+ ] items?;
+ }* data?;
+ object {
+ integer code?;
+ string message?;
+ array [
+ object {
+ string domain?;
+ string reason?;
+ string message?;
+ string location?;
+ string locationType?;
+ string extendedHelp?;
+ string sendReport?;
+ }*;
+ ] errors?;
+ }* error?;
+}*;
+----------------------------------------------
+
+The JSON object has a few top-level properties, followed by either a `data` object or an `error` object, but not both. An explanation of each of these properties can be found below.
+
+[[Top-Level_Reserved_Property_Names]]
+== Top-Level Reserved Property Names
+
+The top-level of the JSON object may contain the following properties.
+
+=== apiVersion
+
+
+
+Property Value Type: string +
+Parent: -
+
+Represents the desired version of the service API in a request, and the version of the service API that's served in the response. `apiVersion` should always be present. This is not related to the version of the data. Versioning of data should be handled through some other mechanism such as etags.
+
+Example:
+
+-----------------------
+{ "apiVersion": "2.1" }
+-----------------------
+
+=== context
+
+
+
+Property Value Type: string +
+Parent: -
+
+Client sets this value and server echos data in the response. This is useful in JSON-P and batch situations , where the user can use the `context` to correlate responses with requests. This property is a top-level property because the `context` should present regardless of whether the response was successful or an error. `context` differs from `id` in that `context` is specified by the user while `id` is assigned by the service.
+
+Example:
+
+Request #1:
+
+----------------------------------------
+http://www.google.com/myapi?context=bart
+----------------------------------------
+
+Request #2:
+
+----------------------------------------
+http://www.google.com/myapi?context=lisa
+----------------------------------------
+
+Response #1:
+
+--------------------
+{
+ "context": "bart",
+ "data": {
+ "items": []
+ }
+}
+--------------------
+
+Response #2:
+
+--------------------
+{
+ "context": "lisa",
+ "data": {
+ "items": []
+ }
+}
+--------------------
+
+Common JavaScript handler code to process both responses:
+
+-------------------------------------------------
+function handleResponse(response) {
+ if (response.result.context == "bart") {
+ // Update the "Bart" section of the page.
+ } else if (response.result.context == "lisa") {
+ // Update the "Lisa" section of the page.
+ }
+}
+-------------------------------------------------
+
+=== id
+
+
+
+Property Value Type: string +
+Parent: -
+
+A server supplied identifier for the response (regardless of whether the response is a success or an error). This is useful for correlating server logs with individual responses received at a client.
+
+Example:
+
+-------------
+{ "id": "1" }
+-------------
+
+=== method
+
+
+
+Property Value Type: string +
+Parent: -
+
+Represents the operation to perform, or that was performed, on the data. In the case of a JSON request, the `method` property can be used to indicate which operation to perform on the data. In the case of a JSON response, the `method` property can indicate the operation performed on the data.
+
+One example of this is in JSON-RPC requests, where `method` indicates the operation to perform on the `params` property:
+
+-------------------------
+{
+ "method": "people.get",
+ "params": {
+ "userId": "@me",
+ "groupId": "@self"
+ }
+}
+-------------------------
+
+=== params
+
+
+
+Property Value Type: object +
+Parent: -
+
+This object serves as a map of input parameters to send to an RPC request. It can be used in conjunction with the `method` property to execute an RPC function. If an RPC function does not need parameters, this property can be omitted.
+
+Example:
+
+-------------------------
+{
+ "method": "people.get",
+ "params": {
+ "userId": "@me",
+ "groupId": "@self"
+ }
+}
+-------------------------
+
+=== data
+
+
+
+Property Value Type: object +
+Parent: -
+
+Container for all the data from a response. This property itself has many reserved property names, which are described below. Services are free to add their own data to this object. A JSON response should contain either a `data` object or an `error` object, but not both. If both `data` and `error` are present, the `error` object takes precedence.
+
+=== error
+
+
+
+Property Value Type: object +
+Parent: -
+
+Indicates that an error has occurred, with details about the error. The error format supports either one or more errors returned from the service. A JSON response should contain either a `data` object or an `error` object, but not both. If both `data` and `error` are present, the `error` object takes precedence.
+
+Example:
+
+--------------------------------------------
+{
+ "apiVersion": "2.0",
+ "error": {
+ "code": 404,
+ "message": "File Not Found",
+ "errors": [{
+ "domain": "Calendar",
+ "reason": "ResourceNotFoundException",
+ "message": "File Not Found
+ }]
+ }
+}
+--------------------------------------------
+
+[[Reserved_Property_Names_in_the_data_object]]
+== Reserved Property Names in the data object
+
+The `data` property of the JSON object may contain the following properties.
+
+=== data.kind
+
+
+
+Property Value Type: string +
+Parent: `data`
+
+The `kind` property serves as a guide to what type of information this particular object stores. It can be present at the `data` level, or at the `items` level, or in any object where its helpful to distinguish between various types of objects. If the `kind` object is present, it should be the first property in the object (See the "Property Ordering" section below for more details).
+
+Example:
+
+-------------------------------------------------
+// "Kind" indicates an "album" in the Picasa API.
+{"data": {"kind": "album"}}
+-------------------------------------------------
+
+=== data.fields
+
+
+
+Property Value Type: string +
+Parent: `data`
+
+Represents the fields present in the response when doing a partial GET, or the fields present in a request when doing a partial PATCH. This property should only exist during a partial GET/PATCH, and should not be empty.
+
+Example:
+
+--------------------------
+{
+ "data": {
+ "kind": "user",
+ "fields": "author,id",
+ "id": "bart",
+ "author": "Bart"
+ }
+}
+--------------------------
+
+=== data.etag
+
+
+
+Property Value Type: string +
+Parent: `data`
+
+Represents the etag for the response. Details about ETags in the GData APIs can be found here: http://code.google.com/apis/gdata/docs/2.0/reference.html#ResourceVersioning
+
+Example:
+
+--------------------------------------------------
+{"data": {"etag": "W/"C0QBRXcycSp7ImA9WxRVFUk.""}}
+--------------------------------------------------
+
+=== data.id
+
+
+
+Property Value Type: string +
+Parent: `data`
+
+A globally unique string used to reference the object. The specific details of the `id` property are left up to the service.
+
+Example:
+
+-------------------------
+{"data": {"id": "12345"}}
+-------------------------
+
+=== data.lang
+
+
+
+Property Value Type: string (formatted as specified in BCP 47) +
+Parent: `data (or any child element)`
+
+Indicates the language of the rest of the properties in this object. This property mimics HTML's `lang` property and XML's `xml:lang` properties. The value should be a language value as defined in http://www.rfc-editor.org/rfc/bcp/bcp47.txt[BCP 47]. If a single JSON object contains data in multiple languages, the service is responsible for developing and documenting an appropriate location for the `lang` property.
+
+Example:
+
+---------------------------------
+{"data": {
+ "items": [
+ { "lang": "en",
+ "title": "Hello world!" },
+ { "lang": "fr",
+ "title": "Bonjour monde!" }
+ ]}
+}
+---------------------------------
+
+=== data.updated
+
+
+
+Property Value Type: string (formatted as specified in RFC 3339) +
+Parent: `data`
+
+Indicates the last date/time (http://www.ietf.org/rfc/rfc3339.txt[RFC 3339]) the item was updated, as defined by the service.
+
+Example:
+
+-------------------------------------------------
+{"data": {"updated": "2007-11-06T16:34:41.000Z"}}
+-------------------------------------------------
+
+=== data.deleted
+
+
+
+Property Value Type: boolean +
+Parent: `data (or any child element)`
+
+A marker element, that, when present, indicates the containing entry is deleted. If deleted is present, its value must be `true`; a value of `false` can cause confusion and should be avoided.
+
+Example:
+
+---------------------------------
+{"data": {
+ "items": [
+ { "title": "A deleted entry",
+ "deleted": true
+ }
+ ]}
+}
+---------------------------------
+
+=== data.items
+
+
+
+Property Value Type: array +
+Parent: `data`
+
+The property name `items` is reserved to represent an array of items (for example, photos in Picasa, videos in YouTube). This construct is intended to provide a standard location for collections related to the current result. For example, the JSON output could be plugged into a generic pagination system that knows to page on the `items` array. If `items` exists, it should be the last property in the `data` object (See the "Property Ordering" section below for more details).
+
+Example:
+
+--------------------------
+{
+ "data": {
+ "items": [
+ { /* Object #1 */ },
+ { /* Object #2 */ },
+ ...
+ ]
+ }
+}
+--------------------------
+
+[[Reserved_Property_Names_for_Paging]]
+== Reserved Property Names for Paging
+
+The following properties are located in the `data` object, and help page through a list of items. Some of the language and concepts are borrowed from the http://www.opensearch.org/Home[OpenSearch specification].
+
+The paging properties below allow for various styles of paging, including:
+
+
+* Previous/Next paging - Allows user's to move forward and backward through a list, one page at a time. The `nextLink` and `previousLink` properties (described in the "Reserved Property Names for Links" section below) are used for this style of paging.
+
+* Index-based paging - Allows user's to jump directly to a specific item position within a list of items. For example, to load 10 items starting at item 200, the developer may point the user to a url with the query string `?startIndex=200`.
+
+* Page-based paging - Allows user's to jump directly to a specific page within the items. This is similar to index-based paging, but saves the developer the extra step of having to calculate the item index for a new page of items. For example, rather than jump to item number 200, the developer could jump to page 20. The urls during page-based paging could use the query string `?page=1` or `?page=20`. The `pageIndex` and `totalPages` properties are used for this style of paging.
+
+An example of how to use these properties to implement paging can be found at the end of this guide.
+
+=== data.currentItemCount
+
+
+
+Property Value Type: integer +
+Parent: `data`
+
+The number of items in this result set. Should be equivalent to items.length, and is provided as a convenience property. For example, suppose a developer requests a set of search items, and asks for 10 items per page. The total set of that search has 14 total items. The first page of items will have 10 items in it, so both `itemsPerPage` and `currentItemCount` will equal "10". The next page of items will have the remaining 4 items; `itemsPerPage` will still be "10", but `currentItemCount` will be "4".
+
+Example:
+
+-------------------------------------------------------------------
+{
+ "data": {
+ // "itemsPerPage" does not necessarily match "currentItemCount"
+ "itemsPerPage": 10,
+ "currentItemCount": 4
+ }
+}
+-------------------------------------------------------------------
+
+=== data.itemsPerPage
+
+
+
+Property Value Type: integer +
+Parent: `data`
+
+The number of items in the result. This is not necessarily the size of the data.items array; if we are viewing the last page of items, the size of data.items may be less than `itemsPerPage`. However the size of data.items should not exceed `itemsPerPage`.
+
+Example:
+
+----------------------
+{
+ "data": {
+ "itemsPerPage": 10
+ }
+}
+----------------------
+
+=== data.startIndex
+
+
+
+Property Value Type: integer +
+Parent: `data`
+
+The index of the first item in data.items. For consistency, `startIndex` should be 1-based. For example, the first item in the first set of items should have a `startIndex` of 1. If the user requests the next set of data, the `startIndex` may be 10.
+
+Example:
+
+-------------------
+{
+ "data": {
+ "startIndex": 1
+ }
+}
+-------------------
+
+=== data.totalItems
+
+
+
+Property Value Type: integer +
+Parent: `data`
+
+The total number of items available in this set. For example, if a user has 100 blog posts, the response may only contain 10 items, but the `totalItems` would be 100.
+
+Example:
+
+---------------------
+{
+ "data": {
+ "totalItems": 100
+ }
+}
+---------------------
+
+=== data.pagingLinkTemplate
+
+
+
+Property Value Type: string +
+Parent: `data`
+
+A URI template indicating how users can calculate subsequent paging links. The URI template also has some reserved variable names: `{index}` representing the item number to load, and `{pageIndex}`, representing the page number to load.
+
+Example:
+
+-------------------------------------------------------------------------------------------------------
+{
+ "data": {
+ "pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N"
+ }
+}
+-------------------------------------------------------------------------------------------------------
+
+=== data.pageIndex
+
+
+
+Property Value Type: integer +
+Parent: `data`
+
+The index of the current page of items. For consistency, `pageIndex` should be 1-based. For example, the first page of items has a `pageIndex` of 1. `pageIndex` can also be calculated from the item-based paging properties: `pageIndex = floor(startIndex / itemsPerPage) + 1`.
+
+Example:
+
+------------------
+{
+ "data": {
+ "pageIndex": 1
+ }
+}
+------------------
+
+=== data.totalPages
+
+
+
+Property Value Type: integer +
+Parent: `data`
+
+The total number of pages in the result set. `totalPages` can also be calculated from the item-based paging properties above: `totalPages = ceiling(totalItems / itemsPerPage)`.
+
+Example:
+
+--------------------
+{
+ "data": {
+ "totalPages": 50
+ }
+}
+--------------------
+
+[[Reserved_Property_Names_for_Links]]
+== Reserved Property Names for Links
+
+The following properties are located in the `data` object, and represent references to other resources. There are two forms of link properties: 1) objects, which can contain any sort of reference (such as a JSON-RPC object), and 2) URI strings, which represent URIs to resources (and will always be suffixed with "Link").
+
+=== data.self / data.selfLink
+
+
+
+Property Value Type: object / string +
+Parent: `data`
+
+The self link can be used to retrieve the item's data. For example, in a list of a user's Picasa album, each album object in the `items` array could contain a `selfLink` that can be used to retrieve data related to that particular album.
+
+Example:
+
+--------------------------------------------------------
+{
+ "data": {
+ "self": { },
+ "selfLink": "http://www.google.com/feeds/album/1234"
+ }
+}
+--------------------------------------------------------
+
+=== data.edit / data.editLink
+
+
+
+Property Value Type: object / string +
+Parent: `data`
+
+The edit link indicates where a user can send update or delete requests. This is useful for REST-based APIs. This link need only be present if the user can update/delete this item.
+
+Example:
+
+-------------------------------------------------------------
+{
+ "data": {
+ "edit": { },
+ "editLink": "http://www.google.com/feeds/album/1234/edit"
+ }
+}
+-------------------------------------------------------------
+
+=== data.next / data.nextLink
+
+
+
+Property Value Type: object / string +
+Parent: `data`
+
+The next link indicates how more data can be retrieved. It points to the location to load the next set of data. It can be used in conjunction with the `itemsPerPage`, `startIndex` and `totalItems` properties in order to page through data.
+
+Example:
+
+-------------------------------------------------------------
+{
+ "data": {
+ "next": { },
+ "nextLink": "http://www.google.com/feeds/album/1234/next"
+ }
+}
+-------------------------------------------------------------
+
+=== data.previous / data.previousLink
+
+
+
+Property Value Type: object / string +
+Parent: `data`
+
+The previous link indicates how more data can be retrieved. It points to the location to load the previous set of data. It can be used in conjunction with the `itemsPerPage`, `startIndex` and `totalItems` properties in order to page through data.
+
+Example:
+
+-----------------------------------------------------------------
+{
+ "data": {
+ "previous": { },
+ "previousLink": "http://www.google.com/feeds/album/1234/next"
+ }
+}
+-----------------------------------------------------------------
+
+[[Reserved_Property_Names_in_the_error_object]]
+== Reserved Property Names in the error object
+
+The `error` property of the JSON object may contain the following properties.
+
+=== error.code
+
+
+
+Property Value Type: integer +
+Parent: `error`
+
+Represents the code for this error. This property value will usually represent the HTTP response code. If there are multiple errors, `code` will be the error code for the first error.
+
+Example:
+
+---------------
+{
+ "error":{
+ "code": 404
+ }
+}
+---------------
+
+=== error.message
+
+
+
+Property Value Type: string +
+Parent: `error`
+
+A human readable message providing more details about the error. If there are multiple errors, `message` will be the message for the first error.
+
+Example:
+
+-------------------------------
+{
+ "error":{
+ "message": "File Not Found"
+ }
+}
+-------------------------------
+
+=== error.errors
+
+
+
+Property Value Type: array +
+Parent: `error`
+
+Container for any additional information regarding the error. If the service returns multiple errors, each element in the `errors` array represents a different error.
+
+Example:
+
+-----------------------------
+{ "error": { "errors": [] } }
+-----------------------------
+
+=== error.errors[].domain
+
+
+
+Property Value Type: string +
+Parent: `error.errors`
+
+Unique identifier for the service raising this error. This helps distinguish service-specific errors (i.e. error inserting an event in a calendar) from general protocol errors (i.e. file not found).
+
+Example:
+
+--------------------------------------
+{
+ "error":{
+ "errors": [{"domain": "Calendar"}]
+ }
+}
+--------------------------------------
+
+=== error.errors[].reason
+
+
+
+Property Value Type: string +
+Parent: `error.errors`
+
+Unique identifier for this error. Different from the `error.code` property in that this is not an http response code.
+
+Example:
+
+-------------------------------------------------------
+{
+ "error":{
+ "errors": [{"reason": "ResourceNotFoundException"}]
+ }
+}
+-------------------------------------------------------
+
+=== error.errors[].message
+
+
+
+Property Value Type: string +
+Parent: `error.errors`
+
+A human readable message providing more details about the error. If there is only one error, this field will match `error.message`.
+
+Example:
+
+---------------------------------------------
+{
+ "error":{
+ "code": 404
+ "message": "File Not Found",
+ "errors": [{"message": "File Not Found"}]
+ }
+}
+---------------------------------------------
+
+=== error.errors[].location
+
+
+
+Property Value Type: string +
+Parent: `error.errors`
+
+The location of the error (the interpretation of its value depends on `locationType`).
+
+Example:
+
+--------------------------------
+{
+ "error":{
+ "errors": [{"location": ""}]
+ }
+}
+--------------------------------
+
+=== error.errors[].locationType
+
+
+
+Property Value Type: string +
+Parent: `error.errors`
+
+Indicates how the `location` property should be interpreted.
+
+Example:
+
+------------------------------------
+{
+ "error":{
+ "errors": [{"locationType": ""}]
+ }
+}
+------------------------------------
+
+=== error.errors[].extendedHelp
+
+
+
+Property Value Type: string +
+Parent: `error.errors`
+
+A URI for a help text that might shed some more light on the error.
+
+Example:
+
+-----------------------------------------------------------------------------
+{
+ "error":{
+ "errors": [{"extendedHelper": "http://url.to.more.details.example.com/"}]
+ }
+}
+-----------------------------------------------------------------------------
+
+=== error.errors[].sendReport
+
+
+
+Property Value Type: string +
+Parent: `error.errors`
+
+A URI for a report form used by the service to collect data about the error condition. This URI should be preloaded with parameters describing the request.
+
+Example:
+
+------------------------------------------------------------
+{
+ "error":{
+ "errors": [{"sendReport": "http://report.example.com/"}]
+ }
+}
+------------------------------------------------------------
+
+[[Property_Ordering]]
+== Property Ordering
+
+Properties can be in any order within the JSON object. However, in some cases the ordering of properties can help parsers quickly interpret data and lead to better performance. One example is a pull parser in a mobile environment, where performance and memory are critical, and unnecessary parsing should be avoided.
+
+=== Kind Property
+
+
+
+`kind` should be the first property
+
+Suppose a parser is responsible for parsing a raw JSON stream into a specific object. The `kind` property guides the parser to instantiate the appropriate object. Therefore it should be the first property in the JSON object. This only applies when objects have a `kind` property (usually found in the `data` and `items` properties).
+
+=== Items Property
+
+
+
+`items` should be the last property in the `data` object
+
+This allows all of the collection's properties to be read before reading each individual item. In cases where there are a lot of items, this avoids unnecessarily parsing those items when the developer only needs fields from the data.
+
+=== Property Ordering Example
+
+
+
+----------------------------------------------------------------------
+// The "kind" property distinguishes between an "album" and a "photo".
+// "Kind" is always the first property in its parent object.
+// The "items" property is the last property in the "data" object.
+{
+ "data": {
+ "kind": "album",
+ "title": "My Photo Album",
+ "description": "An album in the user's account",
+ "items": [
+ {
+ "kind": "photo",
+ "title": "My First Photo"
+ }
+ ]
+ }
+}
+----------------------------------------------------------------------
+
+[[Examples]]
+== Examples
+
+=== YouTube JSON API
+
+
+
+Here's an example of the YouTube JSON API's response object. You can learn more about YouTube's JSON API here: http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html.
+
+-----------------------------------------------------------------------------------------------------------------
+{
+ "apiVersion": "2.0",
+ "data": {
+ "updated": "2010-02-04T19:29:54.001Z",
+ "totalItems": 6741,
+ "startIndex": 1,
+ "itemsPerPage": 1,
+ "items": [
+ {
+ "id": "BGODurRfVv4",
+ "uploaded": "2009-11-17T20:10:06.000Z",
+ "updated": "2010-02-04T06:25:57.000Z",
+ "uploader": "docchat",
+ "category": "Animals",
+ "title": "From service dog to SURFice dog",
+ "description": "Surf dog Ricochets inspirational video ...",
+ "tags": [
+ "Surf dog",
+ "dog surfing",
+ "dog",
+ "golden retriever",
+ ],
+ "thumbnail": {
+ "default": "http://i.ytimg.com/vi/BGODurRfVv4/default.jpg",
+ "hqDefault": "http://i.ytimg.com/vi/BGODurRfVv4/hqdefault.jpg"
+ },
+ "player": {
+ "default": "http://www.youtube.com/watch?v=BGODurRfVv4&feature=youtube_gdata",
+ "mobile": "http://m.youtube.com/details?v=BGODurRfVv4"
+ },
+ "content": {
+ "1": "rtsp://v5.cache6.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
+ "5": "http://www.youtube.com/v/BGODurRfVv4?f=videos&app=youtube_gdata",
+ "6": "rtsp://v7.cache7.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp"
+ },
+ "duration": 315,
+ "rating": 4.96,
+ "ratingCount": 2043,
+ "viewCount": 1781691,
+ "favoriteCount": 3363,
+ "commentCount": 1007,
+ "commentsAllowed": true
+ }
+ ]
+ }
+}
+-----------------------------------------------------------------------------------------------------------------
+
+=== Paging Example
+
+
+
+This example demonstrates how the Google search items could be represented as a JSON object, with special attention to the paging variables.
+
+This sample is for illustrative purposes only. The API below does not actually exist.
+
+Here's a sample Google search results page: +
+image:jsoncstyleguide_example_01.png[image] +
+image:jsoncstyleguide_example_02.png[image]
+
+Here's a sample JSON representation of this page:
+
+--------------------------------------------------------------------------------------------------------
+{
+ "apiVersion": "2.1",
+ "id": "1",
+ "data": {
+ "query": "chicago style pizza",
+ "time": "0.1",
+ "currentItemCount": 10,
+ "itemsPerPage": 10,
+ "startIndex": 11,
+ "totalItems": 2700000,
+ "nextLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=20&sa=N"
+ "previousLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=0&sa=N",
+ "pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N",
+ "items": [
+ {
+ "title": "Pizz'a Chicago Home Page"
+ // More fields for the search results
+ }
+ // More search results
+ ]
+ }
+}
+--------------------------------------------------------------------------------------------------------
+
+Here's how each of the colored boxes from the screenshot would be represented (the background colors correspond to the colors in the images above):
+
+
+* Results 11 - 20 of about 2,700,000 = startIndex
+
+* Results 11 - 20 of about 2,700,000 = startIndex + currentItemCount - 1
+
+* Results 11 - 20 of about 2,700,000 = totalItems
+
+* Search results = items (formatted appropriately)
+
+* Previous/Next = previousLink / nextLink
+
+* Numbered links in "Gooooooooooogle" = Derived from "pageLinkTemplate". The developer is responsible for calculating the values for \{index} and substituting those values into the "pageLinkTemplate". The pageLinkTemplate's \{index} variable is calculated as follows:
+
+** Index #1 = 0 * itemsPerPage = 0
+
+** Index #2 = 2 * itemsPerPage = 10
+
+** Index #3 = 3 * itemsPerPage = 20
+
+** Index #N = N * itemsPerPage
+
+[[Appendix]]
+== Appendix
+
+=== Appendix A: Reserved JavaScript Words
+
+
+
+A list of reserved JavaScript words that should be avoided in property names.
+
+The words below are reserved by the JavaScript language and cannot be referred to using dot notation. The list represents best knowledge of keywords at this time; the list may change or vary based on your specific execution environment.
+
+From the http://www.google.com/url?sa=D&q=http%3A%2F%2Fwww.ecma-international.org%2Fpublications%2Fstandards%2FEcma-262.htm[ECMAScript Language Specification 5th Edition]
+
+------------------------------------------------
+abstract
+boolean break byte
+case catch char class const continue
+debugger default delete do double
+else enum export extends
+false final finally float for function
+goto
+if implements import in instanceof int interface
+let long
+native new null
+package private protected public
+return
+short static super switch synchronized
+this throw throws transient true try typeof
+var volatile void
+while with
+yield
+------------------------------------------------
+
+'''''
+
+Except as otherwise http://code.google.com/policies.html[noted], the content of this page is licensed under the http://creativecommons.org/licenses/by/3.0/[Creative Commons Attribution 3.0 License], and code samples are licensed under the http://www.apache.org/licenses/LICENSE-2.0[Apache 2.0 License].
+
+Revision 0.9
diff --git a/jsoncstyleguide.html b/jsoncstyleguide.html
deleted file mode 100644
index 1bef466..0000000
--- a/jsoncstyleguide.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
- Redirecting
-
-
-
- Redirecting you to jsoncstyleguide.xml.
-
-
diff --git a/jsoncstyleguide.xml b/jsoncstyleguide.xml
deleted file mode 100644
index 0835c26..0000000
--- a/jsoncstyleguide.xml
+++ /dev/null
@@ -1,1187 +0,0 @@
-
-
-
-
-
-Revision 0.9
-
-
-
-
-
-
-
-
-
-This style guide contains many details that are initially hidden from view. They are marked by the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear below.
-
-
-Hooray! Now you know you can expand points to get more details. Alternatively, there's an "expand all" at the top of this document.
-
-
-
-
-This style guide documents guidelines and recommendations for building JSON APIs at Google. In general, JSON APIs should follow the spec found at JSON.org. This style guide clarifies and standardizes specific cases so that JSON APIs from Google have a standard look and feel. These guidelines are applicable to JSON requests and responses in both RPC-based and REST-based APIs.
-
-
-For the purposes of this style guide, we define the following terms:
- property - a name/value pair inside a JSON object.
- property name - the name (or key) portion of the property.
- property value - the value portion of the property.
-
-{
- // The name/value pair together is a "property".
- "propertyName": "propertyValue"
-}
-
-
-Javascript's number
type encompasses all floating-point numbers, which is a broad designation. In this guide, number
will refer to JavaScript's number
type, while integer
will refer to integers.
-
-
-
-
-
-No comments in JSON objects.
-
-
-Comments should not be included in JSON objects. Some of the examples in this style guide include comments. However this is only to clarify the examples.
-
-{
- // You may see comments in the examples below,
- // But don't include comments in your JSON.
- "propertyName": "propertyValue"
-}
-
-
-
-
-
-
-Use double quotes.
-
-
-If a property requires quotes, double quotes must be used. All property names must be surrounded by double quotes. Property values of type string must be surrounded by double quotes. Other value types (like boolean or number) should not be surrounded by double quotes.
-
-
-
-
-Data should not be arbitrarily grouped for convenience.
-
-
-Data elements should be "flattened" in the JSON representation. Data should not be arbitrarily grouped for convenience.
In some cases, such as a collection of properties that represents a single structure, it may make sense to keep the structured hierarchy. These cases should be carefully considered, and only used if it makes semantic sense. For example, an address could be represented two ways, but the structured way probably makes more sense for developers:
-Flattened Address:
-
-{
- "company": "Google",
- "website": "http://www.google.com/",
- "addressLine1": "111 8th Ave",
- "addressLine2": "4th Floor",
- "state": "NY",
- "city": "New York",
- "zip": "10011"
-}
-
-Structured Address:
-
-{
- "company": "Google",
- "website": "http://www.google.com/",
- "address": {
- "line1": "111 8th Ave",
- "line2": "4th Floor",
- "state": "NY",
- "city": "New York",
- "zip": "10011"
- }
-}
-
-
-
-
-
-
-
-Choose meaningful property names.
-
-
-Property names must conform to the following guidelines:
- Property names should be meaningful names with defined semantics.
- Property names must be camel-cased, ascii strings.
- The first character must be a letter, an underscore (_) or a dollar sign ($).
- Subsequent characters can be a letter, a digit, an underscore, or a dollar sign.
- Reserved JavaScript keywords should be avoided (A list of reserved JavaScript keywords can be found below).
These guidelines mirror the guidelines for naming JavaScript identifiers. This allows JavaScript clients to access properties using dot notation. (for example, result.thisIsAnInstanceVariable
). Here's an example of an object with one property:
-
-{
- "thisPropertyIsAnIdentifier": "identifier value"
-}
-
-
-
-
-
-
-JSON maps can use any Unicode character in key names.
-
-
-The property name naming rules do not apply when a JSON object is used as a map. A map (also referred to as an associative array) is a data type with arbitrary key/value pairs that use the keys to access the corresponding values. JSON objects and JSON maps look the same at runtime; this distinction is relevant to the design of the API. The API documentation should indicate when JSON objects are used as maps.
The keys of a map do not have to obey the naming guidelines for property names. Map keys may contain any Unicode characters. Clients can access these properties using the square bracket notation familiar for maps (for example, result.thumbnails["72"]
).
-
-{
- // The "address" property is a sub-object
- // holding the parts of an address.
- "address": {
- "addressLine1": "123 Anystreet",
- "city": "Anytown",
- "state": "XX",
- "zip": "00000"
- },
- // The "thumbnails" property is a map that maps
- // a pixel size to the thumbnail url of that size.
- "thumbnails": {
- "72": "http://url.to.72px.thumbnail",
- "144": "http://url.to.144px.thumbnail"
- }
-}
-
-
-
-
-
-
-Certain property names are reserved for consistent use across services.
-
-
-Details about reserved property names, along with the full list, can be found later on in this guide. Services should avoid using these property names for anything other than their defined semantics.
-
-
-
-
-Array types should have plural property names. All other property names should be singular.
-
-
-Arrays usually contain multiple items, and a plural property name reflects this. An example of this can be seen in the reserved names below. The items
property name is plural because it represents an array of item objects. Most of the other fields are singular.
There may be exceptions to this, especially when referring to numeric property values. For example, in the reserved names, totalItems
makes more sense than totalItem
. However, technically, this is not violating the style guide, since totalItems
can be viewed as totalOfItems
, where total
is singular (as per the style guide), and OfItems
serves to qualify the total. The field name could also be changed to itemCount
to look singular.
-
-{
- // Singular
- "author": "lisa",
- // An array of siblings, plural
- "siblings": [ "bart", "maggie"],
- // "totalItem" doesn't sound right
- "totalItems": 10,
- // But maybe "itemCount" is better
- "itemCount": 10,
-}
-
-
-
-
-
-
-Avoid naming conflicts by choosing a new property name or versioning the API.
-
-
-New properties may be added to the reserved list in the future. There is no concept of JSON namespacing. If there is a naming conflict, these can usually be resolved by choosing a new property name or by versioning. For example, suppose we start with the following JSON object:
-
-{
- "apiVersion": "1.0",
- "data": {
- "recipeName": "pizza",
- "ingredients": ["tomatoes", "cheese", "sausage"]
- }
-}
-
-
-If in the future we wish to make ingredients
a reserved word, we can do one of two things:
1) Choose a different name:
-
-{
- "apiVersion": "1.0",
- "data": {
- "recipeName": "pizza",
- "ingredientsData": "Some new property",
- "ingredients": ["tomatoes", "cheese", "sausage"]
- }
-}
-
-
-2) Rename the property on a major version boundary:
-
-{
- "apiVersion": "2.0",
- "data": {
- "recipeName": "pizza",
- "ingredients": "Some new property",
- "recipeIngredients": ["tomatos", "cheese", "sausage"]
- }
-}
-
-
-
-
-
-
-
-
-Property values must be Unicode booleans, numbers, strings, objects, arrays, or null
.
-
-
-The spec at JSON.org specifies exactly what type of data is allowed in a property value. This includes Unicode booleans, numbers, strings, objects, arrays, and null
. JavaScript expressions are not allowed. APIs should support that spec for all values, and should choose the data type most appropriate for a particular property (numbers to represent numbers, etc.).
Good:
-
-{
- "canPigsFly": null, // null
- "areWeThereYet": false, // boolean
- "answerToLife": 42, // number
- "name": "Bart", // string
- "moreData": {}, // object
- "things": [] // array
-}
-
-
-Bad:
-
-{
- "aVariableName": aVariableName, // Bad - JavaScript identifier
- "functionFoo": function() { return 1; } // Bad - JavaScript function
-}
-
-
-
-
-
-
-Consider removing empty or null
values.
-
-
-If a property is optional or has an empty or null
value, consider dropping the property from the JSON, unless there's a strong semantic reason for its existence.
-
-{
- "volume": 10,
-
- // Even though the "balance" property's value is zero, it should be left in,
- // since "0" signifies "even balance" (the value could be "-1" for left
- // balance and "+1" for right balance.
- "balance": 0,
-
- // The "currentlyPlaying" property can be left out since it is null.
- // "currentlyPlaying": null
-}
-
-
-
-
-
-
-Enum values should be represented as strings.
-
-
-As APIs grow, enum values may be added, removed or changed. Using strings as enum values ensures that downstream clients can gracefully handle changes to enum values.
Java code:
-
-public enum Color {
- WHITE,
- BLACK,
- RED,
- YELLOW,
- BLUE
-}
-
-
-JSON object:
-
-{
- "color": "WHITE"
-}
-
-
-
-
-
-
-As mentioned above, property value types must be booleans, numbers, strings, objects, arrays, or null
. However, it is useful define a set of standard data types when dealing with certain values. These data types will always be strings, but they will be formatted in a specific manner so that they can be easily parsed.
-
-
-Dates should be formatted as recommended by RFC 3339.
-
-
-Dates should be strings formatted as recommended by RFC 3339
-
-{
- "lastUpdate": "2007-11-06T16:34:41.000Z"
-}
-
-
-
-
-
-
-Time durations should be formatted as recommended by ISO 8601.
-
-
-Time duration values should be strings formatted as recommended by ISO 8601.
-
-{
- // three years, six months, four days, twelve hours,
- // thirty minutes, and five seconds
- "duration": "P3Y6M4DT12H30M5S"
-}
-
-
-
-
-
-
-Latitudes/Longitudes should be formatted as recommended by ISO 6709.
-
-
-Latitude/Longitude should be strings formatted as recommended by ISO 6709. Furthermore, they should favor the ±DD.DDDD±DDD.DDDD degrees format.
-
-{
- // The latitude/longitude location of the statue of liberty.
- "statueOfLiberty": "+40.6894-074.0447"
-}
-
-
-
-
-
-
-In order to maintain a consistent interface across APIs, JSON objects should follow the structure outlined below. This structure applies to both requests and responses made with JSON. Within this structure, there are certain property names that are reserved for specific uses. These properties are NOT required; in other words, each reserved property may appear zero or one times. But if a service needs these properties, this naming convention is recommend. Here is a schema of the JSON structure, represented in Orderly format (which in turn can be compiled into a JSONSchema). You can few examples of the JSON structure at the end of this guide.
-
-object {
- string apiVersion?;
- string context?;
- string id?;
- string method?;
- object {
- string id?
- }* params?;
- object {
- string kind?;
- string fields?;
- string etag?;
- string id?;
- string lang?;
- string updated?; # date formatted RFC 3339
- boolean deleted?;
- integer currentItemCount?;
- integer itemsPerPage?;
- integer startIndex?;
- integer totalItems?;
- integer pageIndex?;
- integer totalPages?;
- string pageLinkTemplate /^https?:/ ?;
- object {}* next?;
- string nextLink?;
- object {}* previous?;
- string previousLink?;
- object {}* self?;
- string selfLink?;
- object {}* edit?;
- string editLink?;
- array [
- object {}*;
- ] items?;
- }* data?;
- object {
- integer code?;
- string message?;
- array [
- object {
- string domain?;
- string reason?;
- string message?;
- string location?;
- string locationType?;
- string extendedHelp?;
- string sendReport?;
- }*;
- ] errors?;
- }* error?;
-}*;
-
-
-The JSON object has a few top-level properties, followed by either a data
object or an error
object, but not both. An explanation of each of these properties can be found below.
-
-
-The top-level of the JSON object may contain the following properties.
-
-
-Property Value Type: string
Parent: -
-
-
-Represents the desired version of the service API in a request, and the version of the service API that's served in the response. apiVersion
should always be present. This is not related to the version of the data. Versioning of data should be handled through some other mechanism such as etags.
Example:
-
-{ "apiVersion": "2.1" }
-
-
-
-
-
-
-Property Value Type: string
Parent: -
-
-
-Client sets this value and server echos data in the response. This is useful in JSON-P and batch situations , where the user can use the context
to correlate responses with requests. This property is a top-level property because the context
should present regardless of whether the response was successful or an error. context
differs from id
in that context
is specified by the user while id
is assigned by the service.
Example:
Request #1:
-
-http://www.google.com/myapi?context=bart
-
-
-Request #2:
-
-http://www.google.com/myapi?context=lisa
-
-
-Response #1:
-
-{
- "context": "bart",
- "data": {
- "items": []
- }
-}
-
-
-Response #2:
-
-{
- "context": "lisa",
- "data": {
- "items": []
- }
-}
-
-
-Common JavaScript handler code to process both responses:
-
-function handleResponse(response) {
- if (response.result.context == "bart") {
- // Update the "Bart" section of the page.
- } else if (response.result.context == "lisa") {
- // Update the "Lisa" section of the page.
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: -
-
-
-A server supplied identifier for the response (regardless of whether the response is a success or an error). This is useful for correlating server logs with individual responses received at a client.
Example:
-
-{ "id": "1" }
-
-
-
-
-
-
-Property Value Type: string
Parent: -
-
-
-Represents the operation to perform, or that was performed, on the data. In the case of a JSON request, the method
property can be used to indicate which operation to perform on the data. In the case of a JSON response, the method
property can indicate the operation performed on the data.
One example of this is in JSON-RPC requests, where method
indicates the operation to perform on the params
property:
-
-{
- "method": "people.get",
- "params": {
- "userId": "@me",
- "groupId": "@self"
- }
-}
-
-
-
-
-
-
-Property Value Type: object
Parent: -
-
-
-This object serves as a map of input parameters to send to an RPC request. It can be used in conjunction with the method
property to execute an RPC function. If an RPC function does not need parameters, this property can be omitted.
Example:
-
-{
- "method": "people.get",
- "params": {
- "userId": "@me",
- "groupId": "@self"
- }
-}
-
-
-
-
-
-
-Property Value Type: object
Parent: -
-
-
-Container for all the data from a response. This property itself has many reserved property names, which are described below. Services are free to add their own data to this object. A JSON response should contain either a data
object or an error
object, but not both. If both data
and error
are present, the error
object takes precedence.
-
-
-
-
-Property Value Type: object
Parent: -
-
-
-Indicates that an error has occurred, with details about the error. The error format supports either one or more errors returned from the service. A JSON response should contain either a data
object or an error
object, but not both. If both data
and error
are present, the error
object takes precedence.
Example:
-
-{
- "apiVersion": "2.0",
- "error": {
- "code": 404,
- "message": "File Not Found",
- "errors": [{
- "domain": "Calendar",
- "reason": "ResourceNotFoundException",
- "message": "File Not Found
- }]
- }
-}
-
-
-
-
-
-
-The data
property of the JSON object may contain the following properties.
-
-
-Property Value Type: string
Parent: data
-
-
-The kind
property serves as a guide to what type of information this particular object stores. It can be present at the data
level, or at the items
level, or in any object where its helpful to distinguish between various types of objects. If the kind
object is present, it should be the first property in the object (See the "Property Ordering" section below for more details).
Example:
-
-// "Kind" indicates an "album" in the Picasa API.
-{"data": {"kind": "album"}}
-
-
-
-
-
-
-Property Value Type: string
Parent: data
-
-
-Represents the fields present in the response when doing a partial GET, or the fields present in a request when doing a partial PATCH. This property should only exist during a partial GET/PATCH, and should not be empty.
Example:
-
-{
- "data": {
- "kind": "user",
- "fields": "author,id",
- "id": "bart",
- "author": "Bart"
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: data
-
-
-Represents the etag for the response. Details about ETags in the GData APIs can be found here: http://code.google.com/apis/gdata/docs/2.0/reference.html#ResourceVersioning
Example:
-
-{"data": {"etag": "W/"C0QBRXcycSp7ImA9WxRVFUk.""}}
-
-
-
-
-
-
-Property Value Type: string
Parent: data
-
-
-A globally unique string used to reference the object. The specific details of the id
property are left up to the service.
Example:
-
-{"data": {"id": "12345"}}
-
-
-
-
-
-
-Property Value Type: string (formatted as specified in BCP 47)
Parent: data (or any child element)
-
-
-Indicates the language of the rest of the properties in this object. This property mimics HTML's lang
property and XML's xml:lang
properties. The value should be a language value as defined in BCP 47. If a single JSON object contains data in multiple languages, the service is responsible for developing and documenting an appropriate location for the lang
property.
Example:
-
-{"data": {
- "items": [
- { "lang": "en",
- "title": "Hello world!" },
- { "lang": "fr",
- "title": "Bonjour monde!" }
- ]}
-}
-
-
-
-
-
-Property Value Type: string (formatted as specified in RFC 3339)
Parent: data
-
-
-Indicates the last date/time (RFC 3339) the item was updated, as defined by the service.
Example:
-
-{"data": {"updated": "2007-11-06T16:34:41.000Z"}}
-
-
-
-
-
-
-Property Value Type: boolean
Parent: data (or any child element)
-
-
-A marker element, that, when present, indicates the containing entry is deleted. If deleted is present, its value must be true
; a value of false
can cause confusion and should be avoided.
Example:
-
-{"data": {
- "items": [
- { "title": "A deleted entry",
- "deleted": true
- }
- ]}
-}
-
-
-
-
-
-
-Property Value Type: array
Parent: data
-
-
-The property name items
is reserved to represent an array of items (for example, photos in Picasa, videos in YouTube). This construct is intended to provide a standard location for collections related to the current result. For example, the JSON output could be plugged into a generic pagination system that knows to page on the items
array. If items
exists, it should be the last property in the data
object (See the "Property Ordering" section below for more details).
Example:
-
-{
- "data": {
- "items": [
- { /* Object #1 */ },
- { /* Object #2 */ },
- ...
- ]
- }
-}
-
-
-
-
-
-
-The following properties are located in the data
object, and help page through a list of items. Some of the language and concepts are borrowed from the OpenSearch specification.
The paging properties below allow for various styles of paging, including:
- Previous/Next paging - Allows user's to move forward and backward through a list, one page at a time. The
nextLink
and previousLink
properties (described in the "Reserved Property Names for Links" section below) are used for this style of paging. - Index-based paging - Allows user's to jump directly to a specific item position within a list of items. For example, to load 10 items starting at item 200, the developer may point the user to a url with the query string
?startIndex=200
. - Page-based paging - Allows user's to jump directly to a specific page within the items. This is similar to index-based paging, but saves the developer the extra step of having to calculate the item index for a new page of items. For example, rather than jump to item number 200, the developer could jump to page 20. The urls during page-based paging could use the query string
?page=1
or ?page=20
. The pageIndex
and totalPages
properties are used for this style of paging.
An example of how to use these properties to implement paging can be found at the end of this guide.
-
-
-Property Value Type: integer
Parent: data
-
-
-The number of items in this result set. Should be equivalent to items.length, and is provided as a convenience property. For example, suppose a developer requests a set of search items, and asks for 10 items per page. The total set of that search has 14 total items. The first page of items will have 10 items in it, so both itemsPerPage
and currentItemCount
will equal "10". The next page of items will have the remaining 4 items; itemsPerPage
will still be "10", but currentItemCount
will be "4".
Example:
-
-{
- "data": {
- // "itemsPerPage" does not necessarily match "currentItemCount"
- "itemsPerPage": 10,
- "currentItemCount": 4
- }
-}
-
-
-
-
-
-
-Property Value Type: integer
Parent: data
-
-
-The number of items in the result. This is not necessarily the size of the data.items array; if we are viewing the last page of items, the size of data.items may be less than itemsPerPage
. However the size of data.items should not exceed itemsPerPage
.
Example:
-
-{
- "data": {
- "itemsPerPage": 10
- }
-}
-
-
-
-
-
-
-Property Value Type: integer
Parent: data
-
-
-The index of the first item in data.items. For consistency, startIndex
should be 1-based. For example, the first item in the first set of items should have a startIndex
of 1. If the user requests the next set of data, the startIndex
may be 10.
Example:
-
-{
- "data": {
- "startIndex": 1
- }
-}
-
-
-
-
-
-
-Property Value Type: integer
Parent: data
-
-
-The total number of items available in this set. For example, if a user has 100 blog posts, the response may only contain 10 items, but the totalItems
would be 100.
Example:
-
-{
- "data": {
- "totalItems": 100
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: data
-
-
-A URI template indicating how users can calculate subsequent paging links. The URI template also has some reserved variable names: {index}
representing the item number to load, and {pageIndex}
, representing the page number to load.
Example:
-
-{
- "data": {
- "pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N"
- }
-}
-
-
-
-
-
-
-Property Value Type: integer
Parent: data
-
-
-The index of the current page of items. For consistency, pageIndex
should be 1-based. For example, the first page of items has a pageIndex
of 1. pageIndex
can also be calculated from the item-based paging properties: pageIndex = floor(startIndex / itemsPerPage) + 1
.
Example:
-
-{
- "data": {
- "pageIndex": 1
- }
-}
-
-
-
-
-
-
-Property Value Type: integer
Parent: data
-
-
-The total number of pages in the result set. totalPages
can also be calculated from the item-based paging properties above: totalPages = ceiling(totalItems / itemsPerPage)
.
Example:
-
-{
- "data": {
- "totalPages": 50
- }
-}
-
-
-
-
-
-
-The following properties are located in the data
object, and represent references to other resources. There are two forms of link properties: 1) objects, which can contain any sort of reference (such as a JSON-RPC object), and 2) URI strings, which represent URIs to resources (and will always be suffixed with "Link").
-
-
-Property Value Type: object / string
Parent: data
-
-
-The self link can be used to retrieve the item's data. For example, in a list of a user's Picasa album, each album object in the items
array could contain a selfLink
that can be used to retrieve data related to that particular album.
Example:
-
-{
- "data": {
- "self": { },
- "selfLink": "http://www.google.com/feeds/album/1234"
- }
-}
-
-
-
-
-
-
-Property Value Type: object / string
Parent: data
-
-
-The edit link indicates where a user can send update or delete requests. This is useful for REST-based APIs. This link need only be present if the user can update/delete this item.
Example:
-
-{
- "data": {
- "edit": { },
- "editLink": "http://www.google.com/feeds/album/1234/edit"
- }
-}
-
-
-
-
-
-
-Property Value Type: object / string
Parent: data
-
-
-The next link indicates how more data can be retrieved. It points to the location to load the next set of data. It can be used in conjunction with the itemsPerPage
, startIndex
and totalItems
properties in order to page through data.
Example:
-
-{
- "data": {
- "next": { },
- "nextLink": "http://www.google.com/feeds/album/1234/next"
- }
-}
-
-
-
-
-
-
-Property Value Type: object / string
Parent: data
-
-
-The previous link indicates how more data can be retrieved. It points to the location to load the previous set of data. It can be used in conjunction with the itemsPerPage
, startIndex
and totalItems
properties in order to page through data.
Example:
-
-{
- "data": {
- "previous": { },
- "previousLink": "http://www.google.com/feeds/album/1234/next"
- }
-}
-
-
-
-
-
-
-The error
property of the JSON object may contain the following properties.
-
-
-Property Value Type: integer
Parent: error
-
-
-Represents the code for this error. This property value will usually represent the HTTP response code. If there are multiple errors, code
will be the error code for the first error.
Example:
-
-{
- "error":{
- "code": 404
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: error
-
-
-A human readable message providing more details about the error. If there are multiple errors, message
will be the message for the first error.
Example:
-
-{
- "error":{
- "message": "File Not Found"
- }
-}
-
-
-
-
-
-
-Property Value Type: array
Parent: error
-
-
-Container for any additional information regarding the error. If the service returns multiple errors, each element in the errors
array represents a different error.
Example:
-
-{ "error": { "errors": [] } }
-
-
-
-
-
-
-Property Value Type: string
Parent: error.errors
-
-
-Unique identifier for the service raising this error. This helps distinguish service-specific errors (i.e. error inserting an event in a calendar) from general protocol errors (i.e. file not found).
Example:
-
-{
- "error":{
- "errors": [{"domain": "Calendar"}]
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: error.errors
-
-
-Unique identifier for this error. Different from the error.code
property in that this is not an http response code.
Example:
-
-{
- "error":{
- "errors": [{"reason": "ResourceNotFoundException"}]
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: error.errors
-
-
-A human readable message providing more details about the error. If there is only one error, this field will match error.message
.
Example:
-
-{
- "error":{
- "code": 404
- "message": "File Not Found",
- "errors": [{"message": "File Not Found"}]
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: error.errors
-
-
-The location of the error (the interpretation of its value depends on locationType
).
Example:
-
-{
- "error":{
- "errors": [{"location": ""}]
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: error.errors
-
-
-Indicates how the location
property should be interpreted.
Example:
-
-{
- "error":{
- "errors": [{"locationType": ""}]
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: error.errors
-
-
-A URI for a help text that might shed some more light on the error.
Example:
-
-{
- "error":{
- "errors": [{"extendedHelper": "http://url.to.more.details.example.com/"}]
- }
-}
-
-
-
-
-
-
-Property Value Type: string
Parent: error.errors
-
-
-A URI for a report form used by the service to collect data about the error condition. This URI should be preloaded with parameters describing the request.
Example:
-
-{
- "error":{
- "errors": [{"sendReport": "http://report.example.com/"}]
- }
-}
-
-
-
-
-
-
-Properties can be in any order within the JSON object. However, in some cases the ordering of properties can help parsers quickly interpret data and lead to better performance. One example is a pull parser in a mobile environment, where performance and memory are critical, and unnecessary parsing should be avoided.
-
-
-kind
should be the first property
-
-
-Suppose a parser is responsible for parsing a raw JSON stream into a specific object. The kind
property guides the parser to instantiate the appropriate object. Therefore it should be the first property in the JSON object. This only applies when objects have a kind
property (usually found in the data
and items
properties).
-
-
-
-
-items
should be the last property in the data
object
-
-
-This allows all of the collection's properties to be read before reading each individual item. In cases where there are a lot of items, this avoids unnecessarily parsing those items when the developer only needs fields from the data.
-
-
-
-
-
-// The "kind" property distinguishes between an "album" and a "photo".
-// "Kind" is always the first property in its parent object.
-// The "items" property is the last property in the "data" object.
-{
- "data": {
- "kind": "album",
- "title": "My Photo Album",
- "description": "An album in the user's account",
- "items": [
- {
- "kind": "photo",
- "title": "My First Photo"
- }
- ]
- }
-}
-
-
-
-
-
-
-
-
-Here's an example of the YouTube JSON API's response object. You can learn more about YouTube's JSON API here: http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html.
-
-
-
-{
- "apiVersion": "2.0",
- "data": {
- "updated": "2010-02-04T19:29:54.001Z",
- "totalItems": 6741,
- "startIndex": 1,
- "itemsPerPage": 1,
- "items": [
- {
- "id": "BGODurRfVv4",
- "uploaded": "2009-11-17T20:10:06.000Z",
- "updated": "2010-02-04T06:25:57.000Z",
- "uploader": "docchat",
- "category": "Animals",
- "title": "From service dog to SURFice dog",
- "description": "Surf dog Ricochets inspirational video ...",
- "tags": [
- "Surf dog",
- "dog surfing",
- "dog",
- "golden retriever",
- ],
- "thumbnail": {
- "default": "http://i.ytimg.com/vi/BGODurRfVv4/default.jpg",
- "hqDefault": "http://i.ytimg.com/vi/BGODurRfVv4/hqdefault.jpg"
- },
- "player": {
- "default": "http://www.youtube.com/watch?v=BGODurRfVv4&feature=youtube_gdata",
- "mobile": "http://m.youtube.com/details?v=BGODurRfVv4"
- },
- "content": {
- "1": "rtsp://v5.cache6.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
- "5": "http://www.youtube.com/v/BGODurRfVv4?f=videos&app=youtube_gdata",
- "6": "rtsp://v7.cache7.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp"
- },
- "duration": 315,
- "rating": 4.96,
- "ratingCount": 2043,
- "viewCount": 1781691,
- "favoriteCount": 3363,
- "commentCount": 1007,
- "commentsAllowed": true
- }
- ]
- }
-}
-
-
-
-
-
-
-This example demonstrates how the Google search items could be represented as a JSON object, with special attention to the paging variables.
-
-
-This sample is for illustrative purposes only. The API below does not actually exist.
Here's a sample Google search results page:
Here's a sample JSON representation of this page:
-
-{
- "apiVersion": "2.1",
- "id": "1",
- "data": {
- "query": "chicago style pizza",
- "time": "0.1",
- "currentItemCount": 10,
- "itemsPerPage": 10,
- "startIndex": 11,
- "totalItems": 2700000,
- "nextLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=20&sa=N"
- "previousLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=0&sa=N",
- "pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N",
- "items": [
- {
- "title": "Pizz'a Chicago Home Page"
- // More fields for the search results
- }
- // More search results
- ]
- }
-}
-
-
-Here's how each of the colored boxes from the screenshot would be represented (the background colors correspond to the colors in the images above):
- Results 11 - 20 of about 2,700,000 = startIndex
- Results 11 - 20 of about 2,700,000 = startIndex + currentItemCount - 1
- Results 11 - 20 of about 2,700,000 = totalItems
- Search results = items (formatted appropriately)
- Previous/Next = previousLink / nextLink
- Numbered links in "Gooooooooooogle" = Derived from "pageLinkTemplate". The developer is responsible for calculating the values for {index} and substituting those values into the "pageLinkTemplate". The pageLinkTemplate's {index} variable is calculated as follows:
- Index #1 = 0 * itemsPerPage = 0
- Index #2 = 2 * itemsPerPage = 10
- Index #3 = 3 * itemsPerPage = 20
- Index #N = N * itemsPerPage
-
-
-
-
-
-
-A list of reserved JavaScript words that should be avoided in property names.
-
-
-The words below are reserved by the JavaScript language and cannot be referred to using dot notation. The list represents best knowledge of keywords at this time; the list may change or vary based on your specific execution environment.
From the ECMAScript Language Specification 5th Edition
-
-abstract
-boolean break byte
-case catch char class const continue
-debugger default delete do double
-else enum export extends
-false final finally float for function
-goto
-if implements import in instanceof int interface
-let long
-native new null
-package private protected public
-return
-short static super switch synchronized
-this throw throws transient true try typeof
-var volatile void
-while with
-yield
-
-
-
-
-
-
-
-Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the Apache 2.0 License.
-
-
-Revision 0.9
-
-
-
-
-
-
diff --git a/lispguide.asciidoc b/lispguide.asciidoc
new file mode 100644
index 0000000..538d5f2
--- /dev/null
+++ b/lispguide.asciidoc
@@ -0,0 +1,1653 @@
+= Google Common Lisp Style Guide
+
+Revision 1.28
+
+Robert Brown
+
+mailto:tunes@google.com[François-René Rideau]
+
+In memoriam Dan Weinreb
+
+Patterns mean "I have run out of language." — Rich Hickey
+
+Each style point has a summary for which additional information is available by toggling the accompanying arrow button that looks this way: ▶. You may toggle all summaries with the big arrow button:
+
+▶ Toggle all summaries
+
+Table of Contents
+
+[width="100%",cols="50%,50%",]
+|===========================================================================================================================================================================================================================================================================================================================================
+a|
+link:#Meta-Guide[Meta-Guide]
+
+ a|
+link:#Must,_Should,_May,_or_Not[Must, Should, May, or Not] link:#permission-and-forgiveness[Permission and Forgiveness] link:#conventions[Conventions] link:#old-code[Old Code] link:#future-topics[Future Topics]
+
+a|
+link:#general-guidelines[General Guidelines]
+
+ a|
+link:#principles[Principles] link:#priorities[Priorities] link:#architecture[Architecture] link:#using-libraries[Using Libraries] link:#Open-Sourcing_Code[Open-Sourcing Code] link:#development-process[Development Process]
+
+a|
+link:#formatting[Formatting]
+
+ a|
+link:#spelling-and-abbreviations[Spelling and Abbreviations] link:#line-length[Line length] link:#indentation[Indentation] link:#file-header[File Header] link:#vertical-white-space[Vertical white space] link:#horizontal-white-space[Horizontal white space]
+
+a|
+link:#documentation[Documentation]
+
+ a|
+link:#document-everything[Document everything] link:#comment-semicolons[Comment semicolons] link:#grammar-and-punctuation[Grammar and punctuation] link:#attention-required[Attention Required] link:#Domain-Specific_Languages[Domain-Specific Languages]
+
+a|
+link:#naming[Naming]
+
+ a|
+link:#symbol-guidelines[Symbol guidelines] link:#Denote_intent,_not_content[Denote intent, not content] link:#global-variables-and-constants[Global variables and constants] link:#predicate-names[Predicate names] link:#omit-library-prefixes[Omit library prefixes] link:#packages[Packages]
+
+a|
+link:#language-usage-guidelines[Language usage guidelines]
+
+ a|
+link:#mostly-functional-style[Mostly Functional Style] link:#recursion[Recursion] link:#special-variables[Special variables] link:#assignment[Assignment] link:#assertions-and-conditions[Assertions and Conditions] link:#type-checking[Type Checking] link:#clos[CLOS]
+
+a|
+link:#Meta-language_guidelines[Meta-language guidelines]
+
+ a|
+link:#macros[Macros] link:#EVAL-WHEN[EVAL-WHEN] link:#Read-time_evaluation[Read-time evaluation] link:#eval[EVAL] link:#intern-and-unintern[INTERN and UNINTERN]
+
+a|
+link:#data-representation[Data Representation]
+
+ a|
+#NIL:_empty-list,_false_and_I_Don_t_Know[NIL: empty-list, false and I Don't Know] link:#do-not-abuse-lists[Do not abuse lists] link:#lists_vs._structures_vs._multiple_values[Lists vs. structures vs. multiple values] link:#lists-vs-pairs[Lists vs. Pairs] link:#lists-vs-arrays[Lists vs. Arrays] link:#lists-vs-sets[Lists vs. Sets]
+
+a|
+link:#proper-forms[Proper Forms]
+
+ a|
+link:#defining-constants[Defining Constants] link:#defining-functions[Defining Functions] link:#conditional-expressions[Conditional Expressions] link:#Identity,_Equality_and_Comparisons[Identity, Equality and Comparisons] link:#iteration[Iteration] link:#i-o[I/O]
+
+a|
+link:#optimization[Optimization]
+
+ a|
+link:#avoid-allocation[Avoid Allocation] link:#unsafe-operations[Unsafe Operations] link:#DYNAMIC-EXTENT[DYNAMIC-EXTENT] link:#reduce-vs-apply[REDUCE vs APPLY] link:#avoid-nconc[Avoid NCONC]
+
+a|
+link:#pitfalls[Pitfalls]
+
+ a|
+link:#--fun_vs-__fun[#'FUN vs. 'FUN] link:#pathnames[Pathnames] link:#satisfies[SATISFIES]
+
+|===========================================================================================================================================================================================================================================================================================================================================
+
+[[Important_Note]]
+== Important Note
+
+=== Note: Displaying Hidden Details in this Guide
+
+?showone=Note:_Displaying_Hidden_Details_in_this_Guide#Note:_Displaying_Hidden_Details_in_this_Guide[link]▶
+
+This style guide contains many details that are initially hidden from view. They are marked by the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear below.
+
+Hooray! Now you know you can expand points to get more details. Alternatively, there's an "expand all" at the top of this document.
+
+[[Background]]
+== Background
+
+Common Lisp is a powerful multiparadigm programming language. With great power comes great responsibility.
+
+This guide recommends formatting and stylistic choices designed to make your code easier for other people to understand. For those internal applications and free software libraries that we develop at Google, you should keep within these guidelines when making changes. Note however that each project has its own rules and customs that complement or override these general guidelines; the speed-oriented QPX low fare search engine notably has a very different style and feel from the QRes reservation system.
+
+If you're writing Common Lisp code outside Google, we invite you to consider these guidelines. You may find some of them useful where they don't conflict with other priorities you have. We welcome remarks and constructive feedback on how to improve our guide, and on what alternate styles work for you and why.
+
+This guide is not a Common Lisp tutorial. For basic information about the language, please consult http://www.gigamonkeys.com/book/[Practical Common Lisp]. For a language reference, please consult the http://www.lispworks.com/documentation/HyperSpec/Front/index.htm[Common Lisp HyperSpec]. For more detailed style guidance, take (with a pinch of salt) a look at Peter Norvig and Kent Pitman's http://norvig.com/luv-slides.ps[style guide].
+
+[[Meta-Guide]]
+== Meta-Guide
+
+=== Must, Should, May, or Not
+
+link:?showone=Must,_Should,_May,_or_Not#Must,_Should,_May,_or_Not[link]▶
+
+Each guideline's level of importance is indicated by use of the following keywords and phrases, adapted from http://www.ietf.org/rfc/rfc2119.txt[RFC 2119].
+
+[width="100%",cols="50%,50%",]
+|==========================================================================================================================================================================================================================================================================================================================================
+|MUST |This word, or the terms "REQUIRED" or "SHALL", means that the guideline is an absolute requirement. You must ask permission to violate a MUST.
+|MUST NOT |This phrase, or the phrase "SHALL NOT", means that the guideline is an absolute prohibition. You must ask permission to violate a MUST NOT.
+|SHOULD |This word, or the adjective "RECOMMENDED", means that there may exist valid reasons in particular circumstances to ignore the demands of the guideline, but the full implications must be understood and carefully weighed before choosing a different course. You must ask forgiveness for violating a SHOULD.
+|SHOULD NOT |This phrase, or the phrase "NOT RECOMMENDED", means that there may exist valid reasons in particular circumstances to ignore the prohibitions of this guideline, but the full implications should be understood and carefully weighed before choosing a different course. You must ask forgiveness for violating a SHOULD NOT.
+|MAY |This word, or the adjective "OPTIONAL", means that an item is truly optional.
+|==========================================================================================================================================================================================================================================================================================================================================
+
+Unlike RFCs, we don't capitalize every instance of one of the above keywords when it is used.
+
+=== Permission and Forgiveness
+
+link:?showone=Permission_and_Forgiveness#Permission_and_Forgiveness[link]▶
+
+There are cases where transgression of some of these rules is useful or even necessary. In some cases, you must seek permission or obtain forgiveness from the proper people.
+
+Permission comes from the owners of your project.
+
+Forgiveness is requested in a comment near the point of guideline violation, and is granted by your code reviewer. The original comment should be signed by you, and the reviewer should add a signed approval to the comment at review time.
+
+=== Conventions
+
+link:?showone=Conventions#Conventions[link]▶
+
+You MUST follow conventions. They are not optional.
+
+Some of these guidelines are motivated by universal principles of good programming. Some guidelines are motivated by technical peculiarities of Common Lisp. Some guidelines were once motivated by a technical reason, but the guideline remained after the reason subsided. Some guidelines, such those about as comments and indentation, are based purely on convention, rather than on clear technical merit. Whatever the case may be, you must still follow these guidelines, as well as other conventional guidelines that have not been formalized in this document.
+
+You MUST follow conventions. They are important for readability. When conventions are followed by default, violations of the convention are a signal that something notable is happening and deserves attention. When conventions are systematically violated, violations of the convention are a distracting noise that needs to be ignored.
+
+Conventional guidelines _are_ indoctrination. Their purpose is to make you follow the mores of the community, so you can more effectively cooperate with existing members. It is still useful to distinguish the parts that are technically motivated from the parts that are mere conventions, so you know when best to defy conventions for good effect, and when not to fall into the pitfalls that the conventions are there to help avoid.
+
+=== Old Code
+
+link:?showone=Old_Code#Old_Code[link]▶
+
+Fix old code as you go.
+
+A lot of our code was written before these guidelines existed. You should fix violations as you encounter them in the course of your normal coding.
+
+You must not fix violations en masse without warning other developers and coordinating with them, so as not to make the merging of large branches more difficult than it already is.
+
+=== Future Topics
+
+link:?showone=Future_Topics#Future_Topics[link]▶
+
+There are many topics for additional standardization not covered by current version of this document, but deferred to future versions.
+
+
+* File and directory structure
+
+* Packages and modularity
+
+* Threads and locking
+
+* How to add configurable components
+
+* CLOS style: initforms, slot and accessor names, etc.
+
+* Recommendations on max number of slots per class.
+
+* More concrete examples of good code:
+
+** exceptions
+
+** transactions, with retry
+
+** XML
+
+** typing
+
+** encapsulation / abstraction
+
+** class and slot names
+
+** etc.
+
+* When (not) to use conditional compilation:
+
+** modifying the product
+
+** conditional debugging/console output/etc.
+
+** "temporarily" commenting-out blocks of code
+
+** etc.
+
+[[General_Guidelines]]
+== General Guidelines
+
+=== Principles
+
+link:?showone=Principles#Principles[link]▶
+
+There are some basic principles for team software development that every developer must keep in mind. Whenever the detailed guidelines are inadequate, confusing or contradictory, refer back to these principles for guidance:
+
+
+* Every developer's code must be easy for another developer to read, understand, and modify — even if the first developer isn't around to explain it. (This is the "hit by a truck" principle.)
+
+* Everybody's code should look the same. Ideally, there should be no way to look at lines of code and recognize it as "Fred's code" by its style.
+
+* Be precise.
+
+* Be concise.
+
+* KISS — Keep It Simple, Stupid.
+
+* Use the smallest hammer for the job.
+
+* Use common sense.
+
+* Keep related code together. Minimize the amount of jumping around someone has to do to understand an area of code.
+
+=== Priorities
+
+link:?showone=Priorities#Priorities[link]▶
+
+When making decisions about how to write a given piece of code, aim for the following -ilities in this priority order:
+
+
+* Usability by the customer
+
+* Debuggability/Testability
+
+* Readability/Comprehensibility
+
+* Extensibility/Modifiability
+
+* Efficiency (of the Lisp code at runtime)
+
+Most of these are obvious.
+
+Usability by the customer means that the system has to do what the customer requires; it has to handle the customer's transaction volumes, uptime requirements; etc.
+
+For the Lisp efficiency point, given two options of equivalent complexity, pick the one that performs better. (This is often the same as the one that conses less, i.e. allocates less storage from the heap.)
+
+Given two options where one is more complex than the other, pick the simpler option and revisit the decision only if profiling shows it to be a performance bottleneck.
+
+However, avoid premature optimization. Don't add complexity to speed up something that runs rarely, since in the long run, it matters less whether such code is fast.
+
+=== Architecture
+
+link:?showone=Architecture#Architecture[link]▶
+
+To build code that is robust and maintainable, it matters a lot how the code is divided into components, how these components communicate, how changes propagate as they evolve, and more importantly how the programmers who develop these components communicate as these components evolve.
+
+If your work affects other groups, might be reusable across groups, adds new components, has an impact on other groups (including QA or Ops), or otherwise isn't purely local, you must write it up using at least a couple of paragraphs, and get a design approval from the other parties involved before starting to write code — or be ready to scratch what you have when they object.
+
+If you don't know or don't care about these issues, ask someone who does.
+
+=== Using Libraries
+
+link:?showone=Using_Libraries#Using_Libraries[link]▶
+
+Often, the smallest hammer is to use an existing library. Or one that doesn't exist yet. In such cases, you are encouraged to use or develop such a library, but you must take appropriate precautions.
+
+
+* You MUST NOT start a new library unless you established that none is already available that can be fixed or completed into becoming what you need. That's a rule against the NIH syndrome ("Not Invented Here"), which is particularly strong amongst Lisp hackers.
+
+* Whichever library, old or new, you pick, you MUST get permission to incorporate third-party code into the code base. You must discuss the use of such library in the appropriate mailing-list, and have your code reviewed by people knowledgeable in the domain and/or the Lisp library ecosystem (if any). Please be ready to argue why this particular solution makes sense as compared to other available libraries.
+
+* Some libraries are distributed under licenses not compatible with the software you're writing, and must not be considered available for use. Be aware of these issues, or consult with people who are.
+
+=== Open-Sourcing Code
+
+link:?showone=Open-Sourcing_Code#Open-Sourcing_Code[link]▶
+
+If you write a general-purpose library, or modify an existing open-source library, you are encouraged to publish the result separate from your main project and then have your project import it like any other open-source library.
+
+Use your judgment to distinguish general-purpose versus business-specific code, and open-source the general-purpose parts, while keeping the business-specific parts a trade secret.
+
+Open-Sourcing code has many advantages, including being able to leverage third parties for development, letting the development of features be user-directed, and keeping you honest with respect to code quality. Whatever code you write, you will have to maintain anyway, and make sure its quality is high enough to sustain use in production. There should therefore be no additional burden to Open-Sourcing, even of code that (at least initially) is not directly usable by third parties.
+
+=== Development Process
+
+link:?showone=Development_Process#Development_Process[link]▶
+
+Development process is outside the scope of this document. However, developers should remember at least these bits: get reviewed, write tests, eliminate warnings, run tests, avoid mass-changes.
+
+
+* All code changes must be reviewed. You should expect that your code will be reviewed by other hackers, and that you will be assigned other hackers' code to review. Part of the review criteria will be that code obeys the coding standards in this document.
+
+* You must write and check-in tests for new code that you write and old bugs you fix. There must be a unit test for every API function, and any previously failing case. Your work is not truly done until this activity is complete. Estimating tasks must include the time it takes to produce such tests.
+
+* Your code must compile without any compilation error or warning messages whatsoever. If the compiler issues warnings that should be ignored, muffle those warnings using the `UIOP:WITH-MUFFLED-COMPILER-CONDITIONS` and `UIOP:*UNINTERESTING-COMPILER-CONDITIONS*` framework (part of `UIOP`, part of `ASDF 3`), either around the entire project, or around individual files (using `ASDF`'s `:around-compile` hooks).
+
+* All code should be checked in an appropriate source control system, in a way that allows for complete reproducibility of build, test and execution of the code that is, has been or may be deployed.
+
+* You must run the "precheckin" tests, and each component must pass its unit tests successfully before you commit any code.
+
+* You should incorporate code coverage into your testing process. Tests are not sufficient if they do not cover all new and updated code; code that for whatever reason cannot be included in coverage results should be clearly marked as such including the reason.
+
+* Many people develop on branches. You must get permission to undertake mass-changes (e.g. mass reindentations) so that we can coordinate in advance, and give branch residents time to get back on the mainline
+
+[[Formatting]]
+== Formatting
+
+=== Spelling and Abbreviations
+
+link:?showone=Spelling_and_Abbreviations#Spelling_and_Abbreviations[link]▶
+
+You must use correct spelling in your comments, and most importantly in your identifiers.
+
+When several correct spellings exist (including American vs English), and there isn't a consensus amongst developers as which to use, you should choose the shorter spelling.
+
+You must use only common and domain-specific abbreviations, and must be consistent with these abbreviations. You may abbreviate lexical variables of limited scope in order to avoid overly-long symbol names.
+
+If you're not sure, consult a dictionary, Google for alternative spellings, or ask a local expert.
+
+Here are examples of choosing the correct spelling:
+
+
+* Use "complimentary" in the sense of a meal or beverage that is not paid for by the recipient, not "complementary".
+
+* Use "existent" and "nonexistent", not "existant". Use "existence", not "existance".
+
+* Use "hierarchy" not "heirarchy".
+
+* Use "precede" not "preceed".
+
+* Use "weird", not "wierd".
+
+Here are examples of choosing the shorter spelling:
+
+
+* Use "canceled", not "cancelled"
+
+* Use "queuing", not "queueing".
+
+* Use "signaled", not "signalled";
+
+* Use "traveled", not "travelled".
+
+* Use "aluminum", not "aluminium"
+
+* Use "oriented", not "orientated"
+
+* Use "color", not "colour"
+
+* Use "behavior", not "behaviour"
+
+Make appropriate exceptions for industry standard nomenclature/jargon, including plain misspellings. For instance:
+
+
+* Use "referer", not "referrer", in the context of the HTTP protocol.
+
+=== Line length
+
+link:?showone=Line_length#Line_length[link]▶
+
+You should format source code so that no line is longer than 100 characters.
+
+Some line length restriction is better than none at all. While old text terminals used to make 80 columns the standard, these days, allowing 100 columns seems better, since good style encourages the use of descriptive variables and function names.
+
+=== Indentation
+
+link:?showone=Indentation#Indentation[link]▶
+
+Indent your code the way a properly configured GNU Emacs does.
+
+Maintain a consistent indentation style throughout a project.
+
+Indent carefully to make the code easier to understand.
+
+Common Lisp indentation in Emacs is provided by the cl-indent library. The latest version of cl-indent is packaged with http://www.common-lisp.net/project/slime/[SLIME] (under contrib/slime-cl-indent.el). After installing SLIME, set up Emacs to load SLIME automatically using http://www.common-lisp.net/project/slime/doc/html/Loading-Contribs.html[these instructions], adding slime-indentation to the list of contrib libraries to be loaded in the call to slime-setup.
+
+Ideally, use the default indentation settings provided by slime-indentation. If necessary, customize indentation parameters to maintain a consistent indentation style throughout an existing project. Parameters can be customized using the :variables setting in define-common-lisp-style. Indentation of specific forms can be customized using the :indentation setting of define-common-lisp-style. This is particularly useful when creating forms that behave like macros or special operators that are indented differently than standard function calls (e.g. defun, labels, or let). Add a http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html[hook] to 'lisp-mode-hook that calls common-lisp-set-style to set the appropriate style automatically.
+
+Use indentation to make complex function applications easier to read. When an application does not fit on one line or the function takes many arguments, consider inserting newlines between the arguments so that each one is on a separate line. However, do not insert newlines in a way that makes it hard to tell how many arguments the function takes or where an argument form starts and ends.
+
+--------------------------------------------------------
+;; Bad
+(do-something first-argument second-argument (lambda (x)
+ (frob x)) fourth-argument last-argument)
+--------------------------------------------------------
+
+-------------------------------------
+;; Better
+(do-something first-argument
+ second-argument
+ #'(lambda (x) (frob x))
+ fourth-argument
+ last-argument)
+-------------------------------------
+
+=== File Header
+
+link:?showone=File_Header#File_Header[link]▶
+
+You should include a description at the top of each source file.
+
+You should include neither authorship nor copyright information in a source file.
+
+Every source file should begin with a brief description of the contents of that file.
+
+After that description, every file should start the code itself with an `(in-package :package-name)` form.
+
+After that `in-package` form, every file should follow with any file-specific `(declaim (optimize ...))` declaration that is not covered by an `ASDF` `:around-compile` hook.
+
+----------------------------------------------------------------------
+;;;; Variable length encoding for integers and floating point numbers.
+
+(in-package #:varint)
+(declaim #.*optimize-default*)
+----------------------------------------------------------------------
+
+You should not include authorship information at the top of a file: better information is available from version control, and such a mention will only cause confusion and grief. Indeed, whoever was the main author at the time such a mention was included might not be who eventually made the most significant contributions to the file, and even less who is responsible for the file at the moment.
+
+You should not include copyright information in individual source code files. An exception is made for files meant to be disseminated as standalone.
+
+=== Vertical white space
+
+link:?showone=Vertical_white_space#Vertical_white_space[link]▶
+
+Vertical white space: one blank line between top-level forms.
+
+You should include one blank line between top-level forms, such as function definitions. Exceptionally, blank lines can be omitted between simple, closely related defining forms of the same kind, such as a group of related type declarations or constant definitions.
+
+-----------------------------------------------------------------------------------
+(defconstant +mix32+ #x12b9b0a1 "pi, an arbitrary number")
+(defconstant +mix64+ #x2b992ddfa23249d6 "more digits of pi")
+
+(defconstant +golden-ratio32+ #x9e3779b9 "the golden ratio")
+(defconstant +golden-ratio64+ #xe08c1d668b756f82 "more digits of the golden ratio")
+
+(defmacro incf32 (x y)
+ "Like INCF, but for integers modulo 2**32"
+ `(setf ,x (logand (+ ,x ,y) #xffffffff)))
+(defmacro incf64 (x y)
+ "Like INCF, but for integers modulo 2**64"
+ `(setf ,x (logand (+ ,x ,y) #xffffffffffffffff)))
+-----------------------------------------------------------------------------------
+
+Blank lines can be used to separate parts of a complicated function. Generally, however, you should break a large function into smaller ones instead of trying to make it more readable by adding vertical space. If you can't, you should document with a `;;` comment what each of the separated parts of the function does.
+
+You should strive to keep top-level forms, including comments but excluding the documentation string, of appropriate length; preferrably short. Forms extending beyond a single page should be rare and their use should be justfied. This applies to each of the forms in an `eval-when`, rather than to the `eval-when` itself. Additionally, `defpackage` forms may be longer, since they may include long lists of symbols.
+
+=== Horizontal white space
+
+link:?showone=Horizontal_white_space#Horizontal_white_space[link]▶
+
+Horizontal white space: none around parentheses. No tabs.
+
+You must not include extra horizontal whitespace before or after parentheses or around symbols.
+
+You must not place right parentheses by themselves on a line. A set of consecutive trailing parentheses must appear on the same line.
+
+----------------------------------------------
+;; Very Bad
+( defun factorial ( limit )
+ ( let (( product 1 ))
+ ( loop for i from 1 upto limit
+ do (setf product ( * product i ) ) )
+ product
+ )
+)
+----------------------------------------------
+
+------------------------------------------
+;; Better
+(defun factorial (limit)
+ (let ((product 1))
+ (loop for i from 1 upto limit
+ do (setf product (* product i)))
+ product))
+------------------------------------------
+
+You should use only one space between forms.
+
+You should not use spaces to vertically align forms in the middle of consecutive lines. An exception is made when the code possesses an important yet otherwise not visible symmetry that you want to emphasize.
+
+----------------------------------------------
+;; Bad
+(let* ((low 1)
+ (high 2)
+ (sum (+ (* low low) (* high high))))
+ ...)
+----------------------------------------------
+
+-------------------------------------------
+;; Better
+(let* ((low 1)
+ (high 2)
+ (sum (+ (* low low) (* high high))))
+ ...))
+-------------------------------------------
+
+You must align nested forms if they occur across more than one line.
+
+--------------------
+;; Bad
+(defun munge (a b c)
+(* (+ a b)
+c))
+--------------------
+
+--------------------
+;; Better
+(defun munge (a b c)
+ (* (+ a b)
+ c))
+--------------------
+
+The convention is that the body of a binding form is indented two spaces after the form. Any binding data before the body is usually indented four spaces. Arguments to a function call are aligned with the first argument; if the first argument is on its own line, it is aligned with the function name.
+
+----------------------------------------
+(multiple-value-bind (a b c d)
+ (function-returning-four-values x y)
+ (declare (ignore c))
+ (something-using a)
+ (also-using b d))
+----------------------------------------
+
+An exception to the rule against lonely parentheses is made for an `eval-when` form around several definitions; in this case, include a comment `; eval-when` after the closing parenthesis.
+
+You must set your editor to avoid inserting tab characters in the files you edit. Tabs cause confusion when editors disagree on how many spaces they represent. In Emacs, do `(setq-default indent-tabs-mode nil)`.
+
+[[Documentation]]
+== Documentation
+
+=== Document everything
+
+link:?showone=Document_everything#Document_everything[link]▶
+
+You should use document strings on all visible functions to explain how to use your code.
+
+Unless some bit of code is painfully self-explanatory, document it with a documentation string (also known as docstring).
+
+Documentation strings are destined to be read by the programmers who use your code. They can be extracted from functions, types, classes, variables and macros, and displayed by programming tools, such as IDEs, or by REPL queries such as `(describe 'foo)`; web-based documentation or other reference works can be created based on them. Documentation strings are thus the perfect locus to document your API. They should describe how to use the code (including what pitfalls to avoid), as opposed to how the code works (and where more work is needed), which is what you'll put in comments.
+
+Supply a documentation string when defining top-level functions, types, classes, variables and macros. Generally, add a documentation string wherever the language allows.
+
+For functions, the docstring should describe the function's contract: what the function does, what the arguments mean, what values are returned, what conditions the function can signal. It should be expressed at the appropriate level of abstraction, explaining the intended meaning rather than, say, just the syntax. In documentation strings, capitalize the names of Lisp symbols, such as function arguments. For example, "The value of LENGTH should be an integer."
+
+------------------------------------------------------------------------
+(defun small-prime-number-p (n)
+ "Return T if N, an integer, is a prime number. Otherwise, return NIL."
+ (cond ((or (< n 2))
+ nil)
+ ((= n 2)
+ t)
+ ((divisorp 2 n)
+ nil)
+ (t
+ (loop for i from 3 upto (sqrt n) by 2
+ never (divisorp i n)))))
+------------------------------------------------------------------------
+
+--------------------------------------------------
+(defgeneric table-clear (table)
+ (:documentation
+ "Like clrhash, empties the TABLE of all
+ associations, and returns the table itself."))
+--------------------------------------------------
+
+A long docstring may usefully begin with a short, single-sentence summary, followed by the larger body of the docstring.
+
+When the name of a type is used, the symbol may be quoted by surrounding it with a back quote at the beginning and a single quote at the end. Emacs will highlight the type, and the highlighting serves as a cue to the reader that M-. will lead to the symbol's definition.
+
+-----------------------------------------------------------------
+(defun bag-tag-expected-itinerary (bag-tag)
+ "Return a list of `legacy-pnr-pax-segment' objects representing
+ the expected itinerary of the `bag-tag' object, BAG-TAG."
+ ...)
+-----------------------------------------------------------------
+
+Every method of a generic function should be independently documented when the specialization affects what the method does, beyond what is described in its generic function's docstring.
+
+When you fix a bug, consider whether what the fixed code does is obviously correct or not; if not, you must add a comment explaining the reason for the code in terms of fixing the bug. Adding the bug number, if any, is also recommended.
+
+=== Comment semicolons
+
+link:?showone=Comment_semicolons#Comment_semicolons[link]▶
+
+You must use the appropriate number of semicolons to introduce comments.
+
+Comments are explanations to the future maintainers of the code. Even if you're the only person who will ever see and touch the code, even if you're either immortal and never going to quit, or unconcerned with what happens after you leave (and have your code self-destruct in such an eventuality), you may find it useful to comment your code. Indeed, by the time you revisit your code, weeks, months or years later, you will find yourself a different person from the one who wrote it, and you will be grateful to that previous self for making the code readable.
+
+You must comment anything complicated so that the next developer can understand what's going on. (Again, the "hit by a truck" principle.)
+
+Also use comments as a way to guide those who read the code, so they know what to find where.
+
+
+* File headers and important comments that apply to large sections of code in a source file should begin with four semicolons.
+
+* You should use three semicolons to begin comments that apply to just one top-level form or small group of top-level forms.
+
+* Inside a top-level form, you should use two semicolons to begin a comment if it appears between lines.
+
+* You should use one semicolon if it is a parenthetical remark and occurs at the end of a line. You should use spaces to separate the comment from the code it refers to so the comment stands out. You should try to vertically align consecutive related end-of-line comments.
+
+-------------------------------------------------------------------------
+;;;; project-euler.lisp
+;;;; File-level comments or comments for large sections of code.
+
+;;; Problems are described in more detail here: http://projecteuler.net/
+
+;;; Divisibility
+;;; Comments that describe a group of definitions.
+
+(defun divisorp (d n)
+ (zerop (mod n d)))
+
+(defun proper-divisors (n)
+ ...)
+
+(defun divisors (n)
+ (cons n (proper-divisors n)))
+
+;;; Prime numbers
+
+(defun small-prime-number-p (n)
+ (cond ((or (< n 2))
+ nil)
+ ((= n 2) ; parenthetical remark here
+ t) ; continuation of the remark
+ ((divisorp 2 n)
+ nil) ; different remark
+ ;; Comment that applies to a section of code.
+ (t
+ (loop for i from 3 upto (sqrt n) by 2
+ never (divisorp i n)))))
+-------------------------------------------------------------------------
+
+You should include a space between the semicolon and the text of the comment.
+
+=== Grammar and punctuation
+
+link:?showone=Grammar_and_punctuation#Grammar_and_punctuation[link]▶
+
+You should punctuate documentation correctly.
+
+When a comment is a full sentence, you should capitalize the initial letter of the first word and end the comment with a period. In general, you should use correct punctuation.
+
+=== Attention Required
+
+link:?showone=Attention_Required#Attention_Required[link]▶
+
+You must follow the convention of using TODO comments for code requiring special attention. For code using unobvious forms, you must include a comment.
+
+For comments requiring special attention, such as incomplete code, todo items, questions, breakage, and danger, include a TODO comment indicating the type of problem, its nature, and any notes on how it may be addressed.
+
+The comments begin with `TODO` in all capital letters, followed by the name, e-mail address, or other identifier of the person with the best context about the problem referenced by the `TODO`. The main purpose is to have a consistent `TODO` that can be searched to find out how to get more details upon request. A `TODO` is not a commitment that the person referenced will fix the problem. Thus when you create a `TODO`, it is almost always your name that is given.
+
+When signing comments, you should use your username (for code within the company) or full email address (for code visible outside the company), not just initials.
+
+---------------------------------------------------------------
+;;--- TODO(george@gmail.com): Refactor to provide a better API.
+---------------------------------------------------------------
+
+Be specific when indicating times or software releases in a TODO comment and use http://www.w3.org/TR/NOTE-datetime[YYYY-MM-DD] format for dates to make automated processing of such dates easier, e.g., 2038-01-20 for the end of the 32-bit signed `time_t`.
+
+---------------------------------------------------------------------------
+;;--- TODO(brown): Remove this code after release 1.7 or before 2012-11-30.
+---------------------------------------------------------------------------
+
+For code that uses unobvious forms to accomplish a task, you must include a comment stating the purpose of the form and the task it accomplishes.
+
+=== Domain-Specific Languages
+
+link:?showone=Domain-Specific_Languages#Domain-Specific_Languages[link]▶
+
+You should document DSLs and any terse program in a DSL.
+
+You should design your Domain Specific Language to be easy to read and understand by people familiar with the domain.
+
+You must properly document all your Domain Specific Language.
+
+Sometimes, your DSL is designed for terseness. In that case, it is important to document what each program does, if it's not painfully obvious from the context.
+
+Notably, when you use regular expressions (e.g. with the `CL-PPCRE` package), you MUST ALWAYS put in a comment (usually a two-semicolon comment on the previous line) explaining, at least basically, what the regular expression does, or what the purpose of using it is. The comment need not spell out every bit of the syntax, but it should be possible for someone to follow the logic of the code without actually parsing the regular expression.
+
+[[Naming]]
+== Naming
+
+=== Symbol guidelines
+
+link:?showone=Symbol_guidelines#Symbol_guidelines[link]▶
+
+You should use lower case. You should follow the rules for link:#spelling-and-abbreviations[Spelling and Abbreviations] You should follow punctuation conventions.
+
+Use lower case for all symbols. Consistently using lower case makes searching for symbol names easier and is more readable.
+
+Note that Common Lisp is case-converting, and that the `symbol-name` of your symbols will be upper case. Because of this case-converting, attempts to distinguish symbols by case are defeated, and only result in confusion. While it is possible to escape characters in symbols to force lower case, you should not use this capability unless this is somehow necessary to interoperate with third-party software.
+
+Place hyphens between all the words in a symbol. If you can't easily say an identifier out loud, it is probably badly named.
+
+You must not use `"/"` or `"."` instead of `"-"` unless you have a well-documented overarching reason to, and permission from other hackers who review your proposal.
+
+See the section on link:#spelling-and-abbreviations[Spelling and Abbreviations] for guidelines on using abbreviations.
+
+---------------------------------
+;; Bad
+(defvar *default-username* "Ann")
+(defvar *max-widget-cnt* 200)
+---------------------------------
+
+-----------------------------------
+;; Better
+(defvar *default-user-name* "Ann")
+(defvar *maximum-widget-count* 200)
+-----------------------------------
+
+There are conventions in Common Lisp for the use of punctuation in symbols. You should not use punctuation in symbols outside these conventions.
+
+Unless the scope of a variable is very small, do not use overly short names like `i` and `zq`.
+
+=== Denote intent, not content
+
+link:?showone=Denote_intent,_not_content#Denote_intent,_not_content[link]▶
+
+Name your variables according to their intent, not their content.
+
+You should name a variable according to the high-level concept that it represents, not according to the low-level implementation details of how the concept is represented.
+
+Thus, you should avoid embedding data structure or aggregate type names, such as `list`, `array`, or `hash-table` inside variable names, unless you're writing a generic algorithm that applies to arbitrary lists, arrays, hash-tables, etc. In that case it's perfectly OK to name a variable `list` or `array`.
+
+Indeed, you should be introducing new abstract data types with `DEFCLASS` or `DEFTYPE`, whenever a new kind of intent appears for objects in your protocols. Functions that manipulate such objects generically may then use variables the name of which reflect that abstract type.
+
+For example, if a variable's value is always a row (or is either a row or `NIL`), it's good to call it `row` or `first-row` or something like that. It is alright is `row` has been `DEFTYPE`'d to `STRING` — precisely because you have abstracted the detail away, and the remaining salient point is that it is a row. You should not name the variable `STRING` in this context, except possibly in low-level functions that specifically manipulate the innards of rows to provide the suitable abstraction.
+
+Be consistent. If a variable is named `row` in one function, and its value is being passed to a second function, then call it `row` rather than, say, `value` (this was a real case).
+
+=== Global variables and constants
+
+link:?showone=Global_variables_and_constants#Global_variables_and_constants[link]▶
+
+Name globals according to convention.
+
+The names of global constants should start and end with plus characters.
+
+Global variable names should start and end with asterisks (also known in this context as earmuffs).
+
+In some projects, parameters that are not meant to be usually modified or bound under normal circumstances (but may be during experimentation or exceptional situations) should start (but do not end) with a dollar sign. If such a convention exists within your project, you should follow it consistently. Otherwise, you should avoid naming variables like this.
+
+Common Lisp does not have global lexical variables, so a naming convention is used to ensure that globals, which are dynamically bound, never have names that overlap with local variables. It is possible to fake global lexical variables with a differently named global variable and a `DEFINE-SYMBOL-MACRO`. You should not use this trick, unless you first publish a library that abstracts it away.
+
+-----------------------------------------------
+(defconstant +hash-results+ #xbd49d10d10cbee50)
+
+(defvar *maximum-search-depth* 100)
+-----------------------------------------------
+
+=== Predicate names
+
+link:?showone=Predicate_names#Predicate_names[link]▶
+
+Names of predicate functions and variables end with a `"P"`.
+
+You should name boolean-valued functions and variables with a trailing `"P"` or `"-P"`, to indicate they are predicates. Generally, you should use `"P"` when the rest of the function name is one word and `"-P"` when it is more than one word.
+
+A rationale for this convention is given in http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node69.html[the CLtL2 chapter on predicates].
+
+For uniformity, you should follow the convention above, and not one of the alternatives below.
+
+An alternative rule used in some existing packages is to always use `"-P"`. Another alternative rule used in some existing packages is to always use `"?"`. When you develop such a package, you must be consistent with the rest of the package. When you start a new package, you should not use such an alternative rule without a very good documented reason.
+
+=== Omit library prefixes
+
+link:?showone=Omit_library_prefixes#Omit_library_prefixes[link]▶
+
+You should not include a library or package name as a prefix within the name of symbols.
+
+When naming a symbol (external or internal) in a package, you should not include the package name as a prefix within the name of the symbol. Naming a symbol this way makes it awkward to use from a client package accessing the symbol by qualifying it with a package prefix, where the package name then appears twice (once as a package prefix, another time as a prefix within the symbol name).
+
+---------------------------------------------------------
+;; Bad
+(in-package #:varint)
+(defun varint-length64 () ... )
+
+(in-package #:client-code)
+(defconst +padding+ (varint:varint-length64 +end-token+))
+---------------------------------------------------------
+
+--------------------------------------------------
+;; Better
+(in-package #:varint)
+(defun length64 () ... )
+
+(in-package #:client-code)
+(defconst +padding+ (varint:length64 +end-token+))
+--------------------------------------------------
+
+An exception to the above rule would be to include a prefix for the names of variables that would otherwise be expected to clash with variables in packages that use the current one. For instance, `ASDF` exports a variable `*ASDF-VERBOSE*` that controls the verbosity of `ASDF` only, rather than of the entire Lisp program.
+
+=== Packages
+
+link:?showone=Packages#Packages[link]▶
+
+Use packages appropriately.
+
+Lisp packages are used to demarcate namespaces. Usually, each system has its own namespace. A package has a set of external symbols, which are intended to be used from outside the package, in order to allow other modules to use this module's facilities.
+
+The internal symbols of a package should never be referred to from other packages. That is, you should never have to use the double-colon `::` construct. (e.g. `QUAKE::HIDDEN-FUNCTION`). If you need to use double-colons to write real production code, something is wrong and needs to be fixed.
+
+As an exception, unit tests may use the internals of the package being tested. So when you refactor, watch out for internals used by the package's unit tests.
+
+The `::` construct is also useful for very temporary hacks, and at the REPL. But if the symbol really is part of the externally-visible definition of the package, export it.
+
+You may find that some internal symbols represent concepts you usually want to abstract away and hide under the hood, yet at times are necessary to expose for various extensions. For the former reason, you do not want to export them, yet for the latter reason, you have to export them. The solution is to have two different packages, one for your normal users to use, and another for the implementation and its extenders to use.
+
+Each package is one of two types:
+
+
+* Intended to be included in the `:use` specification of other packages. If package `A` "uses" package `B`, then the external symbols of package `B` can be referenced from within package `A` without a package prefix. We mainly use this for low-level modules that provide widely-used facilities.
+
+* Not intended to be "used". To reference a facility provided by package `B`, code in package `A` must use an explicit package prefix, e.g. `B:DO-THIS`.
+
+If you add a new package, it should always be of the second type, unless you have a special reason and get permission. Usually a package is designed to be one or the other, by virtue of the names of the functions. For example, if you have an abstraction called `FIFO`, and it were in a package of the first type you'd have functions named things like `FIFO-ADD-TO` and `FIFO-CLEAR-ALL`. If you used a package of the second type, you'd have names like `ADD-TO` and `CLEAR-ALL`, because the callers would be saying `FIFO:ADD-TO` and `FIFO:CLEAR-ALL`. (`FIFO:FIFO-CLEAR-ALL` is redundant and ugly.)
+
+Another good thing about packages is that your symbol names won't "collide" with the names of other packages, except the ones your packages "uses". So you have to stay away from symbols that are part of the Lisp implementation (since you always "use" that) and that are part of any other packages you "use", but otherwise you are free to make up your own names, even short ones, and not worry about some else having used the same name. You're isolated from each other.
+
+Your package must not shadow (and thus effectively redefine) symbols that are part of the Common Lisp language. There are certain exceptions, but they should be very well-justified and extremely rare:
+
+
+* If you are explicitly replacing a Common Lisp symbol by a safer or more featureful version.
+
+* If you are defining a package not meant to be "used", and have a good reason to export a symbol that clashes with Common Lisp, such as `log:error` and `log:warn` and so on.
+
+[[Language_usage_guidelines]]
+== Language usage guidelines
+
+=== Mostly Functional Style
+
+link:?showone=Mostly_Functional_Style#Mostly_Functional_Style[link]▶
+
+You should avoid side-effects when they are not necessary.
+
+Lisp is best used as a "mostly functional" language.
+
+Avoid modifying local variables, try rebinding instead.
+
+Avoid creating objects and the SETFing their slots. It's better to set the slots during initialization.
+
+Make classes as immutable as possible, that is, avoid giving slots setter functions if at all possible.
+
+Using a mostly functional style makes it much easier to write concurrent code that is thread-safe. It also makes it easier to test the code.
+
+=== Recursion
+
+link:?showone=Recursion#Recursion[link]▶
+
+You should favor iteration over recursion.
+
+Common Lisp systems are not required to implement function calls from tail positions without leaking stack space — which is known as proper tail calls (PTC), tail call elimination (TCE), or tail call optimization (TCO). This means that indefinite recursion through tail calls may quickly blow out the stack, which hampers functional programming. Still, most serious implementations (including SBCL and CCL) do implement proper tail calls, but with restrictions:
+
+
+* The `(DECLARE (OPTIMIZE ...))` settings must favor `SPEED` enough and not favor `DEBUG` too much, for some compiler-dependent meanings of "enough" and "too much". (For instance, in SBCL, you should avoid `(SPEED 0)` and `(DEBUG 3)` to achieve proper tail calls.)
+
+* There should not be dynamic bindings around the call (even though some Scheme compilers are able to properly treat such dynamic bindings, called parameters in Scheme parlance).
+
+For compatibility with all compilers and optimization settings, and to avoid stack overflow when debugging, you should prefer iteration or the built in mapping functions to relying on proper tail calls.
+
+If you do rely on proper tail calls, you must prominently document the fact, and take appropriate measures to ensure an appropriate compiler is used with appropriate optimization settings. For fully portable code, you may have to use trampolines instead.
+
+=== Special variables
+
+link:?showone=Special_variables#Special_variables[link]▶
+
+Use special variables sparingly.
+
+Using Lisp "special" (dynamically bound) variables as implicit arguments to functions should be used sparingly, and only in cases where it won't surprise the person reading the code, and where it offers significant benefits.
+
+Indeed, each special variable constitutes state. Developers have to mentally track the state of all relevant variables when trying to understand what the code does and how it does it; tests have to be written and run with all relevant combinations; to isolate some activity, care has to be taken to locally bind all relevant variables, including those of indirectly used modules. They can hide precious information from being printed in a backtrace. Not only is there overhead associated to each new variable, but interactions between variables can make the code exponentially more complex as the number of such variables increases. The benefits have to match the costs.
+
+Note though that a Lisp special variable is not a global variable in the sense of a global variable in, say, BASIC or C. As special variables can be dynamically bound to a local value, they are much more powerful than global value cells where all users necessarily interfere with each other.
+
+Good candidates for such special variables are items for which "the current" can be naturally used as prefix, such as "the current database connection" or "the current business data source". They are singletons as far as the rest of the code is concerned, and often passing them as an explicit argument does not add anything to the readability or maintainability of the source code in question.
+
+They can make it easier to write code that can be refactored. If you have a request processing chain, with a number of layers that all operate upon a "current" request, passing the request object explicitly to every function requires that every function in the chain have a request argument. Factoring out code into new functions often requires that these functions also have this argument, which clutters the code with boilerplate.
+
+You should treat special variables as though they are per-thread variables. By default, you should leave a special variable with no top-level binding at all, and each thread of control that needs the variable should bind it explicitly. This will mean that any incorrect use of the variable will result in an "unbound variable" error, and each thread will see its own value for the variable. Variables with a default global value should usually be locally bound at thread creation time. You should use suitable infrastructure to automate the appropriate declaration of such variables.
+
+=== Assignment
+
+link:?showone=Assignment#Assignment[link]▶
+
+Be consistent in assignment forms.
+
+There are several styles for dealing with assignment and side-effects; whichever a given package is using, keep using the same consistently when hacking said package. Pick a style that makes sense when starting a new package.
+
+Regarding multiple assignment in a same form, there are two schools: the first style groups as many assignments as possible into a single `SETF` or `PSETF` form thus minimizing the number of forms with side-effects; the second style splits assignments into as many individual `SETF` (or `SETQ`, see below) forms as possible, to maximize the chances of locating forms that modify a kind of place by grepping for `(setf (foo ...`. A grep pattern must actually contain as many place-modifying forms as you may use in your programs, which may make this rationale either convincing or moot depending on the rest of the style of your code. You should follow the convention used in the package you are hacking. We recommend the first convention for new packages.
+
+Regarding `SETF` and `SETQ`, there are two schools: this first regards `SETQ` as an archaic implementation detail, and avoids it entirely in favor of `SETF`; the second regards `SETF` as an additional layer of complexity, and avoids it in favor of `SETQ` whenever possible (i.e. whenever the assigned place is a variable or symbol-macro). You should follow the convention used in the package you are hacking. We recommend the first convention for new packages.
+
+In the spirit of a mostly pure functional style, which makes testing and maintenance easier, we invite you to consider how to do things with the fewest assignments required.
+
+=== Assertions and Conditions
+
+link:?showone=Assertions_and_Conditions#Assertions_and_Conditions[link]▶
+
+You must make proper usage of assertions and conditions.
+
+
+* `ASSERT` should be used ONLY to detect internal bugs. Code should `ASSERT` invariants whose failure indicates that the software is itself broken. Incorrect input should be handled properly at runtime, and must not cause an assertion violation. The audience for an `ASSERT` failure is a developer. Do not use the data-form and argument-form in `ASSERT` to specify a condition to signal. It's fine to use them to print out a message for debugging purposes (and since it's only for debugging, there's no issue of internationalization).
+
+* `CHECK-TYPE`, `ETYPECASE` are also forms of assertion. When one of these fails, that's a detected bug. You should prefer to use `CHECK-TYPE` over (DECLARE (TYPE ...)) for the inputs of functions.
+
+* Your code should use assertions and type checks liberally. The sooner a bug is discovered, the better! Only code in the critical path for performance and internal helpers should eschew explicit assertions and type checks.
+
+* Invalid input, such as files that are read but do not conform to the expected format, should not be treated as assertion violations. Always check to make sure that input is valid, and take appropriate action if it is not, such as signalling a real error.
+
+* `ERROR` should be used to detect problems with user data, requests, permissions, etc., or to report "unusual outcomes" to the caller.
+
+* `ERROR` should always be called with an explicit condition type; it should never simply be called with a string. This enables internationalization.
+
+* Functions that report unusual outcomes by signaling a condition should say so explicitly in their contracts (their textual descriptions, in documentation and docstrings etc.). When a function signals a condition that is not specified by its contract, that's a bug. The contract should specify the condition class(es) clearly. The function may then signal any condition that is a type-of any of those conditions. That is, signaling instances of subclasses of the documented condition classes is fine.
+
+* Complex bug-checks may need to use `ERROR` instead of `ASSERT`.
+
+* When writing a server, you must not call `WARN`. Instead, you should use the appropriate logging framework.
+
+* Code must not call `SIGNAL`. Instead, use `ERROR` or `ASSERT`.
+
+* Code should not use `THROW` and `CATCH`; instead use the `restart` facility.
+
+* Code should not generically handle all conditions, e.g. type `T`, or use `IGNORE-ERRORS`. Instead, let unknown conditions propagate to the standard ultimate handler for processing.
+
+* There are a few places where handling all conditions is appropriate, but they are rare. The problem is that handling all conditions can mask program bugs. If you _do_ need to handle "all conditions", you MUST handle only `ERROR`, _not_ `T` and not `SERIOUS-CONDITION`. (This is notably because CCL's process shutdown depends on being able to signal `process-reset` and have it handled by CCL's handler, so we must not interpose our own handler.)
+
+* `(error (make-condition 'foo-error ...))` is equivalent to `(error 'foo-error ...)` — code must use the shorter form.
+
+* Code should not signal conditions from inside the cleanup form of `UNWIND-PROTECT` (unless they are always handled inside the cleanup form), or otherwise do non-local exits from cleanup handlers outside of the handler e.g. `INVOKE-RESTART`.
+
+* Do not clean up by resignaling. If you do that, and the condition is not handled, the stack trace will halt at the point of the resignal, hiding the rest. And the rest is the part we really care about!
++
+-------------------------
+;; Bad
+(handler-case
+ (catch 'ticket-at
+ (etd-process-blocks))
+ (error (c)
+ (reset-parser-values)
+ (error c)))
+-------------------------
++
+-------------------------
+;; Better
+(unwind-protect
+ (catch 'ticket-at
+ (etd-process-blocks))
+ (reset-parser-values))
+-------------------------
+
+=== Type Checking
+
+link:?showone=Type_Checking#Type_Checking[link]▶
+
+If you know the type of something, you should make it explicit in order to enable compile-time and run-time sanity-checking.
+
+If your function is using a special variable as an implicit argument, it's good to put in a `CHECK-TYPE` for the special variable, for two reasons: to clue in the person reading the code that this variable is being used implicitly as an argument, and also to help detect bugs.
+
+Using `(declare (type ...))` is the least-desirable mechanism to use because, as Scott McKay puts it:
+
+_________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+The fact is, `(declare (type ...))` does different things depending on the compiler settings of speed, safety, etc. In some compilers, when speed is greater than safety, `(declare (type ...))` will tell the compiler "please assume that these variables have these types" _without_ generating any type-checks. That is, if some variable has the value `1432` in it, and you declare it to be of type `string`, the compiler might just go ahead and use it as though it's a string.
+
+Moral: don't use `(declare (type ...))` to declare the contract of any API functions, it's not the right thing. Sure, use it for "helper" functions, but not API functions.
+_________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
+
+You should, of course, use appropriate declarations in internal low-level functions where these declarations are used for optimization. When you do, however, see our recommendations for link:#unsafe-operations[Unsafe Operations].
+
+=== CLOS
+
+link:?showone=CLOS#CLOS[link]▶
+
+Use CLOS appropriately.
+
+When a generic function is intended to be called from other modules (other parts of the code), there should be an explicit `DEFGENERIC` form, with a `:DOCUMENTATION` string explaining the generic contract of the function (as opposed to its behavior for some specific class). It's generally good to do explicit `DEFGENERIC` forms, but for module entry points it is mandatory.
+
+When the argument list of a generic function includes `&KEY`, the `DEFGENERIC` should always explicitly list all of the keyword arguments that are acceptable, and explain what they mean. (Common Lisp does not require this, but it is good form, and it may avoid spurious warnings on SBCL.)
+
+You should avoid `SLOT-VALUE` and `WITH-SLOTS`, unless you absolutely intend to circumvent any sort of method combination that might be in effect for the slot. Rare exceptions include `INITIALIZE-INSTANCE` and `PRINT-OBJECT` methods and accessing normally hidden slots in the low-level implementation of methods that provide user-visible abstractions. Otherwise, you should use accessors, `WITH-ACCESSORS`
+
+Accessor names generally follow a convention of `-`, where a "protocol" in this case loosely indicates a set of functions with well-defined behavior.
+
+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 http://common-lisp.net/~frideau/lil-ilc2012/lil-ilc2012.html[Interface-Passing Style] 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.
+
+For example, if there were a notional protocol called is `pnr` with accessors `pnr-segments` and `pnr-passengers`, then the classes `air-pnr`, `hotel-pnr` and `car-pnr` could each reasonably implement methods for `pnr-segments` and `pnr-passengers` as accessors.
+
+By default, an abstract base class name is used as the notional protocol name, so accessor names default to `-`; while such names are thus quite prevalent, this form is neither required nor even preferred. In general, it contributes to "symbol bloat", and in many cases has led to a proliferation of "trampoline" methods.
+
+Accessors named `-of` should not be used.
+
+Explicit `DEFGENERIC` forms should be used when there are (or it is anticipated that there will be) more than one `DEFMETHOD` for that generic function. The reason is that the documentation for the generic function explains the abstract contract for the function, as opposed to explaining what an individual method does for some specific class(es).
+
+You must not use generic functions where there is no notional protocol. To put it more concretely, if you have more than one generic function that specializes its Nth argument, the specializing classes should all be descendants of a single class. Generic functions must not be used for "overloading", i.e. simply to use the same name for two entirely unrelated types.
+
+More precisely, it's not really whether they descend from a common superclass, but whether they obey the same "protocol". That is, the two classes should handle the same set of generic functions, as if there were an explicit `DEFGENERIC` for each method.
+
+Here's another way to put it. Suppose you have two classes, A and B, and a generic function F. There are two methods for F, which dispatch on an argument being of types A and B. Is it plausible that there might be a function call somewhere in the program that calls F, in which the argument might sometimes, at runtime, be of class A and other times be of class B? If not, you probably are overloading and should not be using a single generic function.
+
+We allow one exception to this rule: it's OK to do overloading if the corresponding argument "means" the same thing. Typically one overloading allows an X object, and the other allows the name of an X object, which might be a symbol or something.
+
+You must not use MOP "intercessory" operations at runtime. You should not use MOP "intercessory" operations at compile-time. At runtime, they are at worst a danger, at best a performance issue. At compile-time, it is usually cleaner that macros should set things up the right way in one pass than have to require a second pass of fixups through intercession; but sometimes, fixups are necessary to resolve forward references, and intercession is allowed then. MOP intercession is a great tool for interactive development, and you may enjoy it while developping and debugging; but you should not use it in normal applications.
+
+If a class definition creates a method as a `:READER`, `:WRITER`, or `:ACCESSOR`, do not redefine that method. It's OK to add `:BEFORE`, `:AFTER`, and `:AROUND` methods, but don't override the primary method.
+
+In methods with keyword arguments, you must always use `&KEY`, even if the method does not care about the values of any keys, and you should never use `&ALLOW-OTHER-KEYS`. As long as a keyword is accepted by any method of a generic function, it's OK to use it in the generic function, even if the other methods of the same generic function don't mention it explicitly. This is particularly important for `INITIALIZE-INSTANCE` methods, since if you did use `&ALLOW-OTHER-KEYS`, it would disable error checking for misspelled or wrong keywords in `MAKE-INSTANCE` calls!
+
+A typical `PRINT-OBJECT` method might look like this:
+
+----------------------------------------------------------
+(defmethod print-object ((p person) stream)
+ (print-unprintable-object (p stream :type t :identity t)
+ (with-slots (first-name last-name) p
+ (safe-format stream "~a ~a" first-name last-name))))
+----------------------------------------------------------
+
+[[Meta-language_guidelines]]
+== Meta-language guidelines
+
+=== Macros
+
+link:?showone=Macros#Macros[link]▶
+
+Use macros when appropriate, which is often. Define macros when appropriate, which is seldom.
+
+Macros bring syntactic abstraction, which is a wonderful thing. It helps make your code clearer, by describing your intent without getting bogged in implementation details (indeed abstracting those details away). It helps make your code more concise and more readable, by eliminating both redundancy and irrelevant details. But it comes at a cost to the reader, which is learning a new syntactic concept for each macro. And so it should not be abused.
+
+The general conclusion is that there shouldn't be any recognizable _design pattern_ in a good Common Lisp program. The one and only pattern is: __use the language__, which includes defining and using syntactic abstractions.
+
+Existing macros must be used whenever they make code clearer by conveying intent in a more concise way, which is often. When a macro is available in your project that expresses the concept you're using, you must not write the expansion rather than use the macro.
+
+New macros should be defined as appropriate, which should be seldom, for common macros have already been provided by the language and its various libraries, and your program typically only needs few new ones relative to its size.
+
+You should follow the OAOOM rule of thumb for deciding when to create a new abstraction, whether syntactic or not: if a particular pattern is used more than twice, it should probably be abstracted away. A more refined rule to decide when to use abstraction should take into account the benefit in term of number of uses and gain at each use, to the costs in term of having to get used to reading the code. For syntactic abstractions, costs and benefits to the reader is usually more important than costs and benefits to the writer, because good code is usually written once and read many times by many people (including the same programmer who has to maintain the program after having forgotten it). Yet the cost to the writer of the macro should also be taken into account; however, in doing so it should rather be compared to the cost of the programmer writing other code instead that may have higher benefits.
+
+Using Lisp macros properly requires taste. Avoid writing complicated macros unless the benefit clearly outweighs the cost. It takes more effort for your fellow developers to learn your macro, so you should only use a macro if the gain in expressiveness is big enough to justify that cost. As usual, feel free to consult your colleagues if you're not sure, since without a lot of Lisp experience, it can be hard to make this judgment.
+
+You must never use a macro where a function will do. That is, if the semantics of what you are writing conforms to the semantics of a function, then you must write it as a function rather than a macro.
+
+You must not transform a function into a macro for performance reasons. If profiling shows that you have a performance problem with a specific function `FOO`, document the need and profiling-results appropriately, and `(declaim (inline foo))`.
+
+You can also use a compiler-macro as a way to speed up function execution by specifying a source-to-source transformation. Beware that it interferes with tracing the optimized function.
+
+When you write a macro-defining macro (a macro that generates macros), document and comment it particularly clearly, since these are harder to understand.
+
+You must not install new reader macros without a consensus among the developers of your system. Reader macros must not leak out of the system that uses them to clients of that system or other systems used in the same project. You must use software such as `cl-syntax` or `named-readtables` to control how reader macros are used. This clients who desire it may use the same reader macros as you do. In any case, your system must be usable even to clients who do not use these reader macros.
+
+If your macro has a parameter that is a Lisp form that will be evaluated when the expanded code is run, you should name the parameter with the suffix `-form`. This convention helps make it clearer to the macro's user which parameters are Lisp forms to be evaluated, and which are not. The common names `body` and `end` are exceptions to this rule.
+
+You should follow the so-called `CALL-WITH` style when it applies. This style is explained at length in http://random-state.net/log/3390120648.html. The general principle is that the macro is strictly limited to processing the syntax, and as much of the semantics as possible is kept in normal functions. Therefore, a macro `WITH-FOO` is often limited to generating a call to an auxiliary function `CALL-WITH-FOO` with arguments deduced from the macro arguments. Macro `&body` arguments are typically wrapped into a lambda expression of which they become the body, which is passed as one of the arguments of the auxiliary function.
+
+The separation of syntactic and semantic concerns is a general principle of style that applies beyond the case of `WITH-` macros. Its advantages are many. By keeping semantics outside the macro, the macro is made simpler, easier to get right, and less subject to change, which makes it easier to develop and maintain. The semantics is written in a simpler language — one without staging — which also makes it easier to develop and maintain. It becomes possible to debug and update the semantic function without having to recompile all clients of the macro. The semantic function appears in the stack trace which also helps debug client functions. The macro expansion is made shorter and each expansion shares more code with other expansions, which reduces memory pressure which in turn usually makes things faster. It also makes sense to write the semantic functions first, and write the macros last as syntactic sugar on top. You should use this style unless the macro is used in tight loops where performance matters; and even then, see our rules regarding optimization.
+
+Any functions (closures) created by the macro should be named, which can be done using `FLET`. This also allows you to declare the function to be of dynamic extent (if it is — and often it is; yet see below regarding link:#DYNAMIC-EXTENT[DYNAMIC-EXTENT]).
+
+If a macro call contains a form, and the macro expansion includes more than one copy of that form, the form can be evaluated more than once, and code it contains macro-expanded and compiled more than once. If someone uses the macro and calls it with a form that has side effects or that takes a long time to compute, the behavior will be undesirable (unless you're intentionally writing a control structure such as a loop). A convenient way to avoid this problem is to evaluate the form only once, and bind a (generated) variable to the result. There is a very useful macro called `ALEXANDRIA:ONCE-ONLY` that generates code to do this. See also `ALEXANDRIA:WITH-GENSYMS`, to make some temporary variables in the generated code. Note that if you follow our `CALL-WITH` style, you typically expand the code only once, as either an argument to the auxiliary function, or the body of a lambda passed as argument to it; you therefore avoid the above complexity.
+
+When you write a macro with a body, such as a `WITH-xxx` macro, even if there aren't any parameters, you should leave space for them anyway. For example, if you invent `WITH-LIGHTS-ON`, do not make the call to it look like `(defmacro with-lights-on (&body b) ...)`. Instead, do `(defmacro with-lights-on (() &body b) ...)`. That way, if parameters are needed in the future, you can add them without necessarily having to change all the uses of the macro.
+
+=== EVAL-WHEN
+
+link:?showone=EVAL-WHEN#EVAL-WHEN[link]▶
+
+When using `EVAL-WHEN`, you should almost always use all of `(:compile-toplevel :load-toplevel :execute)`.
+
+Lisp evaluation happens at several times, some of them interleaved. Be aware of them when writing macros. http://fare.livejournal.com/146698.html[EVAL-WHEN considered harmful to your mental health].
+
+In summary of the article linked above, unless you're doing truly advanced macrology, the only valid combination in an `EVAL-WHEN` is to include all of `(eval-when (:compile-toplevel :load-toplevel :execute) ...)`
+
+You must use `(eval-when (:compile-toplevel :load-toplevel :execute) ...)` whenever you define functions, types, classes, constants, variables, etc., that are going to be used in macros.
+
+It is usually an error to omit the `:execute`, because it prevents `LOAD`ing the source rather than the fasl. It is usually an error to omit the `:load-toplevel` (except to modify e.g. readtables and compile-time settings), because it prevents `LOAD`ing future files or interactively compiling code that depends on the effects that happen at compile-time, unless the current file was `COMPILE-FILE`d within the same Lisp session.
+
+Regarding variables, note that because macros may or may not be expanded in the same process that runs the expanded code, you must not depend on compile-time and runtime effects being either visible or invisible at the other time. There are still valid uses of variables in macros:
+
+
+* Some variables may hold dictionaries for some new kind of definition and other meta-data. If such meta-data is to be visible at runtime and/or in other files, you must make sure that the macro expands into code that will register the definitions to those meta-data structures at load-time, in addition to effecting the registration at compile-time. Typically, your top-level definitions expand to code that does the registration. if your code doesn't expand at the top-level, you can sometimes use `LOAD-TIME-VALUE` for good effect. In extreme cases, you may have to use `ASDF-FINALIZERS:EVAL-AT-TOPLEVEL`.
+
+* Some variables may hold temporary data that is only used at compile-time in the same file, and can be cleaned up at the end of the file's compilation. Predefined such variables would include `*readtable*` or compiler-internal variables holding the current optimization settings. You can often manage existing and new such variables using the `:AROUND-COMPILE` hooks of `ASDF`.
+
+=== Read-time evaluation
+
+link:?showone=Read-time_evaluation#Read-time_evaluation[link]▶
+
+You should use `#.` sparingly, and you must avoid read-time side-effects.
+
+The `#.` standard read-macro will read one object, evaluate the object, and have the reader return the resulting value.
+
+You must not use it where other idioms will do, such as using `EVAL-WHEN` to evaluate side-effects at compile-time, using a regular macro to return an expression computed at compile-time, using `LOAD-TIME-VALUE` to compute it at load-time.
+
+Read-time evaluation is often used as a quick way to get something evaluated at compile time (actually "read time" but it amounts to the same thing). If you use this, the evaluation MUST NOT have any side effects and MUST NOT depend on any variable global state. The `#.` should be treated as a way to force "constant-folding" that a sufficiently-clever compiler could have figure out all by itself, when the compiler isn't sufficiently-clever and the difference matters.
+
+Another use of `#.` is to expand the equivalent of macros in places that are neither expressions nor (quasi)quotations, such as lambda-lists. However, if you find yourself using it a lot, it might be time to instead define macros to replace your consumers of lambda-lists with something that recognizes an extension.
+
+Whenever you are going to use `#.`, you should consider using `DEFCONSTANT` and its variants, possibly in an `EVAL-WHEN`, to give the value a name explaining what it means.
+
+=== EVAL
+
+link:?showone=EVAL#EVAL[link]▶
+
+You must not use `EVAL` at runtime.
+
+Places where it is actually appropriate to use `EVAL` are so few and far between that you must consult with your reviewers; it's easily misused.
+
+If your code manipulates symbols at runtime and needs to get the value of a symbol, use `SYMBOL-VALUE`, not `EVAL`.
+
+Often, what you really need is to write a macro, not to use `EVAL`.
+
+You may be tempted to use `EVAL` as a shortcut to evaluating expressions in a safe subset of the language. But it often requires more scrutiny to properly check and sanitize all possible inputs to such use of `EVAL` than to build a special-purpose evaluator. You must not use `EVAL` in this way at runtime.
+
+Places where it is OK to use `EVAL` are:
+
+
+* The implementation of an interactive development tool.
+
+* The build infrastructure.
+
+* Backdoors that are part of testing frameworks. (You MUST NOT have such backdoors in production code.)
+
+* Macros that fold constants at compile-time.
+
+* Macros that register definitions to meta-data structures; the registration form is sometimes evaluated at compile-time as well as included in the macro-expansion, so it is immediately available to other macros.
+
+Note that in the latter case, if the macro isn't going to be used at the top-level, it might not be possible to make these definitions available as part of the expansion. The same phenomenon may happen in a `DEFTYPE` expansion, or in helper functions used by macros. In these cases, you may actually have to use `ASDF-FINALIZERS:EVAL-AT-TOPLEVEL` in your macro. It will not only `EVAL` your definitions at macro-expansion time for immediate availability, it will also save the form aside, for inclusion in a `(ASDF-FINALIZERS:FINAL-FORMS)` that you need to include at the end of the file being compiled (or before the form is needed). This way, the side-effects are present when loading the fasl without having compiled it as well as while compiling it; in either case, the form is made available at load-time. `ASDF-FINALIZERS` ensures that the form is present, by throwing an error if you omit it.
+
+=== INTERN and UNINTERN
+
+link:?showone=INTERN_and_UNINTERN#INTERN_and_UNINTERN[link]▶
+
+You must not use `INTERN` or `UNINTERN` at runtime.
+
+You must not use `INTERN` at runtime. Not only does it cons, it either creates a permanent symbol that won't be collected or gives access to internal symbols. This creates opportunities for memory leaks, denial of service attacks, unauthorized access to internals, clashes with other symbols.
+
+You must not `INTERN` a string just to compare it to a keyword; use `STRING=` or `STRING-EQUAL`.
+
+------------------------------------------
+(member (intern str :keyword) $keys) ; Bad
+------------------------------------------
+
+------------------------------------------------
+(member str $keys :test #'string-equal) ; Better
+------------------------------------------------
+
+You must not use `UNINTERN` at runtime. It can break code that relies on dynamic binding. It makes things harder to debug. You must not dynamically intern any new symbol, and therefore you need not dynamically unintern anything.
+
+You may of course use `INTERN` at compile-time, in the implementation of some macros. Even so, it is usually more appropriate to use abstractions on top of it, such as `ALEXANDRIA:SYMBOLICATE` or `ALEXANDRIA:FORMAT-SYMBOL` to create the symbols you need.
+
+[[Data_Representation]]
+== Data Representation
+
+=== NIL: empty-list, false and I Don't Know
+
+?showone=NIL:_empty-list,_false_and_I_Don_t_Know#NIL:_empty-list,_false_and_I_Don_t_Know[link]▶
+
+Appropriately use or avoid using `NIL`.
+
+`NIL` can have several different interpretations:
+
+
+* "False." In this case, use `NIL`. You should test for false `NIL` using the operator `NOT` or using the predicate function `NULL`.
+
+* "Empty-list." In this case, use `'()`. (Be careful about quoting the empty-list when calling macros.) You should use `ENDP` to test for the empty list when the argument is known to be a proper list, or with `NULL` otherwise.
+
+* A statement about some value being unspecified. In this case, you may use `NIL` if there is no risk of ambiguity anywhere in your code; otherwise you should use an explicit, descriptive symbol.
+
+* A statement about some value being known not to exist. In this case, you should use an explicit, descriptive symbol instead of `NIL`.
+
+You must not introduce ambiguity in your data representations that will cause headaches for whoever has to debug code. If there is any risk of ambiguity, you should use an explicit, descriptive symbol or keyword for each case, instead of using `NIL` for either. If you do use `NIL`, you must make sure that the distinction is well documented.
+
+In many contexts, instead of representing "I don't know" as a particular value, you should instead use multiple values, one for the value that is known if any, and one to denote whether the value was known or found.
+
+When working with database classes, keep in mind that `NIL` need not always map to `'NULL'` (and vice-versa)! The needs of the database may differ from the needs of the Lisp.
+
+=== Do not abuse lists
+
+link:?showone=Do_not_abuse_lists#Do_not_abuse_lists[link]▶
+
+You must select proper data representation. You must not abuse the `LIST` data structure.
+
+Even though back in 1958, LISP was short for "LISt Processing", its successor Common Lisp has been a modern programming language with modern data structures since the 1980s. You must use the proper data structures in your programs.
+
+You must not abuse the builtin (single-linked) `LIST` data structure where it is not appropriate, even though Common Lisp makes it especially easy to use it.
+
+You must only use lists when their performance characteristics is appropriate for the algorithm at hand: sequential iteration over the entire contents of the list.
+
+An exception where it is appropriate to use lists is when it is known in advance that the size of the list will remain very short (say, less than 16 elements).
+
+List data structures are often (but not always) appropriate for macros and functions used by macros at compile-time: indeed, not only is source code passed as lists in Common Lisp, but the macro-expansion and compilation processes will typically walk over the entire source code, sequentially, once. (Note that advanced macro systems don't directly use lists, but instead use abstract syntax objects that track source code location and scope; however there is no such advanced macro system in Common Lisp at this time.)
+
+Another exception where it is appropriate to use lists is for introducing literal constants that will be transformed into more appropriate data structures at compile-time or load-time. It is a good to have a function with a relatively short name to build your program's data structures from such literals.
+
+In the many cases when lists are not the appropriate data structure, various libraries such as http://cliki.net/cl-containers[cl-containers] or http://cliki.net/lisp-interface-library[lisp-interface-library] provide plenty of different data structures that should fulfill all the basic needs of your programs. If the existing libraries are not satisfactory, see above about link:#using-libraries[Using Libraries] and link:#Open-Sourcing_Code[Open-Sourcing Code].
+
+=== Lists vs. structures vs. multiple values
+
+link:?showone=Lists_vs._structures_vs._multiple_values#Lists_vs._structures_vs._multiple_values[link]▶
+
+You should use the appropriate representation for product types.
+
+You should avoid using a list as anything besides a container of elements of like type. You must not use a list as method of passing multiple separate values of different types in and out of function calls. Sometimes it is convenient to use a list as a little ad hoc structure, i.e. "the first element of the list is a FOO, and the second is a BAR", but this should be used minimally since it gets harder to remember the little convention. You must only use a list that way when destructuring the list of arguments from a function, or creating a list of arguments to which to `APPLY` a function.
+
+The proper way to pass around an object comprising several values of heterogeneous types is to use a structure as defined by `DEFSTRUCT` or `DEFCLASS`.
+
+You should use multiple values only when function returns a small number of values that are meant to be destructured immediately by the caller, rather than passed together as arguments to further functions.
+
+You should not return a condition object as one of a set of multiple values. Instead, you should signal the condition to denote an unusual outcome.
+
+You should signal a condition to denote an unusual outcome, rather than relying on a special return type.
+
+=== Lists vs. Pairs
+
+link:?showone=Lists_vs._Pairs#Lists_vs._Pairs[link]▶
+
+Use the appropriate functions when manipulating lists.
+
+Use `FIRST` to access the first element of a list, `SECOND` to access the second element, etc. Use `REST` to access the tail of a list. Use `ENDP` to test for the end of the list.
+
+Use `CAR` and `CDR` when the cons cell is not being used to implement a proper list and is instead being treated as a pair of more general objects. Use `NULL` to test for `NIL` in this context.
+
+The latter case should be rare outside of alists, since you should be using structures and classes where they apply, and data structure libraries when you want trees.
+
+Exceptionally, you may use `CDADR` and other variants on lists when manually destructuring them, instead of using a combination of several list accessor functions. In this context, using `CAR` and `CDR` instead of `FIRST` and `REST` also makes sense. However, keep in mind that it might be more appropriate in such cases to use higher-level constructs such as `DESTRUCTURING-BIND` or `OPTIMA:MATCH`.
+
+=== Lists vs. Arrays
+
+link:?showone=Lists_vs._Arrays#Lists_vs._Arrays[link]▶
+
+You should use arrays rather than lists where random access matters.
+
+`ELT` has _O(n)_ behavior when used on lists. If you are to use random element access on an object, use arrays and `AREF` instead.
+
+The exception is for code outside the critical path where the list is known to be small anyway.
+
+=== Lists vs. Sets
+
+link:?showone=Lists_vs._Sets#Lists_vs._Sets[link]▶
+
+You should only use lists as sets for very small lists.
+
+Using lists as representations of sets is a bad idea unless you know the lists will be small, for accessors are _O(n)_ instead of __O(log n)__. For arbitrary big sets, use balanced binary trees, for instance using `lisp-interface-library`.
+
+If you still use lists as sets, you should not `UNION` lists just to search them.
+
+----------------------------------------
+(member foo (union list-1 list-2)) ; Bad
+----------------------------------------
+
+-----------------------------------------------------
+(or (member foo list-1) (member foo list-2)) ; Better
+-----------------------------------------------------
+
+Indeed, `UNION` not only conses unnecessarily, but it can be _O(n^2)_ on some implementations, and is rather slow even when it's __O(n)__.
+
+[[Proper_Forms]]
+== Proper Forms
+
+You must follow the proper usage regarding well-known functions, macros and special forms.
+
+=== Defining Constants
+
+link:?showone=Defining_Constants#Defining_Constants[link]▶
+
+You must use proper defining forms for constant values.
+
+The Lisp system we primarily use, SBCL, is very picky and signals a condition whenever a constant is redefined to a value not `EQL` to its previous setting. You must not use `DEFCONSTANT` when defining variables that are not numbers, characters, or symbols (including booleans and keywords). Instead, consistently use whichever alternative is recommended for your project.
+
+---------------------------------------------------
+;; Bad
+(defconstant +google-url+ "http://www.google.com/")
+(defconstant +valid-colors+ '(red green blue))
+---------------------------------------------------
+
+Open-Source libraries may use `ALEXANDRIA:DEFINE-CONSTANT` for constants other than numbers, characters and symbols (including booleans and keywords). You may use the `:TEST` keyword argument to specify an equality predicate.
+
+-----------------------------------------------------------------------
+;; Better, for Open-Source code:
+(define-constant +google-url+ "http://www.google.com/" :test #'string=)
+(define-constant +valid-colors+ '(red green blue))
+-----------------------------------------------------------------------
+
+Note that with optimizing implementations, such as SBCL or CMUCL, defining constants this way precludes any later redefinition short of `UNINTERN`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 `DEFPARAMETER` or `DEFVAR` instead, or possibly a variant of `DEFINE-CONSTANT` that builds upon some future library implementing global lexicals rather than `DEFCONSTANT`. You may keep the `+plus+` convention in these cases to document the intent of the parameter as a constant.
+
+Also note that `LOAD-TIME-VALUE` may help you avoid the need for defined constants.
+
+=== Defining Functions
+
+link:?showone=Defining_Functions#Defining_Functions[link]▶
+
+You should make proper use of `&OPTIONAL` and `&KEY` arguments. You should not use `&AUX` arguments.
+
+You should avoid using `&ALLOW-OTHER-KEYS`, since it blurs the contract of a function. Almost any real function (generic or not) allows a certain fixed set of keywords, as far as its caller is concerned, and those are part of its contract. If you are implementing a method of a generic function, and it does not need to know the values of some of the keyword arguments, you should explicitly `(DECLARE (IGNORE ...))` all the arguments that you are not using. You must not use `&ALLOW-OTHER-KEYS` unless you explicitly want to disable checking of allowed keys for all methods when invoking the generic function on arguments that match this particular method. Note that the contract of a generic function belongs in the `DEFGENERIC`, not in the `DEFMETHOD` which is basically an "implementation detail" of the generic function as far as the caller of the generic is concerned.
+
+A case where `&ALLOW-OTHER-KEYS` is appropriate is when you write a wrapper function to other some other functions that may vary (within the computation or during development), and pass around a plist as a `&REST` argument.
+
+You should avoid using `&AUX` arguments.
+
+You should avoid having both `&OPTIONAL` and `&KEY` arguments, unless it never makes sense to specify keyword arguments when the optional arguments are not all specified. You must not have non-`NIL` defaults to your `&OPTIONAL` arguments when your function has both `&OPTIONAL` and `&KEY` arguments.
+
+For maximum portability of a library, it is good form that `DEFMETHOD` definitions should `(DECLARE (IGNORABLE ...))` all the required arguments that they are not using. Indeed, some implementations will issue a warning if you `(DECLARE (IGNORE ...))` those arguments, whereas other implementations will issue a warning if you fail to `(DECLARE (IGNORE ...))` them. `(DECLARE (IGNORABLE ...))` works on all implementations.
+
+You should avoid excessive nesting of binding forms inside a function. If your function ends up with massive nesting, you should probably break it up into several functions or macros. If it is really a single conceptual unit, consider using a macro such as `FARE-UTILS:NEST` to at least reduce the amount of indentation required. It is bad form to use `NEST` in typical short functions with 4 or fewer levels of nesting, but also bad form not to use it in the exceptional long functions with 10 or more levels of nesting. Use your judgment and consult your reviewers.
+
+=== Conditional Expressions
+
+link:?showone=Conditional_Expressions#Conditional_Expressions[link]▶
+
+Use the appropriate conditional form.
+
+Use `WHEN` and `UNLESS` when there is only one alternative. Use `IF` when there are two alternatives and `COND` when there are several.
+
+However, don't use `PROGN` for an `IF` clause — use `COND`, `WHEN`, or `UNLESS`.
+
+Note that in Common Lisp, `WHEN` and `UNLESS` return `NIL` when the condition is not met. You may take advantage of it. Nevertheless, you may use an `IF` to explicitly return `NIL` if you have a specific reason to insist on the return value. You may similarly include a fall-through clause `(t nil)` as the last in your COND, or `(otherwise nil)` as the last in your CASE, to insist on the fact that the value returned by the conditional matters and that such a case is going to be used. You should omit the fall-through clause when the conditional is used for side-effects.
+
+You should prefer `AND` and `OR` when it leads to more concise code than using `IF`, `COND`, `WHEN` or `UNLESS`, and there are no side-effects involved. You may also use an `ERROR` as a side-effect in the final clause of an `OR`.
+
+You should only use `CASE` and `ECASE` to compare numbers, characters or symbols (including booleans and keywords). Indeed, `CASE` uses `EQL` for comparisons, so strings, pathnames and structures may not compare the way you expect, and `1` will differ from `1.0`.
+
+You should use `ECASE` and `ETYPECASE` in preference to `CASE` and `TYPECASE`. It is better to catch erroneous values early.
+
+You should not use `CCASE` or `CTYPECASE` at all. At least, you should not use them in server processes, unless you have quite robust error handling infrastructure and make sure not to leak sensitive data this way. These are meant for interactive use, and can cause interesting damage if they cause data or control to leak to attackers.
+
+You must not use gratuitous single quotes in `CASE` forms. This is a common error:
+
+-----------------------------------------------
+(case x ; Bad: silently returns NIL on mismatch
+ ('bar :bar) ; Bad: catches QUOTE
+ ('baz :baz)) ; Bad: also would catch QUOTE
+-----------------------------------------------
+
+------------------------------------------
+(ecase x ; Better: will error on mismatch
+ ((bar) :bar) ; Better: won't match QUOTE
+ ((baz) :baz)) ; Better: same reason
+------------------------------------------
+
+`'BAR` there is `(QUOTE BAR)`, meaning this leg of the case will be executed if `X` is `QUOTE`... and ditto for the second leg (though `QUOTE` will be caught by the first clause). This is unlikely to be what you really want.
+
+In `CASE` forms, you must use `otherwise` instead of `t` when you mean "execute this clause if the others fail". You must use `((t) ...)` when you mean "match the symbol T" rather than "match anything". You must also use `((nil) ...)` when you mean "match the symbol NIL" rather than "match nothing".
+
+Therefore, if you want to map booleans `NIL` and `T` to respective symbols `:BAR` and `:QUUX`, you should avoid the former way and do it the latter way:
+
+-----------------------------------------
+(ecase x ; Bad: has no actual error case!
+ (nil :bar)) ; Bad: matches nothing
+ (t :quux)) ; Bad: matches anything
+-----------------------------------------
+
+---------------------------------------------------
+(ecase x ; Better: will actually catch non-booleans
+ ((nil) :bar)) ; Better: matches NIL
+ ((t) :quux)) ; Better: matches T
+---------------------------------------------------
+
+=== Identity, Equality and Comparisons
+
+link:?showone=Identity,_Equality_and_Comparisons#Identity,_Equality_and_Comparisons[link]▶
+
+You should the appropriate predicates when comparing objects.
+
+Lisp provides four general equality predicates: `EQ`, `EQL`, `EQUAL`, and `EQUALP`, which subtly vary in semantics. Additionally, Lisp provides the type-specific predicates `=`, `CHAR=`, `CHAR-EQUAL`, `STRING=`, and `STRING-EQUAL`. Know the distinction!
+
+You should use `EQL` to compare objects and symbols for __identity__.
+
+You must not use `EQ` to compare numbers or characters. Two numbers or characters that are `EQL` are not required by Common Lisp to be `EQ`.
+
+When choosing between `EQ` and `EQL`, you should use `EQL` unless you are writing performance-critical low-level code. `EQL` reduces the opportunity for a class of embarrassing errors (i.e. if numbers or characters are ever compared). There may a tiny performance cost relative to `EQ`, although under SBCL, it often compiles away entirely. `EQ` is equivalent to `EQL` and type declarations, and use of it for optimization should be treated just like any such link:#unsafe-operations[unsafe operations].
+
+You should use `CHAR=` for case-dependent character comparisons, and `CHAR-EQUAL` for case-ignoring character comparisons.
+
+You should use `STRING=` for case-dependent string comparisons, and `STRING-EQUAL` for case-ignoring string comparisons.
+
+A common mistake when using `SEARCH` on strings is to provide `STRING=` or `STRING-EQUAL` as the `:TEST` function. The `:TEST` function is given two sequence elements to compare. If the sequences are strings, the `:TEST` function is called on two characters, so the correct tests are `CHAR=` or `CHAR-EQUAL`. If you use `STRING=` or `STRING-EQUAL`, the result is what you expect, but in some Lisp implementations it's much slower. CCL (at least as of 8/2008) creates a one-character string upon each comparison, for example, which is very expensive.
+
+Also, you should use `:START` and `:END` arguments to `STRING=` or `STRING-EQUAL` instead of using `SUBSEQ`; e.g. `(string-equal (subseq s1 2 6) s2)` should instead be `(string-equal s1 s2 :start1 2 :end1 6)` This is preferable because it does not cons.
+
+You should use `ZEROP`, `PLUSP`, or `MINUSP`, instead of comparing a value to `0` or `0.0`.
+
+You must not use exact comparison on floating point numbers, since the vague nature of floating point arithmetic can produce little "errors" in numeric value. You should compare absolute values to a threshhold.
+
+You must use `=` to compare numbers, unless you really mean for `0`, `0.0` and `-0.0` to compare unequal, in which case you should use `EQL`. Then again, you must not usually use exact comparison on floating point numbers.
+
+Monetary amounts should be using decimal (rational) numbers to avoid the complexities and rounding errors of floating-point arithmetic. Libraries such as http://wukix.com/lisp-decimals[wu-decimal] may help you; once again, if this library is not satisfactory, see above about link:#using-libraries[Using Libraries] and link:#Open-Sourcing_Code[Open-Sourcing Code].
+
+=== Iteration
+
+link:?showone=Iteration#Iteration[link]▶
+
+Use the appropriate form for iteration.
+
+You should simpler forms such as `DOLIST` or `DOTIMES` instead of `LOOP` in simple cases when you're not going to use any of the `LOOP` facilities such as bindings, collection or block return.
+
+Use the `WITH` clause of `LOOP` when it will avoid a level of nesting with `LET`. You may use `LET` if it makes it clearer to return one of bound variables after the `LOOP`, rather than use a clumsy `FINALLY (RETURN ...)` form.
+
+In the body of a `DOTIMES`, do not set the iteration variable. (CCL will issue a compiler warning if you do.)
+
+Most systems use unadorned symbols in the current package as `LOOP` keywords. Other systems use actual `:keywords` from the `KEYWORD` package as `LOOP` keywords. You must be consistent with the convention used in your system.
+
+=== I/O
+
+link:?showone=I/O#I/O[link]▶
+
+Use the appropriate I/O functions.
+
+When writing a server, code must not send output to the standard streams such as `*STANDARD-OUTPUT*` or `*ERROR-OUTPUT*`. Instead, code must use the proper logging framework to output messages for debugging. We are running as a server, so there is no console!
+
+Code must not use `PRINT-OBJECT` to communicate with a user — `PRINT-OBJECT` is for debugging purposes only. Modifying any `PRINT-OBJECT` method must not break any public interfaces.
+
+You should not use a sequence of `WRITE-XXX` where a single `FORMAT` string could be used. Using format allows you to parameterize the format control string in the future if the need arises.
+
+You should use `WRITE-CHAR` to emit a character rather than `WRITE-STRING` to emit a single-character string.
+
+You should not use `(format nil "~A" value)`; you should use `PRINC-TO-STRING` instead.
+
+You should use `~` or `~@` in format strings to keep them from wrapping in 100-column editor windows, or to indent sections or clauses to make them more readable.
+
+You should not use `STRING-UPCASE` or `STRING-DOWNCASE` on format control parameters; instead, it should use `"~:@(~A~)"` or `"~(~A~)"`.
+
+Be careful when using the `FORMAT` conditional directive. The parameters are easy to forget.
+
+No parameters, e.g. `"~[Siamese~;Manx~;Persian~] Cat"` ::
+ Take one format argument, which should be an integer. Use it to choose a clause. Clause numbers are zero-based. If the number is out of range, just print nothing. You can provide a default value by putting a `":"` in front of the last `";"`. E.g. in `"~[Siamese~;Manx~;Persian~:;Alley~] Cat"`, an out-of-range arg prints `"Alley"`.
+ `:` parameter, e.g. `"~:[Siamese~;Manx~]"` ::
+ Take one format argument. If it's `NIL`, use the first clause, otherwise use the second clause.
+ `@` parameter, e.g. `"~@[Siamese ~a~]"` ::
+ If the next format argument is true, use the choice, but do NOT take the argument. If it's false, take one format argument and print nothing. (Normally the clause uses the format argument.)
+ `#` parameter, e.g. `"~#[ none~; ~s~; ~s and ~s~]"` ::
+ Use the number of arguments to format as the number to choose a clause. The same as no parameters in all other ways. Here's the full hairy example: `"Items:~#[ none~; ~S~; ~S and ~S~:;~@{~#[~; and~] ~S~^ ,~}~]."`
+
+[[Optimization]]
+== Optimization
+
+=== Avoid Allocation
+
+link:?showone=Avoid_Allocation#Avoid_Allocation[link]▶
+
+You should avoid unnecessary allocation of memory.
+
+In a language with automatic storage management (such as Lisp or Java), the colloquial phrase "memory leak" refers to situation where storage that is not actually needed nevertheless does not get deallocated, because it is still reachable.
+
+You should be careful that when you create objects, you don't leave them reachable after they are no longer needed!
+
+Here's a particular trap-for-the-unwary in Common Lisp. If you make an array with a fill pointer, and put objects in it, and then set the fill pointer back to zero, those objects are still reachable as far as Lisp goes (the Common Lisp spec says that it's still OK to refer to the array entries past the end of the fill pointer).
+
+Don't cons (i.e., allocate) unnecessarily. Garbage collection is not magic. Excessive allocation is usually a performance problem.
+
+=== Unsafe Operations
+
+link:?showone=Unsafe_Operations#Unsafe_Operations[link]▶
+
+You must only use faster unsafe operations when there is a clear performance need and you can document why it's correct.
+
+Common Lisp implementations often provide backdoors to compute some operations faster in an unsafe way. For instance, some libraries provide arithmetic operations that are designed to be used with fixnums only, and yield the correct result faster if provided proper arguments. The downside is that the result of such operations is incorrect in case of overflow, and can have undefined behavior when called with anything but fixnums.
+
+More generally, unsafe operations will yield the correct result faster than would the equivalent safe operation if the arguments satisfy some invariant such as being of the correct type and small enough; however if the arguments fail to satisfy the required invariants, then the operation may have undefined behavior, such as crashing the software, or, which is sometimes worse, silently giving wrong answers. Depending on whether the software is piloting an aircraft or other life-critical device, or whether it is accounting for large amounts money, such undefined behavior can kill or bankrupt people. Yet proper speed can sometimes make the difference between software that's unusably slow and software that does its job, or between software that is a net loss and software that can yield a profit.
+
+You must not define or use unsafe operations without both profiling results indicating the need for this optimization, and careful documentation explaining why it is safe to use them. Unsafe operations should be restricted to internal functions; you should carefully documented how unsafe it is to use these functions with the wrong arguments. You should only use unsafe operations inside functions internal to a package and you should document the use of the declarations, since calling the functions with arguments of the wrong type can lead to undefined behavior. Use `check-type` in functions exported from a package to sanitize input arguments, so that internal functions are never passed illegal values.
+
+On some compilers, new unsafe operations can usually be defined by combining type declarations with an `OPTIMIZE` declaration that has sufficiently high `SPEED` and low `SAFETY`. In addition to providing more speed for production code, such declarations may more helpful than `check-type` assertions for finding bugs at compile-time, on compilers that have type inference. These compilers may interpret those declarations as assertions if you switch to safer and slower optimize settings; this is good to locate a dynamic error in your code during development, but is not to be used for production code since it defeats the purpose of declarations as a performance trick.
+
+=== DYNAMIC-EXTENT
+
+link:?showone=DYNAMIC-EXTENT#DYNAMIC-EXTENT[link]▶
+
+You should only use `DYNAMIC-EXTENT` where it matters for performance, and you can document why it is correct.
+
+`DYNAMIC-EXTENT` declarations are a particular case of link:#unsafe-operations[unsafe operations].
+
+The purpose of a `DYNAMIC-EXTENT` declaration is to improve performance by reducing garbage collection in cases where it appears to be obvious that an object's lifetime is within the "dynamic extent" of a function. That means the object is created at some point after the function is called, and the object is always inaccessible after the function exits by any means.
+
+By declaring a variable or a local function `DYNAMIC-EXTENT`, the programmer _asserts_ to Lisp that any object that is ever a value of that variable or the closure that is the definition of the function has a lifetime within the dynamic extent of the (innermost) function that declares the variable.
+
+The Lisp implementation is then free to use that information to make the program faster. Typically, Lisp implementations can take advantage of this knowledge to stack-allocate:
+
+
+* The lists created to store `&REST` parameters.
+
+* Lists, vectors and structures allocated within a function.
+
+* Closures.
+
+If the assertion is wrong, i.e. if the programmer's claim is not true, the results can be __catastrophic__: Lisp can terminate any time after the function returns, or it can hang forever, or — worst of all — it can produce incorrect results without any runtime error!
+
+Even if the assertion is correct, future changes to the function might introduce a violation of the assertion. This increases the danger.
+
+In most cases, such objects are ephemeral. Modern Lisp implementations use generational garbage collectors, which are quite efficient under these circumstances.
+
+Therefore, `DYNAMIC-EXTENT` declarations should be used sparingly. You must only use them if:
+
+1. There is some good reason to think that the overall effect on performance is noticeable, and
+2. It is absolutely clear that the assertion is true.
+3. It is quite unlikely that the code will be changed in ways that cause the declaration to become false.
+
+Point (1) is a special case of the principle of avoiding premature optimization. An optimization like this only matters if such objects are allocated at a very high rate, e.g. "inside an inner loop".
+
+Note that is relatively easy to ascertain that a function will not escape the dynamic extent of the current call frame by analyzing where the function is called and what other functions it is passed to; therefore, you should somewhat wary of declaring a function `DYNAMIC-EXTENT`, but this is not a high-stress declaration. On the other hand, it is much harder to ascertain that none of the objects ever bound or assigned to that variable and none of their sub-objects will escape the dynamic extent of the current call frame, and that they still won't in any future modification of a function. Therefore, you should be extremely wary of declaring a variable `DYNAMIC-EXTENT`.
+
+It's usually hard to predict the effect of such optimization on performance. When writing a function or macro that is part of a library of reusable code, there's no a priori way to know how often the code will run. Ideally, tools would be available to discover the availability and suitability of using such an optimization based on running simulations and test cases, but in practice this isn't as easy as it ought to be. It's a tradeoff. If you're very, very sure that the assertion is true (that any object bound to the variable and any of its sub-objects are only used within the dynamic extent of the specified scope), and it's not obvious how much time will be saved and it's not easy to measure, then it may be better to put in the declaration than to leave it out. (Ideally it would be easier to make such measurements than it actually is.)
+
+=== REDUCE vs APPLY
+
+link:?showone=REDUCE_vs_APPLY#REDUCE_vs_APPLY[link]▶
+
+You should use `REDUCE` instead of `APPLY` where appropriate.
+
+You should use `REDUCE` instead of `APPLY` and a consed-up list, where the semantics of the first operator argument otherwise guarantees the same semantics. Of course, you must use `APPLY` if it does what you want and `REDUCE` doesn't. For instance:
+
+--------------------------------
+;; Bad
+(apply #'+ (mapcar #'acc frobs))
+--------------------------------
+
+----------------------------------------------
+;; Better
+(reduce #'+ frobs :key #'acc :initial-value 0)
+----------------------------------------------
+
+This is preferable because it does not do extra consing, and does not risk going beyond `CALL-ARGUMENTS-LIMIT` on implementations where that limit is small, which could blow away the stack on long lists (we want to avoid gratuitous non-portability in our code).
+
+However, you must be careful not to use `REDUCE` in ways that needlessly increase the complexity class of the computation. For instance, `(REDUCE 'STRCAT ...)` is _O(n^2)_ when an appropriate implementation is only __O(n)__. Moreover, `(REDUCE 'APPEND ...)` is also _O(n^2)_ unless you specify `:FROM-END T`. In such cases, you MUST NOT use `REDUCE`, and you MUST NOT use `(APPLY 'STRCAT ...)` or `(APPLY 'APPEND ...)` either. Instead you MUST use proper abstractions from a suitable library (that you may have to contribute to) that properly handles those cases without burdening users with implementation details. See for instance `UIOP:REDUCE/STRCAT`.
+
+=== Avoid NCONC
+
+link:?showone=Avoid_NCONC#Avoid_NCONC[link]▶
+
+You should not use `NCONC`; you should use `APPEND` instead, or better, better data structures.
+
+You should almost never use `NCONC`. You should use `APPEND` when you don't depend on any side-effect. You should use `ALEXANDRIA:APPENDF` when you need to update a variable. You should probably not depend on games being played with the `CDR` of the current CONS cell (which some might argue is suggested but not guaranteed by the specification); if you do, you must include a prominent comment explaining the use of `NCONC`; and you should probably reconsider your data representation strategy.
+
+By extension, you should avoid `MAPCAN` or the `NCONC` feature of `LOOP`. You should instead respectively use `ALEXANDRIA:MAPPEND` and the `APPEND` feature of `LOOP`.
+
+`NCONC` is very seldom a good idea, since its time complexity class is no better than `APPEND`, its space complexity class also is no better than `APPEND` in the common case where no one else is sharing the side-effected list, and its bug complexity class is way higher than `APPEND`.
+
+If the small performance hit due to `APPEND` vs. `NCONC` is a limiting factor in your program, you have a big problem and are probably using the wrong data structure: you should be using sequences with constant-time append (see Okasaki's book, and add them to lisp-interface-library), or more simply you should be accumulating data in a tree that will get flattened once in linear time after the accumulation phase is complete.
+
+You may only use `NCONC`, `MAPCAN` or the `NCONC` feature of `LOOP` in low-level functions where performance matters, where the use of lists as a data structure has been vetted because these lists are known to be short, and when the function or expression the result of which are accumulated explicitly promises in its contract that it only returns fresh lists (in particular, it can't be a constant quote or backquote expression). Even then, the use of such primitives must be rare, and accompanied by justifying documentation.
+
+[[Pitfalls]]
+== Pitfalls
+
+=== #'FUN vs. 'FUN
+
+link:?showone=__FUN_vs.__FUN#__FUN_vs.__FUN[link]▶
+
+You should usually refer to a function as `#'FUN` rather than `'FUN`.
+
+The former, which reads as `(FUNCTION FUN)`, refers to the function object, and is lexically scoped. The latter, which reads as `(QUOTE FUN)`, refers to the symbol, which when called uses the global `FDEFINITION` of the symbol.
+
+When using functions that take a functional argument (e.g., `MAPCAR`, `APPLY`, `:TEST` and `:KEY` arguments), you should use the `#'` to refer to the function, not just single quote.
+
+An exception is when you explicitly want dynamic linking, because you anticipate that the global function binding will be updated.
+
+Another exception is when you explicitly want to access a global function binding, and avoid a possible shadowing lexical binding. This shouldn't happen often, as it is usually a bad idea to shadow a function when you will want to use the shadowed function; just use a different name for the lexical function.
+
+You must consistently use either `#'(lambda ...)` or `(lambda ...)` without `#'` everywhere. Unlike the case of `#'symbol` vs `'symbol`, it is only a syntactic difference with no semantic impact, except that the former works on Genera and the latter doesn't. You must use the former style if your code is intended as a library with maximal compatibility to all Common Lisp implementations; otherwise, it is optional which style you use. `#'` may be seen as a hint that you're introducing a function in expression context; but the `lambda` itself is usually sufficient hint, and concision is good. Choose wisely, but above all, consistently with yourself and other developers, within a same file, package, system, project, etc.
+
+Note that if you start writing a new system in a heavily functional style, you may consider using http://cliki.net/lambda-reader[lambda-reader], a system that lets you use the unicode character `λ` instead of `LAMBDA`. But you must not start using such a syntactic extension in an existing system without getting permission from other developers.
+
+=== Pathnames
+
+link:?showone=Pathnames#Pathnames[link]▶
+
+Common Lisp pathnames are tricky. Be aware of pitfalls. Use `UIOP`.
+
+It is surprisingly hard to properly deal with pathnames in Common Lisp.
+
+`ASDF 3` comes with a portability library `UIOP` that makes it _much_ easier to deal with pathnames portably — and correctly — in Common Lisp. You should use it when appropriate.
+
+First, be aware of the discrepancies between the syntax of Common Lisp pathnames, which depends on which implementation and operating system you are using, and the native syntax of pathnames on your operating system. The Lisp syntax may involves quoting of special characters such as `#\.` and `#\*`, etc., in addition to the quoting of `#\\` and `#\"` within strings. By contrast, your operating system's other system programming languages (shell, C, scripting languages) may only have one layer of quoting, into strings.
+
+Second, when using `MERGE-PATHNAMES`, be wary of the treatment of the `HOST` component, which matters a lot on non-Unix platforms (and even on some Unix implementations). You probably should be using `UIOP:MERGE-PATHNAMES*` or `UIOP:SUBPATHNAME` instead of `MERGE-PATHNAMES`, especially if your expectations for relative pathnames are informed by the way they work in Unix or Windows; otherwise you might hit weird bugs whereby on some implementations, merging a relative pathnames with an absolute pathname results in overriding the absolute pathname's host and replace it with the host from the value of `*DEFAULT-PATHNAME-DEFAULTS*` at the time the relative pathname was created.
+
+Third, be aware that `DIRECTORY` is not portable across implementations in how it handles wildcards, sub-directories, symlinks, etc. There again, `UIOP` provides several common abstractions to deal with pathnames, but only does so good a job. For a complete portable solution, use IOLib — though its Windows support lags behind.
+
+`LOGICAL-PATHNAME`s are not a portable abstraction, and should not be used in portable code. Many implementations have bugs in them, when they are supported at all. SBCL implements them very well, but strictly enforces the limitations on characters allowed by the standard, which restricts their applicability. Other implementations allow arbitrary characters in such pathnames, but in doing so are not being conformant, and are still incompatible with each other in many ways. You should use other pathname abstractions, such as `ASDF:SYSTEM-RELATIVE-PATHNAME` or the underlying `UIOP:SUBPATHNAME` and `UIOP:PARSE-UNIX-NAMESTRING`.
+
+Finally, be aware that paths may change between the time you build the Lisp image for your application, and the time you run the application from its image. You should be careful to reset your image to forget irrelevant build-time paths and reinitialize any search path from current environment variables. `ASDF` for instance requires you to reset its paths with `UIOP:CLEAR-CONFIGURATION`. `UIOP` provides hooks to call functions before an image is dumped, from which to reset or `makunbound` relevant variables.
+
+=== SATISFIES
+
+link:?showone=SATISFIES#SATISFIES[link]▶
+
+You must be careful when using a `SATISFIES` clause in a type specifier.
+
+Most Common Lisp implementations can't optimize based on a `SATISFIES` type, but many of them offer simple optimizations based on a type of the form `(AND FOO (SATISFIES BAR-P))` where the first term of the `AND` clause describes the structure of the object without any `SATISFIES` and the second term is the `SATISFIES`.
+
+----------------------------------------------------------
+(deftype prime-number () (satisfies prime-number-p)) ; Bad
+----------------------------------------------------------
+
+--------------------------------------------------------------------------
+(deftype prime-number () (and integer (satisfies prime-number-p)) ; Better
+--------------------------------------------------------------------------
+
+However, `AND` in the `DEFTYPE` language isn't a left-to-right short-circuit operator as in the expression language; it is a symmetrical connector that allows for reordering subterms and doesn't guarantee short-circuiting. Therefore, in the above example, you cannot rely on the test for `INTEGER`ness to protect the function `PRIME-NUMBER-P` from being supplied non-integer arguments to test for being of instances of the type. Implementations may, and some __will__, invoke `SATISFIES`-specified function at compile-time to test various relevant objects.
+
+That is why any function specified in a `SATISFIES` clause MUST accept objects of any type as argument to the function, and MUST be defined within an `EVAL-WHEN` (as well as any variable it uses or function it calls):
+
+---------------------------------------
+(defun prime-number-p (n) ; Doubly bad!
+ (let ((m (abs n)))
+ (if (<= m *prime-number-cutoff*)
+ (small-prime-number-p m)
+ (big-prime-number-p m))))
+---------------------------------------
+
+---------------------------------------------------------------
+(eval-when (:compile-toplevel :load-toplevel :execute) ; Better
+ (defun prime-number-p (n)
+ (when (integerp n) ; Better
+ (let ((m (abs n)))
+ (if (<= m *prime-number-cutoff*)
+ (small-prime-number-p m)
+ (big-prime-number-p m))))))
+---------------------------------------------------------------
+
+In particular, the above means that the http://www.lispworks.com/documentation/HyperSpec/Body/t_satisf.htm[example] used in the Common Lisp Standard is erroneous: `(and integer (satisfies evenp))` is _not_ a safe, conformant type specifier to use, because `EVENP` will throw an error rather than return `NIL` when passed a non-integer as an argument.
+
+Finally, there is a catch when your `DEFTYPE` code expands to a `SATISFIES` with a dynamically generated function:
+
+
+* You cannot control when implementations will or will not expand a `DEFTYPE`.
+
+* The expansion itself cannot contain a function definition or any code in the expression language.
+
+* You cannot control when the expansion is used, it may happen in a different process that didn't expand the definition.
+
+Therefore, you cannot merely create the function as a side-effect of expansion using `EVAL` at type-expansion time. The solution is to use `ASDF-FINALIZERS:EVAL-AT-TOPLEVEL` instead. See the very last point in the discussion about link:#eval[EVAL].
+
+Common Lisp is hard to satisfy.
+
+'''''
+
+Credits: Adam Worrall, Dan Pierson, Matt Marjanovic, Matt Reklaitis, Paul Weiss, Scott McKay, Sundar Narasimhan, and several other people contributed. Special thanks to Steve Hain, and to the previous editors, in reverse chronological order Dan Weinreb and Jeremy Brown.
+
+Revision 1.28
+
+Robert Brown
+
+mailto:tunes@google.com[François-René Rideau]
diff --git a/lispguide.xml b/lispguide.xml
deleted file mode 100644
index e5b6dc3..0000000
--- a/lispguide.xml
+++ /dev/null
@@ -1,3887 +0,0 @@
-
-
-
-
-
-
-
-Revision 1.28
-
-
-
-
-Robert Brown
-
-
- François-René Rideau
-
-
-
- In memoriam Dan Weinreb
-
-
-
-Patterns mean "I have run out of language." — Rich Hickey
-
-
-
-
-
-
-
- This style guide contains many details
- that are initially hidden from view.
- They are marked by the triangle icon, which you see here on your left.
- Click it now. You should see "Hooray" appear below.
-
-
-
- Hooray! Now you know you can expand points to get more details.
- Alternatively, there's an "expand all" at the top of this document.
-
-
-
-
-
-
- Common Lisp is a powerful multiparadigm programming language.
- With great power comes great responsibility.
-
-
- This guide recommends formatting and stylistic choices
- designed to make your code easier for other people to understand.
- For those internal applications and free software libraries that
- we develop at Google,
- you should keep within these guidelines when making changes.
- Note however that each project has its own rules and customs
- that complement or override these general guidelines;
- the speed-oriented QPX low fare search engine notably
- has a very different style and feel from the QRes reservation system.
-
-
- If you're writing Common Lisp code outside Google,
- we invite you to consider these guidelines.
- You may find some of them useful
- where they don't conflict with other priorities you have.
- We welcome remarks and constructive feedback
- on how to improve our guide, and
- on what alternate styles work for you and why.
-
-
-
- This guide is not a Common Lisp tutorial.
- For basic information about the language, please consult
- Practical Common Lisp.
- For a language reference, please consult the
- Common Lisp HyperSpec.
- For more detailed style guidance, take (with a pinch of salt)
- a look at Peter Norvig and Kent Pitman's
- style guide.
-
-
-
-
-
-
- Each guideline's level of importance is indicated
- by use of the following keywords and phrases, adapted from
- RFC 2119.
-
-
-
-
- MUST
-
-
- This word, or the terms "REQUIRED" or "SHALL",
- means that the guideline is an absolute requirement.
- You must ask permission to violate a MUST.
-
-
-
-
- MUST NOT
-
-
- This phrase, or the phrase "SHALL NOT",
- means that the guideline is an absolute prohibition.
- You must ask permission to violate a MUST NOT.
-
-
-
-
- SHOULD
-
-
- This word, or the adjective "RECOMMENDED", means that
- there may exist valid reasons in particular circumstances
- to ignore the demands of the guideline, but
- the full implications must be understood and carefully weighed
- before choosing a different course.
- You must ask forgiveness for violating a SHOULD.
-
-
-
-
- SHOULD NOT
-
-
- This phrase, or the phrase "NOT RECOMMENDED", means that
- there may exist valid reasons in particular circumstances
- to ignore the prohibitions of this guideline, but
- the full implications should be understood and carefully weighed
- before choosing a different course.
- You must ask forgiveness for violating a SHOULD NOT.
-
-
-
-
- MAY
-
-
- This word, or the adjective "OPTIONAL",
- means that an item is truly optional.
-
-
-
-
-
- Unlike RFCs, we don't capitalize every instance of one of the above
- keywords when it is used.
-
-
-
-
-
- There are cases where transgression of some of these rules
- is useful or even necessary.
- In some cases, you must seek permission or obtain forgiveness
- from the proper people.
-
-
-
- Permission comes from the owners of your project.
-
-
-
- Forgiveness is requested in a comment
- near the point of guideline violation,
- and is granted by your code reviewer.
- The original comment should be signed by you, and
- the reviewer should add a signed approval to the comment at review time.
-
-
-
-
-
-
- You MUST follow conventions. They are not optional.
-
-
-
- Some of these guidelines are motivated by universal principles of good programming.
- Some guidelines are motivated by technical peculiarities of Common Lisp.
- Some guidelines were once motivated by a technical reason,
- but the guideline remained after the reason subsided.
- Some guidelines, such those about as comments and indentation,
- are based purely on convention, rather than on clear technical merit.
- Whatever the case may be, you must still follow these guidelines,
- as well as other conventional guidelines
- that have not been formalized in this document.
-
-
- You MUST follow conventions.
- They are important for readability.
- When conventions are followed by default,
- violations of the convention are a signal
- that something notable is happening and deserves attention.
- When conventions are systematically violated,
- violations of the convention are a distracting noise
- that needs to be ignored.
-
-
- Conventional guidelines are indoctrination.
- Their purpose is to make you follow the mores of the community,
-
- so you can more effectively cooperate with existing members.
- It is still useful to distinguish the parts that are technically motivated
- from the parts that are mere conventions,
- so you know when best to defy conventions for good effect,
- and when not to fall into the pitfalls that the conventions are there to help avoid.
-
-
-
-
-
- Fix old code as you go.
-
-
-
- A lot of our code was written before these guidelines existed.
- You should fix violations as you encounter them
- in the course of your normal coding.
-
-
- You must not fix violations en masse
- without warning other developers and coordinating with them,
- so as not to make the merging of large branches
- more difficult than it already is.
-
-
-
-
-
- There are many topics for additional standardization
- not covered by current version of this document,
- but deferred to future versions.
-
-
-
- -
- File and directory structure
-
- -
- Packages and modularity
-
- -
- Threads and locking
-
- -
- How to add configurable components
-
- -
- CLOS style: initforms, slot and accessor names, etc.
-
- -
- Recommendations on max number of slots per class.
-
- -
- More concrete examples of good code:
-
- -
- exceptions
-
- -
- transactions, with retry
-
- -
- XML
-
- -
- typing
-
- -
- encapsulation / abstraction
-
- -
- class and slot names
-
- -
- etc.
-
-
-
- -
- When (not) to use conditional compilation:
-
- -
- modifying the product
-
- -
- conditional debugging/console output/etc.
-
- -
- "temporarily" commenting-out blocks of code
-
- -
- etc.
-
-
-
-
-
-
-
-
-
-
- There are some basic principles for team software development
- that every developer must keep in mind.
- Whenever the detailed guidelines are inadequate, confusing or contradictory,
- refer back to these principles for guidance:
-
- -
- Every developer's code must be easy for another developer
- to read, understand, and modify
- — even if the first developer isn't around to explain it.
- (This is the "hit by a truck" principle.)
-
- -
- Everybody's code should look the same.
- Ideally, there should be no way to look at lines of code
- and recognize it as "Fred's code" by its style.
-
- -
- Be precise.
-
- -
- Be concise.
-
- -
- KISS — Keep It Simple, Stupid.
-
- -
- Use the smallest hammer for the job.
-
- -
- Use common sense.
-
- -
- Keep related code together.
- Minimize the amount of jumping around
- someone has to do to understand an area of code.
-
-
-
-
-
-
-
-
-
- When making decisions about how to write a given piece of
- code, aim for the following -ilities in this priority order:
-
-
- -
- Usability by the customer
-
- -
- Debuggability/Testability
-
- -
- Readability/Comprehensibility
-
- -
- Extensibility/Modifiability
-
- -
- Efficiency (of the Lisp code at runtime)
-
-
-
-
-
- Most of these are obvious.
-
-
- Usability by the customer means that the system has to do what the
- customer requires; it has to handle the customer's transaction
- volumes, uptime requirements; etc.
-
-
- For the Lisp efficiency point,
- given two options of equivalent complexity,
- pick the one that performs better.
- (This is often the same as the one that conses less,
- i.e. allocates less storage from the heap.)
-
-
- Given two options where one is more complex than the other,
- pick the simpler option and revisit the decision only if
- profiling shows it to be a performance bottleneck.
-
-
- However, avoid premature optimization.
- Don't add complexity to speed up something that runs rarely,
- since in the long run, it matters less whether such code is fast.
-
-
-
-
-
- To build code that is robust and maintainable,
- it matters a lot how the code is divided into components,
- how these components communicate,
- how changes propagate as they evolve,
- and more importantly
- how the programmers who develop these components communicate
- as these components evolve.
-
-
-
- If your work affects other groups, might be reusable across groups,
- adds new components, has an impact on other groups
- (including QA or Ops), or otherwise isn't purely local,
- you must write it up using at least a couple of paragraphs,
- and get a design approval from the other parties involved
- before starting to write code — or be ready to scratch what you have
- when they object.
-
-
- If you don't know or don't care about these issues,
- ask someone who does.
-
-
-
-
-
- Often, the smallest hammer is to use an existing library.
- Or one that doesn't exist yet.
- In such cases, you are encouraged to use or develop such a library,
- but you must take appropriate precautions.
-
-
-
- -
- You MUST NOT start a new library
- unless you established that none is already available
- that can be fixed or completed into becoming what you need.
- That's a rule against the NIH syndrome ("Not Invented Here"),
- which is particularly strong amongst Lisp hackers.
-
- -
- Whichever library, old or new, you pick, you MUST get permission
- to incorporate third-party code into the code base.
- You must discuss the use of such library
- in the appropriate mailing-list,
- and have your code reviewed by people knowledgeable in the domain
- and/or the Lisp library ecosystem (if any).
- Please be ready to argue why this particular solution makes sense
- as compared to other available libraries.
-
- -
- Some libraries are distributed under licenses not compatible
- with the software you're writing, and
- must not be considered available for use.
- Be aware of these issues, or consult with people who are.
-
-
-
-
-
-
-
-
- If you write a general-purpose library,
- or modify an existing open-source library,
- you are encouraged to publish the result
- separate from your main project and then
- have your project import it like any other open-source library.
-
-
-
-
-
- Use your judgment to distinguish
- general-purpose versus business-specific code,
- and open-source the general-purpose parts,
- while keeping the business-specific parts a trade secret.
-
-
-
- Open-Sourcing code has many advantages,
- including being able to leverage third parties for development,
- letting the development of features be user-directed,
- and keeping you honest with respect to code quality.
- Whatever code you write, you will have to maintain anyway,
- and make sure its quality is high enough to sustain use in production.
- There should therefore be no additional burden to Open-Sourcing,
- even of code that (at least initially)
- is not directly usable by third parties.
-
-
-
-
-
-
- Development process is outside the scope of this document.
- However, developers should remember at least these bits:
- get reviewed, write tests, eliminate warnings, run tests, avoid mass-changes.
-
-
-
-
-
- -
- All code changes must be reviewed.
- You should expect that your code will be reviewed by other hackers,
- and that you will be assigned other hackers' code to review.
- Part of the review criteria will be that code obeys
- the coding standards in this document.
-
- -
- You must write and check-in tests for new code that you write and old bugs you fix.
- There must be a unit test for every API function,
- and any previously failing case.
- Your work is not truly done until this activity is complete.
- Estimating tasks must include the time it takes to produce such tests.
-
- -
- Your code must compile
- without any compilation error or warning messages whatsoever.
- If the compiler issues warnings that should be ignored,
- muffle those warnings using the
-
UIOP:WITH-MUFFLED-COMPILER-CONDITIONS
and
- UIOP:*UNINTERESTING-COMPILER-CONDITIONS*
- framework (part of UIOP
, part of ASDF 3
),
- either around the entire project, or around individual files
- (using ASDF
's :around-compile
hooks).
-
- -
- All code should be checked in an appropriate source control system,
- in a way that allows for complete reproducibility of
- build, test and execution of
- the code that is, has been or may be deployed.
-
- -
- You must run the "precheckin" tests, and each component must pass
- its unit tests successfully before you commit any code.
-
- -
- You should incorporate code coverage into your testing process.
- Tests are not sufficient
- if they do not cover all new and updated code;
- code that for whatever reason cannot be included in coverage results
- should be clearly marked as such including the reason.
-
- -
- Many people develop on branches.
- You must get permission to undertake mass-changes
- (e.g. mass reindentations)
- so that we can coordinate in advance,
- and give branch residents time to get back on the mainline
-
-
-
-
-
-
-
-
-
- You must use correct spelling in your comments,
- and most importantly in your identifiers.
-
-
- When several correct spellings exist (including American vs English),
- and there isn't a consensus amongst developers as which to use,
- you should choose the shorter spelling.
-
-
- You must use only common and domain-specific abbreviations, and
- must be consistent with these abbreviations. You may abbreviate
- lexical variables of limited scope in order to avoid overly-long
- symbol names.
-
-
-
-
- If you're not sure, consult a dictionary,
- Google for alternative spellings,
- or ask a local expert.
-
-
- Here are examples of choosing the correct spelling:
-
-
- -
- Use "complimentary" in the sense of a meal or beverage
- that is not paid for by the recipient, not "complementary".
-
- -
- Use "existent" and "nonexistent", not "existant".
- Use "existence", not "existance".
-
- -
- Use "hierarchy" not "heirarchy".
-
- -
- Use "precede" not "preceed".
-
- -
- Use "weird", not "wierd".
-
-
-
- Here are examples of choosing the shorter spelling:
-
-
- -
- Use "canceled", not "cancelled"
-
- -
- Use "queuing", not "queueing".
-
- -
- Use "signaled", not "signalled";
-
- -
- Use "traveled", not "travelled".
-
- -
- Use "aluminum", not "aluminium"
-
- -
- Use "oriented", not "orientated"
-
- -
- Use "color", not "colour"
-
- -
- Use "behavior", not "behaviour"
-
-
-
- Make appropriate exceptions for industry standard nomenclature/jargon,
- including plain misspellings.
- For instance:
-
-
- -
- Use "referer", not "referrer", in the context of the HTTP protocol.
-
-
-
-
-
-
-
- You should format source code so that no line is longer than 100 characters.
-
-
-
- Some line length restriction is better than none at all.
- While old text terminals used to make 80 columns the standard,
- these days, allowing 100 columns seems better,
- since good style encourages the use of
- descriptive variables and function names.
-
-
-
-
-
-
-
- Indent your code the way a properly configured GNU Emacs does.
-
-
- Maintain a consistent indentation style throughout a project.
-
-
- Indent carefully to make the code easier to understand.
-
-
-
-
- Common Lisp indentation in Emacs is provided by the cl-indent library.
- The latest version of cl-indent is packaged with
- SLIME
- (under contrib/slime-cl-indent.el). After installing SLIME, set up Emacs
- to load SLIME automatically using
- these instructions, adding slime-indentation to the list of
- contrib libraries to be loaded in the call to slime-setup.
-
-
- Ideally, use the default indentation settings provided by
- slime-indentation. If necessary, customize indentation parameters to
- maintain a consistent indentation style throughout an existing project.
- Parameters can be customized using the :variables setting in
- define-common-lisp-style. Indentation of specific forms can be
- customized using the :indentation setting of define-common-lisp-style.
- This is particularly useful when creating forms that behave like macros
- or special operators that are indented differently than standard
- function calls (e.g. defun, labels, or let). Add a
- hook to 'lisp-mode-hook that calls common-lisp-set-style to set
- the appropriate style automatically.
-
-
-
-
- Use indentation to make complex function applications easier to read.
- When an application does not fit on one line
- or the function takes many arguments,
- consider inserting newlines between the arguments
- so that each one is on a separate line.
- However, do not insert newlines in a way that makes it hard to tell
- how many arguments the function takes
- or where an argument form starts and ends.
-
-
- ;; Bad
- (do-something first-argument second-argument (lambda (x)
- (frob x)) fourth-argument last-argument)
-
-
- ;; Better
- (do-something first-argument
- second-argument
- #'(lambda (x) (frob x))
- fourth-argument
- last-argument)
-
-
-
-
-
-
- You should include a description at the top of each source file.
-
-
- You should include neither authorship nor copyright information in a source file.
-
-
-
-
- Every source file should begin with a brief description
- of the contents of that file.
-
-
- After that description, every file should start the code itself with an
- (in-package :package-name)
form.
-
-
- After that in-package
form,
- every file should follow with any file-specific
- (declaim (optimize ...))
declaration
- that is not covered by an ASDF
:around-compile
hook.
-
-
- ;;;; Variable length encoding for integers and floating point numbers.
-
- (in-package #:varint)
- (declaim #.*optimize-default*)
-
-
- You should not include authorship information at the top of a file:
- better information is available from version control,
- and such a mention will only cause confusion and grief.
- Indeed, whoever was the main author at the time such a mention was included
- might not be who eventually made the most significant contributions to the file,
- and even less who is responsible for the file at the moment.
-
-
-
- You should not include copyright information in individual source code files.
- An exception is made for files meant to be disseminated as standalone.
-
-
-
-
-
-
-
- Vertical white space: one blank line between top-level forms.
-
-
-
- You should include one blank line between top-level forms,
- such as function definitions.
- Exceptionally, blank lines can be omitted
- between simple, closely related defining forms of the same kind,
- such as a group of related type declarations or constant definitions.
-
-
- (defconstant +mix32+ #x12b9b0a1 "pi, an arbitrary number")
- (defconstant +mix64+ #x2b992ddfa23249d6 "more digits of pi")
-
- (defconstant +golden-ratio32+ #x9e3779b9 "the golden ratio")
- (defconstant +golden-ratio64+ #xe08c1d668b756f82 "more digits of the golden ratio")
-
- (defmacro incf32 (x y)
- "Like INCF, but for integers modulo 2**32"
- `(setf ,x (logand (+ ,x ,y) #xffffffff)))
- (defmacro incf64 (x y)
- "Like INCF, but for integers modulo 2**64"
- `(setf ,x (logand (+ ,x ,y) #xffffffffffffffff)))
-
-
- Blank lines can be used to separate parts of a complicated function.
- Generally, however, you should break a large function into smaller ones
- instead of trying to make it more readable by adding vertical space.
- If you can't, you should document with a ;;
comment
- what each of the separated parts of the function does.
-
-
- You should strive to keep top-level forms,
- including comments but excluding the documentation string, of
- appropriate length; preferrably short. Forms extending beyond a
- single page should be rare and their use should be justfied.
- This applies to each of the forms in an eval-when
,
- rather than to the eval-when
itself.
- Additionally, defpackage
forms may be longer,
- since they may include long lists of symbols.
-
-
-
-
-
- Horizontal white space: none around parentheses. No tabs.
-
-
-
- You must not include extra horizontal whitespace
- before or after parentheses or around symbols.
-
-
- You must not place right parentheses by themselves on a line.
- A set of consecutive trailing parentheses must appear on the same line.
-
-
- ;; Very Bad
- ( defun factorial ( limit )
- ( let (( product 1 ))
- ( loop for i from 1 upto limit
- do (setf product ( * product i ) ) )
- product
- )
- )
-
-
- ;; Better
- (defun factorial (limit)
- (let ((product 1))
- (loop for i from 1 upto limit
- do (setf product (* product i)))
- product))
-
-
- You should use only one space between forms.
-
-
- You should not use spaces to vertically align forms
- in the middle of consecutive lines.
- An exception is made when the code possesses
- an important yet otherwise not visible symmetry
- that you want to emphasize.
-
-
- ;; Bad
- (let* ((low 1)
- (high 2)
- (sum (+ (* low low) (* high high))))
- ...)
-
-
- ;; Better
- (let* ((low 1)
- (high 2)
- (sum (+ (* low low) (* high high))))
- ...))
-
-
- You must align nested forms if they occur across more than one line.
-
-
- ;; Bad
- (defun munge (a b c)
- (* (+ a b)
- c))
-
-
- ;; Better
- (defun munge (a b c)
- (* (+ a b)
- c))
-
-
- The convention is that the body of a binding form
- is indented two spaces after the form.
- Any binding data before the body is usually indented four spaces.
- Arguments to a function call are aligned with the first argument;
- if the first argument is on its own line,
- it is aligned with the function name.
-
-
- (multiple-value-bind (a b c d)
- (function-returning-four-values x y)
- (declare (ignore c))
- (something-using a)
- (also-using b d))
-
-
- An exception to the rule against lonely parentheses
- is made for an eval-when
form around several definitions;
- in this case, include a comment ; eval-when
- after the closing parenthesis.
-
-
- You must set your editor to
- avoid inserting tab characters in the files you edit.
- Tabs cause confusion when editors disagree
- on how many spaces they represent.
- In Emacs, do (setq-default indent-tabs-mode nil)
.
-
-
-
-
-
-
-
-
- You should use document strings on all visible functions
- to explain how to use your code.
-
-
-
- Unless some bit of code is painfully self-explanatory,
- document it with a documentation string (also known as docstring).
-
-
- Documentation strings are destined to be read
- by the programmers who use your code.
- They can be extracted from functions, types, classes, variables and macros,
- and displayed by programming tools, such as IDEs,
- or by REPL queries such as (describe 'foo)
;
- web-based documentation or other reference works
- can be created based on them.
- Documentation strings are thus the perfect locus to document your API.
- They should describe how to use the code
- (including what pitfalls to avoid),
- as opposed to how the code works (and where more work is needed),
- which is what you'll put in comments.
-
-
- Supply a documentation string when defining
- top-level functions, types, classes, variables and macros.
- Generally, add a documentation string wherever the language allows.
-
-
- For functions, the docstring should describe the function's contract:
- what the function does,
- what the arguments mean,
- what values are returned,
- what conditions the function can signal.
- It should be expressed at the appropriate level of abstraction,
- explaining the intended meaning rather than, say, just the syntax.
- In documentation strings, capitalize the names of Lisp symbols,
- such as function arguments.
- For example, "The value of LENGTH should be an integer."
-
-
- (defun small-prime-number-p (n)
- "Return T if N, an integer, is a prime number. Otherwise, return NIL."
- (cond ((or (< n 2))
- nil)
- ((= n 2)
- t)
- ((divisorp 2 n)
- nil)
- (t
- (loop for i from 3 upto (sqrt n) by 2
- never (divisorp i n)))))
-
-
- (defgeneric table-clear (table)
- (:documentation
- "Like clrhash, empties the TABLE of all
- associations, and returns the table itself."))
-
-
- A long docstring may usefully
- begin with a short, single-sentence summary,
- followed by the larger body of the docstring.
-
-
- When the name of a type is used,
- the symbol may be quoted by surrounding it with
- a back quote at the beginning and a single quote at the end.
- Emacs will highlight the type, and the highlighting serves
- as a cue to the reader that M-.
- will lead to the symbol's definition.
-
-
- (defun bag-tag-expected-itinerary (bag-tag)
- "Return a list of `legacy-pnr-pax-segment' objects representing
- the expected itinerary of the `bag-tag' object, BAG-TAG."
- ...)
-
-
- Every method of a generic function should be independently documented
- when the specialization affects what the method does,
- beyond what is described in its generic function's docstring.
-
-
- When you fix a bug,
- consider whether what the fixed code does is obviously correct or not;
- if not, you must add a comment explaining
- the reason for the code in terms of fixing the bug.
- Adding the bug number, if any, is also recommended.
-
-
-
-
-
- You must use the appropriate number of semicolons to introduce comments.
-
-
-
- Comments are explanations to the future maintainers of the code.
- Even if you're the only person who will ever see and touch the code,
- even if you're either immortal and never going to quit,
- or unconcerned with what happens after you leave
- (and have your code self-destruct in such an eventuality),
- you may find it useful to comment your code.
- Indeed, by the time you revisit your code,
- weeks, months or years later,
- you will find yourself a different person from the one who wrote it,
- and you will be grateful to that previous self
- for making the code readable.
-
-
- You must comment anything complicated
- so that the next developer can understand what's going on.
- (Again, the "hit by a truck" principle.)
-
-
- Also use comments as a way to guide those who read the code,
- so they know what to find where.
-
-
- -
- File headers and important comments
- that apply to large sections of code in a source file
- should begin with four semicolons.
-
- -
- You should use three semicolons
- to begin comments that apply to just
- one top-level form or small group of top-level forms.
-
- -
- Inside a top-level form, you should use two semicolons
- to begin a comment if it appears between lines.
-
- -
- You should use one semicolon if it is a parenthetical remark
- and occurs at the end of a line.
- You should use spaces to separate the comment
- from the code it refers to so the comment stands out.
- You should try to vertically align
- consecutive related end-of-line comments.
-
-
-
- ;;;; project-euler.lisp
- ;;;; File-level comments or comments for large sections of code.
-
- ;;; Problems are described in more detail here: http://projecteuler.net/
-
- ;;; Divisibility
- ;;; Comments that describe a group of definitions.
-
- (defun divisorp (d n)
- (zerop (mod n d)))
-
- (defun proper-divisors (n)
- ...)
-
- (defun divisors (n)
- (cons n (proper-divisors n)))
-
- ;;; Prime numbers
-
- (defun small-prime-number-p (n)
- (cond ((or (< n 2))
- nil)
- ((= n 2) ; parenthetical remark here
- t) ; continuation of the remark
- ((divisorp 2 n)
- nil) ; different remark
- ;; Comment that applies to a section of code.
- (t
- (loop for i from 3 upto (sqrt n) by 2
- never (divisorp i n)))))
-
-
- You should include a space between the semicolon and the text of the comment.
-
-
-
-
-
- You should punctuate documentation correctly.
-
-
-
- When a comment is a full sentence,
- you should capitalize the initial letter of the first word
- and end the comment with a period.
- In general, you should use correct punctuation.
-
-
-
-
-
- You must follow the convention of using TODO comments
- for code requiring special attention.
- For code using unobvious forms, you must include a comment.
-
-
-
- For comments requiring special attention, such as
- incomplete code, todo items, questions, breakage, and danger,
- include a TODO comment indicating the type of problem,
- its nature, and any notes on how it may be addressed.
-
-
- The comments begin with TODO
in all capital letters,
- followed by the
-
- name, e-mail address, or other identifier
- of the person
- with the best context about the problem referenced by the TODO
.
- The main purpose is to have a consistent TODO
that
- can be searched to find out how to get more details upon
- request. A TODO
is not a commitment that the
- person referenced will fix the problem. Thus when you create
- a TODO
,
- it is almost always your
- name
- that is given.
-
-
- When signing comments,
- you should use your username (for code within the company)
- or full email address (for code visible outside the company),
- not just initials.
-
-
-
- ;;--- TODO(george@gmail.com): Refactor to provide a better API.
-
-
- Be specific when indicating times or software releases
- in a TODO comment and use
- YYYY-MM-DD
- format for dates to make automated processing of such dates easier,
- e.g., 2038-01-20 for the end of the 32-bit signed time_t
.
-
-
- ;;--- TODO(brown): Remove this code after release 1.7 or before 2012-11-30.
-
-
- For code that uses unobvious forms to accomplish a task, you must include a comment
- stating the purpose of the form and the task it accomplishes.
-
-
-
-
-
- You should document DSLs and
- any terse program in a DSL.
-
-
-
- You should design your Domain Specific Language
- to be easy to read and understand by people familiar with the domain.
-
-
- You must properly document all your Domain Specific Language.
-
-
- Sometimes, your DSL is designed for terseness.
- In that case, it is important to document what each program does,
- if it's not painfully obvious from the context.
-
-
- Notably, when you use regular expressions
- (e.g. with the CL-PPCRE
package),
- you MUST ALWAYS put in a comment
- (usually a two-semicolon comment on the previous line)
- explaining, at least basically, what the regular expression does,
- or what the purpose of using it is.
- The comment need not spell out every bit of the syntax, but
- it should be possible for someone to follow the logic of the code
- without actually parsing the regular expression.
-
-
-
-
-
-
-
-
-
- You should use lower case.
- You should follow the rules for Spelling and Abbreviations
- You should follow punctuation conventions.
-
-
-
- Use lower case for all symbols.
- Consistently using lower case makes searching for symbol names easier
- and is more readable.
-
-
- Note that Common Lisp is case-converting,
- and that the symbol-name
of your symbols
- will be upper case.
- Because of this case-converting,
- attempts to distinguish symbols by case are defeated,
- and only result in confusion.
- While it is possible to escape characters in symbols
- to force lower case,
- you should not use this capability
- unless this is somehow necessary
- to interoperate with third-party software.
-
-
- Place hyphens between all the words in a symbol.
- If you can't easily say an identifier out loud,
- it is probably badly named.
-
-
- You must not use "/"
or "."
- instead of "-"
- unless you have a well-documented overarching reason to,
- and permission from other hackers who review your proposal.
-
-
- See the section on Spelling and Abbreviations
- for guidelines on using abbreviations.
-
-
- ;; Bad
- (defvar *default-username* "Ann")
- (defvar *max-widget-cnt* 200)
-
-
- ;; Better
- (defvar *default-user-name* "Ann")
- (defvar *maximum-widget-count* 200)
-
-
- There are conventions in Common Lisp
- for the use of punctuation in symbols.
- You should not use punctuation in symbols outside these conventions.
-
-
- Unless the scope of a variable is very small,
- do not use overly short names like
- i
and zq
.
-
-
-
-
-
- Name your variables according to their intent,
- not their content.
-
-
-
- You should name a variable according
- to the high-level concept that it represents,
- not according to the low-level implementation details
- of how the concept is represented.
-
-
- Thus, you should avoid embedding
- data structure or aggregate type names,
- such as list
, array
, or
- hash-table
inside variable names,
- unless you're writing a generic algorithm that applies to
- arbitrary lists, arrays, hash-tables, etc.
- In that case it's perfectly OK to name a variable
- list
or array
.
-
-
- Indeed, you should be introducing new abstract data types
- with DEFCLASS
or DEFTYPE
,
- whenever a new kind of intent appears for objects in your protocols.
- Functions that manipulate such objects generically may then
- use variables the name of which reflect that abstract type.
-
-
- For example, if a variable's value is always a row
- (or is either a row or NIL
),
- it's good to call it row
or first-row
- or something like that.
- It is alright is row
has been
- DEFTYPE
'd to STRING
—
- precisely because you have abstracted the detail away,
- and the remaining salient point is that it is a row.
- You should not name the variable STRING
in this context,
- except possibly in low-level functions that specifically manipulate
- the innards of rows to provide the suitable abstraction.
-
-
- Be consistent.
- If a variable is named row
in one function,
- and its value is being passed to a second function,
- then call it row
rather than, say, value
- (this was a real case).
-
-
-
-
-
- Name globals according to convention.
-
-
-
- The names of global constants should start and end
- with plus characters.
-
-
- Global variable names should start and end with asterisks
- (also known in this context as earmuffs).
-
-
- In some projects, parameters that are not meant
- to be usually modified or bound under normal circumstances
- (but may be during experimentation or exceptional situations)
- should start (but do not end) with a dollar sign.
- If such a convention exists within your project,
- you should follow it consistently.
- Otherwise, you should avoid naming variables like this.
-
-
- Common Lisp does not have global lexical variables,
- so a naming convention is used to ensure that globals,
- which are dynamically bound,
- never have names that overlap with local variables.
- It is possible to fake global lexical variables
- with a differently named global variable
- and a DEFINE-SYMBOL-MACRO
.
- You should not use this trick,
- unless you first publish a library that abstracts it away.
-
-
- (defconstant +hash-results+ #xbd49d10d10cbee50)
-
- (defvar *maximum-search-depth* 100)
-
-
-
-
-
- Names of predicate functions and variables end with a "P"
.
-
-
-
- You should name boolean-valued functions and variables with a
- trailing "P"
or "-P"
,
- to indicate they are predicates.
- Generally, you should use
- "P"
when the rest of the function name is one word
- and "-P"
when it is more than one word.
-
-
- A rationale for this convention is given in
- the CLtL2 chapter on predicates.
-
-
- For uniformity, you should follow the convention above,
- and not one of the alternatives below.
-
-
- An alternative rule used in some existing packages
- is to always use "-P"
.
- Another alternative rule used in some existing packages
- is to always use "?"
.
- When you develop such a package,
- you must be consistent with the rest of the package.
- When you start a new package,
- you should not use such an alternative rule
- without a very good documented reason.
-
-
-
-
-
- You should not include a library or package name
- as a prefix within the name of symbols.
-
-
-
- When naming a symbol (external or internal) in a package,
- you should not include the package name
- as a prefix within the name of the symbol.
- Naming a symbol this way makes it awkward to use
- from a client package accessing the symbol
- by qualifying it with a package prefix,
- where the package name then appears twice
- (once as a package prefix,
- another time as a prefix within the symbol name).
-
-
- ;; Bad
- (in-package #:varint)
- (defun varint-length64 () ... )
-
- (in-package #:client-code)
- (defconst +padding+ (varint:varint-length64 +end-token+))
-
-
- ;; Better
- (in-package #:varint)
- (defun length64 () ... )
-
- (in-package #:client-code)
- (defconst +padding+ (varint:length64 +end-token+))
-
-
- An exception to the above rule would be to include a prefix
- for the names of variables that would otherwise be expected to clash
- with variables in packages that use the current one.
- For instance, ASDF
exports a variable *ASDF-VERBOSE*
- that controls the verbosity of ASDF
only,
- rather than of the entire Lisp program.
-
-
-
-
-
- Use packages appropriately.
-
-
-
- Lisp packages are used to demarcate namespaces.
- Usually, each system has its own namespace.
- A package has a set of external symbols,
- which are intended to be used from outside the package,
- in order to allow other modules to use this module's facilities.
-
-
- The internal symbols of a package
- should never be referred to from other packages.
- That is, you should never have to use
- the double-colon ::
construct.
- (e.g. QUAKE::HIDDEN-FUNCTION
).
- If you need to use double-colons to write real production code,
- something is wrong and needs to be fixed.
-
-
- As an exception,
- unit tests may use the internals of the package being tested.
- So when you refactor, watch out for
- internals used by the package's unit tests.
-
-
- The ::
construct is also useful for very temporary hacks,
- and at the REPL.
- But if the symbol really is part of
- the externally-visible definition of the package,
- export it.
-
-
- You may find that some internal symbols represent concepts
- you usually want to abstract away and hide under the hood,
- yet at times are necessary to expose for various extensions.
- For the former reason, you do not want to export them,
- yet for the latter reason, you have to export them.
- The solution is to have two different packages,
- one for your normal users to use, and
- another for the implementation and its extenders to use.
-
-
- Each package is one of two types:
-
-
- -
- Intended to be included
- in the
:use
specification of other packages.
- If package A
"uses" package B
,
- then the external symbols of package B
- can be referenced from within package A
- without a package prefix.
- We mainly use this for low-level modules
- that provide widely-used facilities.
-
- -
- Not intended to be "used".
- To reference a facility provided by package
B
,
- code in package A
must use an explicit package prefix,
- e.g. B:DO-THIS
.
-
-
-
- If you add a new package, it should always be of the second type,
- unless you have a special reason and get permission.
- Usually a package is designed to be one or the other,
- by virtue of the names of the functions.
- For example, if you have an abstraction called FIFO
,
- and it were in a package of the first type
- you'd have functions named things like
- FIFO-ADD-TO
and FIFO-CLEAR-ALL
.
- If you used a package of the second type,
- you'd have names like ADD-TO
and CLEAR-ALL
,
- because the callers would be saying
- FIFO:ADD-TO
and FIFO:CLEAR-ALL
.
- (FIFO:FIFO-CLEAR-ALL
is redundant and ugly.)
-
-
- Another good thing about packages is that
- your symbol names won't "collide" with the names of other packages,
- except the ones your packages "uses".
- So you have to stay away from symbols
- that are part of the Lisp implementation (since you always "use" that)
- and that are part of any other packages you "use",
- but otherwise you are free to make up your own names,
- even short ones, and not worry about some else
- having used the same name.
- You're isolated from each other.
-
-
- Your package must not shadow (and thus effectively redefine)
- symbols that are part of the Common Lisp language.
- There are certain exceptions,
- but they should be very well-justified and extremely rare:
-
-
- -
- If you are explicitly replacing a Common Lisp symbol
- by a safer or more featureful version.
-
- -
- If you are defining a package not meant to be "used",
- and have a good reason to export a symbol
- that clashes with Common Lisp,
- such as
log:error
and log:warn
- and so on.
-
-
-
-
-
-
-
-
-
- You should avoid side-effects when they are not necessary.
-
-
-
- Lisp is best used as a "mostly functional" language.
-
-
- Avoid modifying local variables, try rebinding instead.
-
-
- Avoid creating objects and the SETFing their slots.
- It's better to set the slots during initialization.
-
-
- Make classes as immutable as possible, that is, avoid giving slots
- setter functions if at all possible.
-
-
- Using a mostly functional style makes it much easier
- to write concurrent code that is thread-safe.
- It also makes it easier to test the code.
-
-
-
-
-
- You should favor iteration over recursion.
-
-
-
- Common Lisp systems are not required to implement
- function calls from tail positions without leaking stack space
- — which is known as proper tail calls (PTC),
- tail call elimination (TCE),
- or tail call optimization (TCO).
- This means that indefinite recursion through tail calls
- may quickly blow out the stack,
- which hampers functional programming.
- Still, most serious implementations (including SBCL and CCL)
- do implement proper tail calls, but with restrictions:
-
-
- -
- The
(DECLARE (OPTIMIZE ...))
settings
- must favor SPEED
enough and
- not favor DEBUG
too much,
- for some compiler-dependent meanings of "enough" and "too much".
- (For instance, in SBCL, you should avoid (SPEED 0)
- and (DEBUG 3)
to achieve proper tail calls.)
-
- -
- There should not be dynamic bindings around the call
- (even though some Scheme compilers are able to properly treat
- such dynamic bindings, called parameters in Scheme parlance).
-
-
-
- For compatibility with all compilers and optimization settings,
- and to avoid stack overflow when debugging,
- you should prefer iteration or the built in mapping functions
- to relying on proper tail calls.
-
-
- If you do rely on proper tail calls,
- you must prominently document the fact,
- and take appropriate measures to ensure an appropriate compiler is used
- with appropriate optimization settings.
- For fully portable code, you may have to use trampolines instead.
-
-
-
-
-
- Use special variables sparingly.
-
-
-
- Using Lisp "special" (dynamically bound) variables
- as implicit arguments to functions should be used sparingly,
- and only in cases where it won't surprise the person reading the code,
- and where it offers significant benefits.
-
-
- Indeed, each special variable constitutes state.
- Developers have to mentally track the state of all relevant variables
- when trying to understand what the code does and how it does it;
- tests have to be written and run with all relevant combinations;
- to isolate some activity, care has to be taken to locally bind
- all relevant variables, including those of indirectly used modules.
- They can hide precious information from being printed in a backtrace.
- Not only is there overhead associated to each new variable,
- but interactions between variables
- can make the code exponentially more complex
- as the number of such variables increases.
- The benefits have to match the costs.
-
-
- Note though that a Lisp special variable is not a global variable
- in the sense of a global variable in, say, BASIC or C.
- As special variables can be dynamically bound to a local value,
- they are much more powerful than
- global value cells where all users necessarily interfere with each other.
-
-
- Good candidates for such special variables
- are items for which "the current" can be naturally used as prefix,
- such as "the current database connection" or
- "the current business data source".
- They are singletons as far as the rest of the code is concerned,
- and often passing them as an explicit argument
- does not add anything to the readability or maintainability
- of the source code in question.
-
-
- They can make it easier to write code that can be refactored.
- If you have a request processing chain,
- with a number of layers that all operate upon a "current" request,
- passing the request object explicitly to every function
- requires that every function in the chain have a request argument.
- Factoring out code into new functions often requires
- that these functions also have this argument,
- which clutters the code with boilerplate.
-
-
- You should treat special variables
- as though they are per-thread variables.
- By default, you should leave a special variable
- with no top-level binding at all,
- and each thread of control
- that needs the variable should bind it explicitly.
- This will mean that any incorrect use of the variable
- will result in an "unbound variable" error, and
- each thread will see its own value for the variable.
- Variables with a default global value should usually be
- locally bound at thread creation time.
- You should use suitable infrastructure
- to automate the appropriate declaration of such variables.
-
-
-
-
-
-
- Be consistent in assignment forms.
-
-
-
- There are several styles for dealing with assignment and side-effects;
- whichever a given package is using,
- keep using the same consistently when hacking said package.
- Pick a style that makes sense when starting a new package.
-
-
- Regarding multiple assignment in a same form, there are two schools:
- the first style groups as many assignments as possible into a single
- SETF
or PSETF
form
- thus minimizing the number of forms with side-effects;
- the second style splits assignments into as many individual
- SETF
(or SETQ
, see below) forms as possible,
- to maximize the chances of locating forms that modify a kind of place
- by grepping for (setf (foo ...
.
- A grep pattern must actually contain as many place-modifying forms
- as you may use in your programs, which may make this rationale either
- convincing or moot depending on the rest of the style of your code.
- You should follow the convention used in the package you are hacking.
- We recommend the first convention for new packages.
-
-
- Regarding SETF
and SETQ
,
- there are two schools:
- this first regards SETQ
- as an archaic implementation detail,
- and avoids it entirely in favor of SETF
;
- the second regards SETF
- as an additional layer of complexity,
- and avoids it in favor of SETQ
whenever possible
- (i.e. whenever the assigned place is a variable or symbol-macro).
- You should follow the convention used in the package you are hacking.
- We recommend the first convention for new packages.
-
-
- In the spirit of a mostly pure functional style,
- which makes testing and maintenance easier,
- we invite you to consider how to do things with the fewest assignments required.
-
-
-
-
-
- You must make proper usage of assertions and conditions.
-
-
-
- -
-
ASSERT
should be used ONLY to detect internal bugs.
- Code should ASSERT
invariants whose failure indicates
- that the software is itself broken.
- Incorrect input should be handled properly at runtime,
- and must not cause an assertion violation.
- The audience for an ASSERT
failure is a developer.
- Do not use the data-form and argument-form in ASSERT
- to specify a condition to signal.
- It's fine to use them to print out a message for debugging purposes
- (and since it's only for debugging, there's no issue of
- internationalization).
-
- -
-
CHECK-TYPE
,
- ETYPECASE
are also forms of assertion.
- When one of these fails, that's a detected bug.
- You should prefer to use CHECK-TYPE
- over (DECLARE (TYPE ...))
- for the inputs of functions.
-
- -
- Your code should use assertions and type checks liberally.
- The sooner a bug is discovered, the better!
- Only code in the critical path for performance
- and internal helpers should eschew
- explicit assertions and type checks.
-
- -
- Invalid input, such as files that are read
- but do not conform to the expected format,
- should not be treated as assertion violations.
- Always check to make sure that input is valid,
- and take appropriate action if it is not,
- such as signalling a real error.
-
- -
-
ERROR
should be used
- to detect problems with user data, requests, permissions, etc.,
- or to report "unusual outcomes" to the caller.
-
- -
-
ERROR
should always be called
- with an explicit condition type;
- it should never simply be called with a string.
- This enables internationalization.
-
- -
- Functions that report unusual outcomes
- by signaling a condition should say so explicitly in their contracts
- (their textual descriptions, in documentation and docstrings etc.).
- When a function signals a condition
- that is not specified by its contract, that's a bug.
- The contract should specify the condition class(es) clearly.
- The function may then signal any condition
- that is a type-of any of those conditions.
- That is, signaling instances of subclasses
- of the documented condition classes is fine.
-
- -
- Complex bug-checks may need to use
ERROR
- instead of ASSERT
.
-
-
- -
- When writing a server, you must not call
WARN
.
- Instead, you should use the appropriate logging framework.
-
-
- -
- Code must not call
SIGNAL
.
- Instead, use ERROR
or ASSERT
.
-
- -
- Code should not use
THROW
and CATCH
;
- instead use the restart
facility.
-
- -
- Code should not generically handle all conditions,
- e.g. type
T
, or use IGNORE-ERRORS
.
- Instead, let unknown conditions propagate to
- the standard ultimate handler for processing.
-
-
- -
- There are a few places where handling all conditions is appropriate,
- but they are rare.
- The problem is that handling all conditions can mask program bugs.
- If you do need to handle "all conditions",
- you MUST handle only
ERROR
, not T
- and not SERIOUS-CONDITION
.
- (This is notably because CCL's process shutdown
- depends on being able to signal process-reset
- and have it handled by CCL's handler,
- so we must not interpose our own handler.)
-
- -
-
(error (make-condition 'foo-error ...))
- is equivalent to (error 'foo-error ...)
—
- code must use the shorter form.
-
- -
- Code should not signal conditions from inside the cleanup form of
-
UNWIND-PROTECT
- (unless they are always handled inside the cleanup form),
- or otherwise do non-local exits from cleanup handlers
- outside of the handler e.g. INVOKE-RESTART
.
-
- -
- Do not clean up by resignaling.
- If you do that, and the condition is not handled,
- the stack trace will halt at the point of the resignal,
- hiding the rest.
- And the rest is the part we really care about!
-
- ;; Bad
- (handler-case
- (catch 'ticket-at
- (etd-process-blocks))
- (error (c)
- (reset-parser-values)
- (error c)))
-
-
- ;; Better
- (unwind-protect
- (catch 'ticket-at
- (etd-process-blocks))
- (reset-parser-values))
-
-
-
-
-
-
-
- If you know the type of something, you should make it explicit
- in order to enable compile-time and run-time sanity-checking.
-
-
-
-
- If your function is using a special variable as an implicit argument,
- it's good to put in a CHECK-TYPE
for the special variable,
- for two reasons:
- to clue in the person reading the code
- that this variable is being used implicitly as an argument,
- and also to help detect bugs.
-
-
-
- Using (declare (type ...))
- is the least-desirable mechanism to use
- because, as Scott McKay puts it:
-
-
-
- The fact is, (declare (type ...))
does different things
- depending on the compiler settings of speed, safety, etc.
- In some compilers, when speed is greater than safety,
- (declare (type ...))
will tell the compiler
- "please assume that these variables have these types"
- without generating any type-checks.
- That is, if some variable has the value 1432
in it,
- and you declare it to be of type string
,
- the compiler might just go ahead and use it as though it's a string.
-
-
- Moral: don't use (declare (type ...))
- to declare the contract of any API functions,
- it's not the right thing.
- Sure, use it for "helper" functions, but not API functions.
-
-
-
- You should, of course, use appropriate declarations
- in internal low-level functions
- where these declarations are used for optimization.
- When you do, however, see our recommendations for
- Unsafe Operations.
-
-
-
-
-
- Use CLOS appropriately.
-
-
-
- When a generic function is intended to be called from other
- modules (other parts of the code), there should be an
- explicit DEFGENERIC
form,
- with a :DOCUMENTATION
string
- explaining the generic contract of the function
- (as opposed to its behavior for some specific class).
- It's generally good to do explicit DEFGENERIC
forms,
- but for module entry points it is mandatory.
-
-
- When the argument list of a generic function includes
- &KEY
,
- the DEFGENERIC
should always explicitly list
- all of the keyword arguments that are acceptable,
- and explain what they mean.
- (Common Lisp does not require this, but it is good form,
- and it may avoid spurious warnings on SBCL.)
-
-
- You should avoid SLOT-VALUE
and WITH-SLOTS
,
- unless you absolutely intend to circumvent
- any sort of method combination that might be in effect for the slot.
- Rare exceptions include INITIALIZE-INSTANCE
- and PRINT-OBJECT
methods and
- accessing normally hidden slots in the low-level implementation of
- methods that provide user-visible abstractions.
- Otherwise, you should use accessors,
- WITH-ACCESSORS
-
-
-
- Accessor names generally follow a convention of
- <protocol-name>-<slot-name>
,
- where a "protocol" in this case loosely indicates
- a set of functions with well-defined behavior.
-
-
- 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
- Interface-Passing Style 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.
-
-
- For example, if there were a notional protocol called
- is pnr
with accessors pnr-segments
- and pnr-passengers
, then
- the classes air-pnr
, hotel-pnr
and
- car-pnr
could each reasonably implement
- methods for pnr-segments
and pnr-passengers
- as accessors.
-
-
- By default, an abstract base class name is used
- as the notional protocol name, so accessor names default
- to <class-name>-<slot-name>
;
- while such names are thus quite prevalent,
- this form is neither required nor even preferred.
- In general, it contributes to "symbol bloat",
- and in many cases has led to a proliferation of "trampoline" methods.
-
-
- Accessors named <slot-name>-of
should not be used.
-
-
- Explicit DEFGENERIC
forms should be used when there are
- (or it is anticipated that there will be)
- more than one DEFMETHOD
for that generic function.
- The reason is that the documentation for the generic function
- explains the abstract contract for the function,
- as opposed to explaining what an individual method does for
- some specific class(es).
-
-
- You must not use generic functions where there is no notional protocol.
- To put it more concretely,
- if you have more than one generic function that specializes its Nth argument,
- the specializing classes should all be descendants of a single class.
- Generic functions must not be used for "overloading",
- i.e. simply to use the same name for two entirely unrelated types.
-
-
- More precisely, it's not really
- whether they descend from a common superclass,
- but whether they obey the same "protocol".
- That is, the two classes should handle the same set of generic functions,
- as if there were an explicit DEFGENERIC
for each method.
-
-
- Here's another way to put it.
- Suppose you have two classes, A and B, and a generic function F.
- There are two methods for F,
- which dispatch on an argument being of types A and B.
- Is it plausible that there might be a function call somewhere
- in the program that calls F,
- in which the argument might sometimes, at runtime,
- be of class A and other times be of class B?
- If not, you probably are overloading and
- should not be using a single generic function.
-
-
- We allow one exception to this rule:
- it's OK to do overloading
- if the corresponding argument "means" the same thing.
- Typically one overloading allows an X object,
- and the other allows the name of an X object,
- which might be a symbol or something.
-
-
- You must not use MOP "intercessory" operations at runtime.
- You should not use MOP "intercessory" operations at compile-time.
- At runtime, they are at worst a danger, at best a performance issue.
- At compile-time, it is usually cleaner that
- macros should set things up the right way in one pass
- than have to require a second pass of fixups through intercession;
- but sometimes, fixups are necessary to resolve forward references,
- and intercession is allowed then.
- MOP intercession is a great tool for interactive development,
- and you may enjoy it while developping and debugging;
- but you should not use it in normal applications.
-
-
- If a class definition creates a method
- as a :READER
, :WRITER
,
- or :ACCESSOR
,
- do not redefine that method.
- It's OK to add :BEFORE
, :AFTER
,
- and :AROUND
methods,
- but don't override the primary method.
-
-
- In methods with keyword arguments,
- you must always use &KEY
,
- even if the method does not care about the values of any keys,
- and you should never use &ALLOW-OTHER-KEYS
.
- As long as a keyword is accepted by any method of a generic function,
- it's OK to use it in the generic function,
- even if the other methods of the same generic function
- don't mention it explicitly.
- This is particularly important
- for INITIALIZE-INSTANCE
methods,
- since if you did use &ALLOW-OTHER-KEYS
,
- it would disable error checking for misspelled or wrong keywords
- in MAKE-INSTANCE
calls!
-
-
-
- A typical PRINT-OBJECT
method might look like this:
-
-
- (defmethod print-object ((p person) stream)
- (print-unprintable-object (p stream :type t :identity t)
- (with-slots (first-name last-name) p
- (safe-format stream "~a ~a" first-name last-name))))
-
-
-
-
-
-
-
-
- Use macros when appropriate, which is often.
- Define macros when appropriate, which is seldom.
-
-
-
- Macros bring syntactic abstraction, which is a wonderful thing.
- It helps make your code clearer, by describing your intent
- without getting bogged in implementation details
- (indeed abstracting those details away).
- It helps make your code more concise and more readable,
- by eliminating both redundancy and irrelevant details.
- But it comes at a cost to the reader,
- which is learning a new syntactic concept for each macro.
- And so it should not be abused.
-
-
- The general conclusion is that there shouldn't be
- any recognizable design pattern
- in a good Common Lisp program.
- The one and only pattern is: use the language,
- which includes defining and using syntactic abstractions.
-
-
- Existing macros must be used
- whenever they make code clearer
- by conveying intent in a more concise way,
- which is often.
- When a macro is available in your project
- that expresses the concept you're using,
- you must not write the expansion rather than use the macro.
-
-
- New macros should be defined as appropriate,
- which should be seldom,
- for common macros have already been provided
- by the language and its various libraries,
- and your program typically only needs few new ones
- relative to its size.
-
-
- You should follow the OAOOM rule of thumb
- for deciding when to create a new abstraction,
- whether syntactic or not:
- if a particular pattern is used more than twice,
- it should probably be abstracted away.
- A more refined rule to decide when to use abstraction
- should take into account
- the benefit in term of number of uses and gain at each use,
- to the costs in term of having to get used to reading the code.
- For syntactic abstractions, costs and benefits to the reader
- is usually more important than costs and benefits to the writer,
- because good code is usually written once
- and read many times by many people
- (including the same programmer
- who has to maintain the program after having forgotten it).
- Yet the cost to the writer of the macro
- should also be taken into account;
- however, in doing so it should rather be compared
- to the cost of the programmer writing other code instead
- that may have higher benefits.
-
-
- Using Lisp macros properly requires taste.
- Avoid writing complicated macros
- unless the benefit clearly outweighs the cost.
- It takes more effort for your fellow developers to learn your macro,
- so you should only use a macro if the gain in expressiveness
- is big enough to justify that cost.
- As usual, feel free to consult your colleagues if you're not sure,
- since without a lot of Lisp experience,
- it can be hard to make this judgment.
-
-
- You must never use a macro where a function will do.
- That is, if the semantics of what you are writing
- conforms to the semantics of a function,
- then you must write it as a function rather than a macro.
-
-
- You must not transform a function into a macro for performance reasons.
- If profiling shows that you have a performance problem
- with a specific function FOO
,
- document the need and profiling-results appropriately,
- and
- (declaim (inline foo))
.
-
-
-
- You can also use a compiler-macro
- as a way to speed up function execution
- by specifying a source-to-source transformation.
- Beware that it interferes with tracing the optimized function.
-
-
- When you write a macro-defining macro
- (a macro that generates macros),
- document and comment it particularly clearly,
- since these are harder to understand.
-
-
- You must not install new reader macros
- without a consensus among the developers of your system.
- Reader macros must not leak out of the system that uses them
- to clients of that system or other systems used in the same project.
- You must use software such as
- cl-syntax
or named-readtables
- to control how reader macros are used.
- This clients who desire it may use the same reader macros as you do.
- In any case, your system must be usable
- even to clients who do not use these reader macros.
-
-
- If your macro has a parameter that is a Lisp form
- that will be evaluated when the expanded code is run,
- you should name the parameter with the suffix -form
.
- This convention helps make it clearer to the macro's user
- which parameters are Lisp forms to be evaluated, and which are not.
- The common names body
and end
are
- exceptions to this rule.
-
-
- You should follow the so-called CALL-WITH
style when it applies.
- This style is explained at length in
- http://random-state.net/log/3390120648.html.
- The general principle is that the macro is strictly limited to processing the syntax,
- and as much of the semantics as possible is kept in normal functions.
- Therefore, a macro WITH-FOO
is often limited to
- generating a call to an auxiliary function
- CALL-WITH-FOO
- with arguments deduced from the macro arguments.
- Macro &body
arguments are typically
- wrapped into a lambda expression of which they become the body,
- which is passed as one of the arguments of the auxiliary function.
-
-
- The separation of syntactic and semantic concerns
- is a general principle of style that applies
- beyond the case of WITH-
macros.
- Its advantages are many.
- By keeping semantics outside the macro,
- the macro is made simpler, easier to get right, and less subject to change,
- which makes it easier to develop and maintain.
- The semantics is written in a simpler language — one without staging —
- which also makes it easier to develop and maintain.
- It becomes possible to debug and update the semantic function
- without having to recompile all clients of the macro.
- The semantic function appears in the stack trace
- which also helps debug client functions.
- The macro expansion is made shorter and
- each expansion shares more code with other expansions,
- which reduces memory pressure which in turn usually makes things faster.
- It also makes sense to write the semantic functions first,
- and write the macros last as syntactic sugar on top.
- You should use this style unless the macro is used
- in tight loops where performance matters;
- and even then, see our rules regarding optimization.
-
-
- Any functions (closures) created by the macro should be named,
- which can be done using FLET
.
-
- This also allows you to declare the function to be of dynamic extent
- (if it is — and often it is; yet see below regarding
- DYNAMIC-EXTENT).
-
-
- If a macro call contains a form,
- and the macro expansion includes more than one copy of that form,
- the form can be evaluated more than once,
- and code it contains macro-expanded and compiled more than once.
- If someone uses the macro and calls it
- with a form that has side effects or that takes a long time to compute,
- the behavior will be undesirable
- (unless you're intentionally writing
- a control structure such as a loop).
- A convenient way to avoid this problem
- is to evaluate the form only once,
- and bind a (generated) variable to the result.
- There is a very useful macro called ALEXANDRIA:ONCE-ONLY
- that generates code to do this.
- See also ALEXANDRIA:WITH-GENSYMS
,
- to make some temporary variables in the generated code.
- Note that if you follow our CALL-WITH
style,
- you typically expand the code only once, as either
- an argument to the auxiliary function, or
- the body of a lambda passed as argument to it;
- you therefore avoid the above complexity.
-
-
- When you write a macro with a body,
- such as a WITH-xxx
macro,
- even if there aren't any parameters,
- you should leave space for them anyway.
- For example, if you invent WITH-LIGHTS-ON
,
- do not make the call to it look like
- (defmacro with-lights-on (&body b) ...)
.
- Instead, do (defmacro with-lights-on (() &body b) ...)
.
- That way, if parameters are needed in the future,
- you can add them without necessarily having to change
- all the uses of the macro.
-
-
-
-
-
- When using EVAL-WHEN
, you should almost always use all of
- (:compile-toplevel :load-toplevel :execute)
.
-
-
-
- Lisp evaluation happens at several times,
- some of them interleaved.
- Be aware of them when writing macros.
- EVAL-WHEN considered harmful to your mental health.
-
-
- In summary of the article linked above,
- unless you're doing truly advanced macrology,
- the only valid combination in an EVAL-WHEN
- is to include all of
- (eval-when (:compile-toplevel :load-toplevel :execute) ...)
-
-
- You must use
- (eval-when (:compile-toplevel :load-toplevel :execute) ...)
- whenever you define functions, types, classes, constants, variables, etc.,
- that are going to be used in macros.
-
-
- It is usually an error to omit the :execute
,
- because it prevents LOAD
ing the source rather than the fasl.
- It is usually an error to omit the :load-toplevel
- (except to modify e.g. readtables and compile-time settings),
- because it prevents LOAD
ing future files
- or interactively compiling code
- that depends on the effects that happen at compile-time,
- unless the current file was COMPILE-FILE
d
- within the same Lisp session.
-
-
- Regarding variables, note that because macros may or may not
- be expanded in the same process that runs the expanded code,
- you must not depend on compile-time and runtime effects
- being either visible or invisible at the other time.
- There are still valid uses of variables in macros:
-
-
- -
- Some variables may hold dictionaries
- for some new kind of definition and other meta-data.
- If such meta-data is to be visible at runtime and/or in other files,
- you must make sure that the macro expands into code that
- will register the definitions to those meta-data structures
- at load-time,
- in addition to effecting the registration at compile-time.
- Typically, your top-level definitions expand
- to code that does the registration.
- if your code doesn't expand at the top-level,
- you can sometimes use
LOAD-TIME-VALUE
for good effect.
- In extreme cases, you may have to use
- ASDF-FINALIZERS:EVAL-AT-TOPLEVEL
.
-
- -
- Some variables may hold temporary data
- that is only used at compile-time in the same file,
- and can be cleaned up at the end of the file's compilation.
- Predefined such variables would include
*readtable*
- or compiler-internal variables holding
- the current optimization settings.
- You can often manage existing and new such variables using
- the :AROUND-COMPILE
hooks of ASDF
.
-
-
-
-
-
-
- You should use #.
sparingly,
- and you must avoid read-time side-effects.
-
-
-
- The #.
standard read-macro
- will read one object, evaluate the object, and
- have the reader return the resulting value.
-
-
- You must not use it where other idioms will do, such as
- using EVAL-WHEN
to evaluate side-effects at compile-time,
- using a regular macro to return an expression computed at compile-time,
- using LOAD-TIME-VALUE
to compute it at load-time.
-
-
- Read-time evaluation is often used as a quick way
- to get something evaluated at compile time
- (actually "read time" but it amounts to the same thing).
- If you use this, the evaluation MUST NOT have any side effects
- and MUST NOT depend on any variable global state.
- The #.
should be treated as a way
- to force "constant-folding"
- that a sufficiently-clever compiler
- could have figure out all by itself,
- when the compiler isn't sufficiently-clever
- and the difference matters.
-
-
- Another use of #.
is to expand the equivalent of macros
- in places that are neither expressions nor (quasi)quotations,
- such as lambda-lists. However, if you find yourself using it a lot,
- it might be time to instead define macros to replace your consumers
- of lambda-lists with something that recognizes an extension.
-
-
- Whenever you are going to use #.
,
- you should consider using DEFCONSTANT
and its variants,
- possibly in an EVAL-WHEN
,
- to give the value a name explaining what it means.
-
-
-
-
-
- You must not use EVAL
at runtime.
-
-
-
- Places where it is actually appropriate to use EVAL
- are so few and far between that you must consult with your reviewers;
- it's easily misused.
-
-
- If your code manipulates symbols at runtime
- and needs to get the value of a symbol,
- use SYMBOL-VALUE
, not EVAL
.
-
-
- Often, what you really need is to write a macro,
- not to use EVAL
.
-
-
- You may be tempted to use EVAL
as a shortcut
- to evaluating expressions in a safe subset of the language.
- But it often requires more scrutiny to properly check and sanitize
- all possible inputs to such use of EVAL
- than to build a special-purpose evaluator.
- You must not use EVAL
in this way at runtime.
-
-
- Places where it is OK to use EVAL
are:
-
-
- -
- The implementation of an interactive development tool.
-
- -
- The build infrastructure.
-
- -
- Backdoors that are part of testing frameworks.
- (You MUST NOT have such backdoors in production code.)
-
- -
- Macros that fold constants at compile-time.
-
- -
- Macros that register definitions to meta-data structures;
- the registration form is sometimes evaluated at compile-time
- as well as included in the macro-expansion,
- so it is immediately available to other macros.
-
-
-
- Note that in the latter case,
- if the macro isn't going to be used at the top-level,
- it might not be possible to make these definitions available
- as part of the expansion.
- The same phenomenon may happen in a DEFTYPE
expansion,
- or in helper functions used by macros.
- In these cases, you may actually have to use
- ASDF-FINALIZERS:EVAL-AT-TOPLEVEL
in your macro.
- It will not only EVAL
your definitions
- at macro-expansion time for immediate availability,
- it will also save the form aside, for inclusion in a
- (ASDF-FINALIZERS:FINAL-FORMS)
- that you need to include at the end of the file being compiled
- (or before the form is needed).
- This way, the side-effects are present when loading the fasl
- without having compiled it as well as while compiling it;
- in either case, the form is made available at load-time.
- ASDF-FINALIZERS
ensures that the form is present,
- by throwing an error if you omit it.
-
-
-
-
-
- You must not use INTERN
or UNINTERN
at runtime.
-
-
-
- You must not use INTERN
at runtime.
- Not only does it cons,
- it either creates a permanent symbol that won't be collected
- or gives access to internal symbols.
- This creates opportunities for memory leaks, denial of service attacks,
- unauthorized access to internals, clashes with other symbols.
-
-
- You must not INTERN
a string
- just to compare it to a keyword;
- use STRING=
or STRING-EQUAL
.
-
-
- (member (intern str :keyword) $keys) ; Bad
-
-
- (member str $keys :test #'string-equal) ; Better
-
-
- You must not use UNINTERN
at runtime.
- It can break code that relies on dynamic binding.
- It makes things harder to debug.
- You must not dynamically intern any new symbol,
- and therefore you need not dynamically unintern anything.
-
-
- You may of course use INTERN
at compile-time,
- in the implementation of some macros.
- Even so, it is usually more appropriate
- to use abstractions on top of it, such as
- ALEXANDRIA:SYMBOLICATE
or
- ALEXANDRIA:FORMAT-SYMBOL
- to create the symbols you need.
-
-
-
-
-
-
-
-
-
- Appropriately use or avoid using NIL
.
-
-
-
- NIL
can have several different interpretations:
-
-
- -
- "False."
- In this case, use
NIL
.
- You should test for false NIL
- using the operator NOT
or
- using the predicate function NULL
.
-
- -
- "Empty-list."
- In this case, use
'()
.
- (Be careful about quoting the empty-list when calling macros.)
- You should use ENDP
to test for the empty list
- when the argument is known to be a proper list,
- or with NULL
otherwise.
-
- -
- A statement about some value being unspecified.
- In this case, you may use
NIL
- if there is no risk of ambiguity anywhere in your code;
- otherwise you should use an explicit, descriptive symbol.
-
- -
- A statement about some value being known not to exist.
- In this case, you should use an explicit, descriptive symbol
- instead of
NIL
.
-
-
-
- You must not introduce ambiguity in your data representations
- that will cause headaches for whoever has to debug code.
- If there is any risk of ambiguity,
- you should use an explicit, descriptive symbol or keyword
- for each case,
- instead of using NIL
for either.
- If you do use NIL
,
- you must make sure that the distinction is well documented.
-
-
- In many contexts,
- instead of representing "I don't know" as a particular value,
- you should instead use multiple values,
- one for the value that is known if any,
- and one to denote whether the value was known or found.
-
-
-
- When working with database classes, keep in mind that
- NIL
need not always map to 'NULL'
- (and vice-versa)!
- The needs of the database may differ from the needs of the Lisp.
-
-
-
-
-
- You must select proper data representation.
- You must not abuse the LIST
data structure.
-
-
-
- Even though back in 1958, LISP was short for "LISt Processing",
- its successor Common Lisp has been a modern programming language
- with modern data structures since the 1980s.
- You must use the proper data structures in your programs.
-
-
- You must not abuse the builtin (single-linked) LIST
- data structure where it is not appropriate,
- even though Common Lisp makes it especially easy to use it.
-
-
- You must only use lists
- when their performance characteristics
- is appropriate for the algorithm at hand:
- sequential iteration over the entire contents of the list.
-
-
- An exception where it is appropriate to use lists
- is when it is known in advance
- that the size of the list will remain very short
- (say, less than 16 elements).
-
-
- List data structures are often (but not always)
- appropriate for macros and functions used by macros at compile-time:
- indeed, not only is source code passed as lists in Common Lisp,
- but the macro-expansion and compilation processes
- will typically walk over the entire source code, sequentially, once.
- (Note that advanced macro systems don't directly use lists, but instead
- use abstract syntax objects that track source code location and scope;
- however there is no such advanced macro system
- in Common Lisp at this time.)
-
-
- Another exception where it is appropriate to use lists is
- for introducing literal constants
- that will be transformed into more appropriate data structures
- at compile-time or load-time.
- It is a good to have a function with a relatively short name
- to build your program's data structures from such literals.
-
-
- In the many cases when lists are not the appropriate data structure,
- various libraries such as
- cl-containers or
- lisp-interface-library
- provide plenty of different data structures
- that should fulfill all the basic needs of your programs.
- If the existing libraries are not satisfactory, see above about
- Using Libraries and
- Open-Sourcing Code.
-
-
-
-
-
- You should use the appropriate representation for product types.
-
-
-
- You should avoid using a list as anything
- besides a container of elements of like type.
- You must not use a list as method of passing
- multiple separate values of different types
- in and out of function calls.
- Sometimes it is convenient to use a list
- as a little ad hoc structure,
- i.e. "the first element of the list is a FOO, and the second is a BAR",
- but this should be used minimally
- since it gets harder to remember the little convention.
- You must only use a list that way
- when destructuring the list of arguments from a function,
- or creating a list of arguments
- to which to APPLY
a function.
-
-
- The proper way to pass around an object
- comprising several values of heterogeneous types
- is to use a structure as defined by DEFSTRUCT
- or DEFCLASS
.
-
-
- You should use multiple values only
- when function returns a small number of values
- that are meant to be destructured immediately by the caller,
- rather than passed together as arguments to further functions.
-
-
- You should not return a condition object
- as one of a set of multiple values.
- Instead, you should signal the condition to denote an unusual outcome.
-
-
- You should signal a condition to denote an unusual outcome,
- rather than relying on a special return type.
-
-
-
-
-
- Use the appropriate functions when manipulating lists.
-
-
-
- Use FIRST
to access the first element of a list,
- SECOND
to access the second element, etc.
- Use REST
to access the tail of a list.
- Use ENDP
to test for the end of the list.
-
-
- Use CAR
and CDR
- when the cons cell is not being used to implement a proper list
- and is instead being treated as a pair of more general objects.
- Use NULL
to test for NIL
in this context.
-
-
- The latter case should be rare outside of alists,
- since you should be using structures and classes where they apply,
- and data structure libraries when you want trees.
-
-
- Exceptionally, you may use CDADR
and other variants
- on lists when manually destructuring them,
- instead of using a combination of several list accessor functions.
- In this context, using CAR
and CDR
- instead of FIRST
and REST
also makes sense.
- However, keep in mind that it might be more appropriate in such cases
- to use higher-level constructs such as
- DESTRUCTURING-BIND
or OPTIMA:MATCH
.
-
-
-
-
-
- You should use arrays rather than lists where random access matters.
-
-
-
- ELT
has O(n) behavior when used on lists.
- If you are to use random element access on an object,
- use arrays and AREF
instead.
-
-
- The exception is for code outside the critical path
- where the list is known to be small anyway.
-
-
-
-
-
- You should only use lists as sets for very small lists.
-
-
-
- Using lists as representations of sets is a bad idea
- unless you know the lists will be small,
- for accessors are O(n) instead of O(log n).
- For arbitrary big sets, use balanced binary trees,
- for instance using lisp-interface-library
.
-
-
- If you still use lists as sets,
- you should not UNION
lists just to search them.
-
-
- (member foo (union list-1 list-2)) ; Bad
-
-
- (or (member foo list-1) (member foo list-2)) ; Better
-
-
- Indeed, UNION
not only conses unnecessarily,
- but it can be O(n^2) on some implementations,
- and is rather slow even when it's O(n).
-
-
-
-
-
-
-
- You must follow the proper usage regarding
- well-known functions, macros and special forms.
-
-
-
- You must use proper defining forms for constant values.
-
-
-
- The Lisp system we primarily use, SBCL, is very picky and
- signals a condition whenever a constant is redefined to a value not
- EQL
to its previous setting.
- You must not use DEFCONSTANT
- when defining variables that are not
- numbers, characters, or symbols (including booleans and keywords).
- Instead, consistently use whichever alternative
- is recommended for your project.
-
-
- ;; Bad
- (defconstant +google-url+ "http://www.google.com/")
- (defconstant +valid-colors+ '(red green blue))
-
-
-
-
-
-
- Open-Source libraries may use
- ALEXANDRIA:DEFINE-CONSTANT
- for constants other than numbers, characters and symbols
- (including booleans and keywords).
- You may use the :TEST
keyword argument
- to specify an equality predicate.
-
-
- ;; Better, for Open-Source code:
- (define-constant +google-url+ "http://www.google.com/" :test #'string=)
- (define-constant +valid-colors+ '(red green blue))
-
-
- Note that with optimizing implementations, such as SBCL or CMUCL,
- defining constants this way precludes any later redefinition
- short of UNINTERN
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
- DEFPARAMETER
or DEFVAR
instead,
- or possibly a variant of DEFINE-CONSTANT
- that builds upon some future library implementing global lexicals
- rather than DEFCONSTANT
.
- You may keep the +plus+
convention in these cases
- to document the intent of the parameter as a constant.
-
-
- Also note that LOAD-TIME-VALUE
may help you
- avoid the need for defined constants.
-
-
-
-
-
- You should make proper use of
- &OPTIONAL
and
- &KEY
arguments.
- You should not use &AUX
arguments.
-
-
-
- You should avoid using &ALLOW-OTHER-KEYS
,
- since it blurs the contract of a function.
- Almost any real function (generic or not) allows a certain
- fixed set of keywords, as far as its caller is concerned,
- and those are part of its contract.
- If you are implementing a method of a generic function,
- and it does not need to know
- the values of some of the keyword arguments,
- you should explicitly (DECLARE (IGNORE ...))
- all the arguments that you are not using.
- You must not use &ALLOW-OTHER-KEYS
- unless you explicitly want to disable checking of allowed keys
- for all methods when invoking the generic function on arguments
- that match this particular method.
- Note that the contract of a generic function belongs in
- the DEFGENERIC
, not in the DEFMETHOD
- which is basically an "implementation detail" of the generic function
- as far as the caller of the generic is concerned.
-
-
- A case where &ALLOW-OTHER-KEYS
is appropriate
- is when you write a wrapper function to other some other functions
- that may vary (within the computation or during development),
- and pass around a plist as a &REST
argument.
-
-
- You should avoid using &AUX
arguments.
-
-
- You should avoid having both &OPTIONAL
- and &KEY
arguments,
- unless it never makes sense to specify keyword arguments
- when the optional arguments are not all specified.
- You must not have non-NIL
defaults
- to your &OPTIONAL
arguments
- when your function has both &OPTIONAL
- and &KEY
arguments.
-
-
- For maximum portability of a library, it is good form
- that DEFMETHOD
definitions should
- (DECLARE (IGNORABLE ...))
- all the required arguments that they are not using.
- Indeed, some implementations will issue a warning
- if you (DECLARE (IGNORE ...))
those arguments,
- whereas other implementations will issue a warning
- if you fail to (DECLARE (IGNORE ...))
them.
- (DECLARE (IGNORABLE ...))
works on all implementations.
-
-
- You should avoid excessive nesting of binding forms inside a function.
- If your function ends up with massive nesting,
- you should probably break it up into several functions or macros.
- If it is really a single conceptual unit,
- consider using a macro such as FARE-UTILS:NEST
- to at least reduce the amount of indentation required.
- It is bad form to use NEST
in typical short functions
- with 4 or fewer levels of nesting,
- but also bad form not to use it in the exceptional long functions
- with 10 or more levels of nesting.
- Use your judgment and consult your reviewers.
-
-
-
-
-
-
- Use the appropriate conditional form.
-
-
-
- Use WHEN
and UNLESS
- when there is only one alternative.
- Use IF
when there are two alternatives
- and COND
when there are several.
-
-
- However, don't use PROGN
for an IF
clause
- — use COND
, WHEN
, or UNLESS
.
-
-
- Note that in Common Lisp,
- WHEN
and UNLESS
return NIL
- when the condition is not met.
- You may take advantage of it.
- Nevertheless, you may use an IF
- to explicitly return NIL
- if you have a specific reason to insist on the return value.
- You may similarly include a fall-through clause (t nil)
- as the last in your COND ,
- or (otherwise nil)
as the last in your CASE ,
- to insist on the fact that the value returned by the conditional matters
- and that such a case is going to be used.
- You should omit the fall-through clause
- when the conditional is used for side-effects.
-
-
- You should prefer AND
and OR
- when it leads to more concise code than using
- IF
, COND
,
- WHEN
or UNLESS
,
- and there are no side-effects involved.
- You may also use an ERROR
- as a side-effect in the final clause of an OR
.
-
-
- You should only use CASE
and ECASE
- to compare numbers, characters or symbols
- (including booleans and keywords).
- Indeed, CASE
uses EQL
for comparisons,
- so strings, pathnames and structures may not compare the way you expect,
- and 1
will differ from 1.0
.
-
-
- You should use ECASE
and ETYPECASE
- in preference to CASE
and TYPECASE
.
- It is better to catch erroneous values early.
-
-
- You should not use CCASE
or CTYPECASE
at all.
- At least, you should not use them in server processes,
- unless you have quite robust error handling infrastructure
- and make sure not to leak sensitive data this way.
- These are meant for interactive use,
- and can cause interesting damage
- if they cause data or control to leak to attackers.
-
-
- You must not use gratuitous single quotes in CASE
forms.
- This is a common error:
-
-
- (case x ; Bad: silently returns NIL on mismatch
- ('bar :bar) ; Bad: catches QUOTE
- ('baz :baz)) ; Bad: also would catch QUOTE
-
-
- (ecase x ; Better: will error on mismatch
- ((bar) :bar) ; Better: won't match QUOTE
- ((baz) :baz)) ; Better: same reason
-
-
- 'BAR
there is (QUOTE BAR)
,
- meaning this leg of the case will be executed
- if X
is QUOTE
...
- and ditto for the second leg
- (though QUOTE
will be caught by the first clause).
- This is unlikely to be what you really want.
-
-
- In CASE
forms,
- you must use otherwise
instead of t
- when you mean "execute this clause if the others fail".
- You must use ((t) ...)
- when you mean "match the symbol T" rather than "match anything".
- You must also use ((nil) ...)
- when you mean "match the symbol NIL" rather than "match nothing".
-
-
- Therefore, if you want to map booleans NIL
and T
- to respective symbols :BAR
and :QUUX
,
- you should avoid the former way and do it the latter way:
-
-
- (ecase x ; Bad: has no actual error case!
- (nil :bar)) ; Bad: matches nothing
- (t :quux)) ; Bad: matches anything
-
-
- (ecase x ; Better: will actually catch non-booleans
- ((nil) :bar)) ; Better: matches NIL
- ((t) :quux)) ; Better: matches T
-
-
-
-
-
- You should the appropriate predicates when comparing objects.
-
-
-
- Lisp provides four general equality predicates:
- EQ
, EQL
, EQUAL
,
- and EQUALP
,
- which subtly vary in semantics.
- Additionally, Lisp provides the type-specific predicates
- =
, CHAR=
, CHAR-EQUAL
,
- STRING=
, and STRING-EQUAL
.
- Know the distinction!
-
-
- You should use EQL
to compare objects and symbols
- for identity.
-
-
- You must not use EQ
to compare numbers or characters.
- Two numbers or characters that are EQL
- are not required by Common Lisp to be EQ
.
-
-
- When choosing between EQ
and EQL
,
- you should use EQL
unless you are writing
- performance-critical low-level code.
- EQL
reduces the opportunity
- for a class of embarrassing errors
- (i.e. if numbers or characters are ever compared).
- There may a tiny performance cost relative to EQ
,
- although under SBCL, it often compiles away entirely.
- EQ
is equivalent to EQL
and type declarations,
- and use of it for optimization should be treated just like
- any such unsafe operations.
-
-
- You should use CHAR=
- for case-dependent character comparisons,
- and CHAR-EQUAL
for case-ignoring character comparisons.
-
-
- You should use STRING=
- for case-dependent string comparisons,
- and STRING-EQUAL
for case-ignoring string comparisons.
-
-
- A common mistake when using SEARCH
on strings
- is to provide STRING=
or STRING-EQUAL
- as the :TEST
function.
- The :TEST
function
- is given two sequence elements to compare.
- If the sequences are strings,
- the :TEST
function is called on two characters,
- so the correct tests are CHAR=
or CHAR-EQUAL
.
- If you use STRING=
or STRING-EQUAL
,
- the result is what you expect,
- but in some Lisp implementations it's much slower.
- CCL (at least as of 8/2008)
- creates a one-character string upon each comparison, for example,
- which is very expensive.
-
-
- Also, you should use :START
and :END
arguments
- to STRING=
or STRING-EQUAL
- instead of using SUBSEQ
;
- e.g. (string-equal (subseq s1 2 6) s2)
should instead be
- (string-equal s1 s2 :start1 2 :end1 6)
- This is preferable because it does not cons.
-
-
- You should use ZEROP
,
- PLUSP
, or MINUSP
,
- instead of comparing a value to 0
or 0.0
.
-
-
- You must not use exact comparison on floating point numbers,
- since the vague nature of floating point arithmetic
- can produce little "errors" in numeric value.
- You should compare absolute values to a threshhold.
-
-
- You must use =
to compare numbers,
- unless you really mean for 0
,
- 0.0
and -0.0
to compare unequal,
- in which case you should use EQL
.
- Then again, you must not usually use exact comparison
- on floating point numbers.
-
-
- Monetary amounts should be using decimal (rational) numbers
- to avoid the complexities and rounding errors
- of floating-point arithmetic.
- Libraries such as
- wu-decimal
- may help you;
- once again, if this library is not satisfactory, see above about
- Using Libraries and
- Open-Sourcing Code.
-
-
-
-
-
-
- Use the appropriate form for iteration.
-
-
-
- You should simpler forms such as
- DOLIST
or DOTIMES
- instead of LOOP
- in simple cases when you're not going to use any
- of the LOOP
facilities such as
- bindings, collection or block return.
-
-
- Use the WITH
clause of LOOP
- when it will avoid a level of nesting with LET
.
- You may use LET
if it makes it clearer
- to return one of bound variables after the LOOP
,
- rather than use a clumsy FINALLY (RETURN ...)
form.
-
-
- In the body of a DOTIMES
,
- do not set the iteration variable.
- (CCL will issue a compiler warning if you do.)
-
-
- Most systems use unadorned symbols in the current package
- as LOOP
keywords.
- Other systems use actual :keywords
- from the KEYWORD
package
- as LOOP
keywords.
- You must be consistent with the convention used in your system.
-
-
-
-
-
- Use the appropriate I/O functions.
-
-
-
- When writing a server,
- code must not send output to the standard streams such as
- *STANDARD-OUTPUT*
or *ERROR-OUTPUT*
.
- Instead, code must use the proper logging framework
- to output messages for debugging.
- We are running as a server, so there is no console!
-
-
- Code must not use PRINT-OBJECT
- to communicate with a user —
- PRINT-OBJECT
is for debugging purposes only.
- Modifying any PRINT-OBJECT
method
- must not break any public interfaces.
-
-
- You should not use a sequence of WRITE-XXX
- where a single FORMAT
string could be used.
- Using format allows you
- to parameterize the format control string in the future
- if the need arises.
-
-
- You should use WRITE-CHAR
to emit a character
- rather than WRITE-STRING
- to emit a single-character string.
-
-
- You should not use (format nil "~A" value)
;
- you should use PRINC-TO-STRING
instead.
-
-
- You should use ~<Newline>
- or ~@<Newline>
in format strings
- to keep them from wrapping in 100-column editor windows,
- or to indent sections or clauses to make them more readable.
-
-
- You should not use STRING-UPCASE
- or STRING-DOWNCASE
- on format control parameters;
- instead, it should use "~:@(~A~)"
or "~(~A~)"
.
-
-
- Be careful when using the FORMAT
conditional directive.
- The parameters are easy to forget.
-
-
- - No parameters, e.g.
"~[Siamese~;Manx~;Persian~] Cat"
- -
- Take one format argument, which should be an integer.
- Use it to choose a clause. Clause numbers are zero-based.
- If the number is out of range, just print nothing.
- You can provide a default value
- by putting a
":"
in front of the last ";"
.
- E.g. in "~[Siamese~;Manx~;Persian~:;Alley~] Cat"
,
- an out-of-range arg prints "Alley"
.
-
- :
parameter, e.g. "~:[Siamese~;Manx~]"
- -
- Take one format argument. If it's
NIL
,
- use the first clause, otherwise use the second clause.
-
- @
parameter, e.g. "~@[Siamese ~a~]"
- -
- If the next format argument is true,
- use the choice, but do NOT take the argument.
- If it's false, take one format argument and print nothing.
- (Normally the clause uses the format argument.)
-
- #
parameter, e.g. "~#[ none~; ~s~; ~s and ~s~]"
- -
- Use the number of arguments to format
- as the number to choose a clause.
- The same as no parameters in all other ways.
- Here's the full hairy example:
-
"Items:~#[ none~; ~S~; ~S and ~S~:;~@{~#[~; and~] ~S~^ ,~}~]."
-
-
-
-
-
-
-
-
-
- You should avoid unnecessary allocation of memory.
-
-
-
- In a language with automatic storage management (such as Lisp or Java),
- the colloquial phrase "memory leak" refers to situation
- where storage that is not actually needed
- nevertheless does not get deallocated,
- because it is still reachable.
-
-
- You should be careful that when you create objects,
- you don't leave them reachable after they are no longer needed!
-
-
- Here's a particular trap-for-the-unwary in Common Lisp.
- If you make an array with a fill pointer, and put objects in it,
- and then set the fill pointer back to zero,
- those objects are still reachable as far as Lisp goes
- (the Common Lisp spec says that it's still OK
- to refer to the array entries past the end of the fill pointer).
-
-
- Don't cons (i.e., allocate) unnecessarily.
- Garbage collection is not magic.
- Excessive allocation is usually a performance problem.
-
-
-
-
-
- You must only use faster unsafe operations
- when there is a clear performance need
- and you can document why it's correct.
-
-
-
- Common Lisp implementations often provide backdoors
- to compute some operations faster in an unsafe way.
- For instance, some libraries provide arithmetic operations
- that are designed to be used with fixnums only,
- and yield the correct result faster if provided proper arguments.
- The downside is that the result of such operations
- is incorrect in case of overflow, and can
- have undefined behavior when called with anything but fixnums.
-
-
-
- More generally, unsafe operations
- will yield the correct result faster
- than would the equivalent safe operation
- if the arguments satisfy some invariant such as
- being of the correct type and small enough;
- however if the arguments fail to satisfy the required invariants,
- then the operation may have undefined behavior,
- such as crashing the software, or,
- which is sometimes worse, silently giving wrong answers.
- Depending on whether the software is piloting an aircraft
- or other life-critical device,
- or whether it is accounting for large amounts money,
- such undefined behavior can kill or bankrupt people.
- Yet proper speed can sometimes make the difference between
- software that's unusably slow and software that does its job,
- or between software that is a net loss
- and software that can yield a profit.
-
-
- You must not define or use unsafe operations without both
- profiling results indicating the need for this optimization,
- and careful documentation explaining why it is safe to use them.
- Unsafe operations should be restricted to internal functions;
- you should carefully documented how unsafe it is
- to use these functions with the wrong arguments.
- You should only use unsafe operations
- inside functions internal to a package and
- you should document the use of the declarations,
- since calling the functions with arguments of the wrong type
- can lead to undefined behavior.
- Use check-type
in functions exported from a package
- to sanitize input arguments,
- so that internal functions are never passed illegal values.
-
-
- On some compilers,
- new unsafe operations
- can usually be defined by combining
- type declarations with an OPTIMIZE
declaration
- that has sufficiently high SPEED
and low SAFETY
.
- In addition to providing more speed for production code,
- such declarations may more helpful
- than check-type
assertions
- for finding bugs at compile-time,
- on compilers that have type inference.
- These compilers may interpret those declarations as assertions
- if you switch to safer and slower optimize settings;
- this is good to locate a dynamic error in your code during development,
- but is not to be used for production code since
- it defeats the purpose of declarations as a performance trick.
-
-
-
-
-
-
- You should only use DYNAMIC-EXTENT
- where it matters for performance,
- and you can document why it is correct.
-
-
-
- DYNAMIC-EXTENT
declarations are
- a particular case of
- unsafe operations.
-
-
- The purpose of a DYNAMIC-EXTENT
declaration
- is to improve performance by reducing garbage collection
- in cases where it appears to be obvious that an object's lifetime
- is within the "dynamic extent" of a function.
- That means the object is created at some point
- after the function is called, and
- the object is always inaccessible after the function exits by any means.
-
-
- By declaring a variable or a local function DYNAMIC-EXTENT
,
- the programmer asserts to Lisp
- that any object that is ever a value of that variable
- or the closure that is the definition of the function
- has a lifetime within the dynamic extent of the (innermost) function
- that declares the variable.
-
-
- The Lisp implementation is then free to use that information
- to make the program faster.
- Typically, Lisp implementations can take advantage of this knowledge
- to stack-allocate:
-
-
- -
- The lists created to store
&REST
parameters.
-
- -
- Lists, vectors and structures allocated within a function.
-
- -
- Closures.
-
-
-
- If the assertion is wrong, i.e. if the programmer's claim is not true,
- the results can be catastrophic:
- Lisp can terminate any time after the function returns,
- or it can hang forever, or — worst of all —
- it can produce incorrect results without any runtime error!
-
-
- Even if the assertion is correct,
- future changes to the function might introduce
- a violation of the assertion.
- This increases the danger.
-
-
- In most cases, such objects are ephemeral.
- Modern Lisp implementations use generational garbage collectors,
- which are quite efficient under these circumstances.
-
-
- Therefore, DYNAMIC-EXTENT
declarations
- should be used sparingly. You must only use them if:
-
-
- -
- There is some good reason to think that the overall effect
- on performance is noticeable, and
-
- -
- It is absolutely clear that the assertion is true.
-
- -
- It is quite unlikely that the code will be changed
- in ways that cause the declaration to become false.
-
-
-
- Point (1) is a special case of
- the principle of avoiding premature optimization.
- An optimization like this only matters if such objects
- are allocated at a very high rate, e.g. "inside an inner loop".
-
-
- Note that is relatively easy to ascertain that
- a function will not escape the dynamic extent of the current call frame
- by analyzing where the function is called and
- what other functions it is passed to;
- therefore, you should somewhat wary of declaring a function
- DYNAMIC-EXTENT
, but this is not a high-stress declaration.
- On the other hand, it is much harder to ascertain that
- none of the objects ever bound or assigned to that variable
- and none of their sub-objects
- will escape the dynamic extent of the current call frame,
- and that they still won't in any future modification of a function.
- Therefore, you should be extremely wary
- of declaring a variable DYNAMIC-EXTENT
.
-
-
- It's usually hard to predict the effect of such optimization on performance.
- When writing a function or macro
- that is part of a library of reusable code,
- there's no a priori way to know how often the code will run.
- Ideally, tools would be available to discover
- the availability and suitability of using such an optimization
- based on running simulations and test cases, but
- in practice this isn't as easy as it ought to be.
- It's a tradeoff.
- If you're very, very sure that the assertion is true
- (that any object bound to the variable and any of its sub-objects
- are only used within the dynamic extent of the specified scope),
- and it's not obvious how much time will be saved
- and it's not easy to measure,
- then it may be better to put in the declaration than to leave it out.
- (Ideally it would be easier to make such measurements
- than it actually is.)
-
-
-
-
-
- You should use REDUCE
- instead of APPLY
where appropriate.
-
-
-
- You should use REDUCE
- instead of APPLY
and a consed-up list,
- where the semantics of the first operator argument
- otherwise guarantees the same semantics.
- Of course, you must use APPLY
- if it does what you want and REDUCE
doesn't.
- For instance:
-
-
- ;; Bad
- (apply #'+ (mapcar #'acc frobs))
-
-
- ;; Better
- (reduce #'+ frobs :key #'acc :initial-value 0)
-
-
- This is preferable because it does not do extra consing,
- and does not risk going beyond CALL-ARGUMENTS-LIMIT
- on implementations where that limit is small,
- which could blow away the stack on long lists
- (we want to avoid gratuitous non-portability in our code).
-
-
- However, you must be careful not to use REDUCE
- in ways that needlessly increase
- the complexity class of the computation.
- For instance, (REDUCE 'STRCAT ...)
is O(n^2)
- when an appropriate implementation is only O(n).
- Moreover, (REDUCE 'APPEND ...)
- is also O(n^2) unless you specify :FROM-END T
.
- In such cases, you MUST NOT use REDUCE
,
- and you MUST NOT use (APPLY 'STRCAT ...)
- or (APPLY 'APPEND ...)
either.
- Instead you MUST use proper abstractions
- from a suitable library (that you may have to contribute to)
- that properly handles those cases
- without burdening users with implementation details.
- See for instance UIOP:REDUCE/STRCAT
.
-
-
-
-
-
-
- You should not use NCONC
;
- you should use APPEND
instead,
- or better, better data structures.
-
-
-
- You should almost never use NCONC
.
- You should use APPEND
- when you don't depend on any side-effect.
- You should use ALEXANDRIA:APPENDF
- when you need to update a variable.
- You should probably not depend on games
- being played with the CDR
- of the current CONS cell
- (which some might argue is suggested but not guaranteed by the specification);
- if you do, you must include a prominent
- comment explaining the use of NCONC
;
- and you should probably reconsider your data representation strategy.
-
-
- By extension, you should avoid MAPCAN
- or the NCONC
feature of LOOP
.
- You should instead respectively use
- ALEXANDRIA:MAPPEND
- and the APPEND
feature of LOOP
.
-
-
- NCONC
is very seldom a good idea,
- since its time complexity class is no better than APPEND
,
- its space complexity class also is no better than APPEND
- in the common case where no one else is sharing the side-effected list,
- and its bug complexity class is way higher than APPEND
.
-
-
- If the small performance hit due
- to APPEND
vs. NCONC
- is a limiting factor in your program,
- you have a big problem and are probably using the wrong data structure:
- you should be using sequences with constant-time append
- (see Okasaki's book, and add them to lisp-interface-library),
- or more simply you should be accumulating data in a tree
- that will get flattened once in linear time
- after the accumulation phase is complete.
-
-
- You may only use NCONC
, MAPCAN
- or the NCONC
feature of LOOP
- in low-level functions where performance matters,
- where the use of lists as a data structure has been vetted
- because these lists are known to be short,
- and when the function or expression the result of which are accumulated
- explicitly promises in its contract that it only returns fresh lists
- (in particular, it can't be a constant quote or backquote expression).
- Even then, the use of such primitives must be rare,
- and accompanied by justifying documentation.
-
-
-
-
-
-
-
-
- You should usually refer to a function as #'FUN
rather than 'FUN
.
-
-
-
- The former, which reads as (FUNCTION FUN)
,
- refers to the function object, and is lexically scoped.
- The latter, which reads as (QUOTE FUN)
,
- refers to the symbol, which when called
- uses the global FDEFINITION
of the symbol.
-
-
- When using functions that take a functional argument
- (e.g., MAPCAR
, APPLY
,
- :TEST
and :KEY
arguments),
- you should use the #'
to refer to the function,
- not just single quote.
-
-
- An exception is when you explicitly want dynamic linking,
- because you anticipate that
- the global function binding will be updated.
-
-
- Another exception is when you explicitly want to access
- a global function binding,
- and avoid a possible shadowing lexical binding.
- This shouldn't happen often, as it is usually a bad idea
- to shadow a function when you will want to use the shadowed function;
- just use a different name for the lexical function.
-
-
- You must consistently use either #'(lambda ...)
- or (lambda ...)
without #'
everywhere.
- Unlike the case of #'symbol
vs 'symbol
,
- it is only a syntactic difference with no semantic impact,
- except that the former works on Genera and the latter doesn't.
-
- You must use the former style if your code is intended as a library
- with maximal compatibility to all Common Lisp implementations;
- otherwise, it is optional which style you use.
- #'
may be seen as a hint
- that you're introducing a function in expression context;
- but the lambda
itself is usually sufficient hint,
- and concision is good.
- Choose wisely, but above all,
- consistently with yourself and other developers,
- within a same file, package, system, project, etc.
-
-
- Note that if you start writing a new system
- in a heavily functional style,
- you may consider using
- lambda-reader,
- a system that lets you use the unicode character λ
- instead of LAMBDA
.
- But you must not start using such a syntactic extension
- in an existing system without getting permission from other developers.
-
-
-
-
-
- Common Lisp pathnames are tricky. Be aware of pitfalls. Use UIOP
.
-
-
-
- It is surprisingly hard to properly deal with pathnames in Common Lisp.
-
-
- ASDF 3
comes with a portability library UIOP
- that makes it much easier to deal with pathnames
- portably — and correctly — in Common Lisp.
- You should use it when appropriate.
-
-
- First, be aware of the discrepancies between
- the syntax of Common Lisp pathnames,
- which depends on which implementation and operating system
- you are using,
- and the native syntax of pathnames on your operating system.
- The Lisp syntax may involves quoting of special characters
- such as #\.
and #\*
, etc.,
- in addition to the quoting of
- #\\
and #\"
within strings.
- By contrast, your operating system's other
- system programming languages
- (shell, C, scripting languages)
- may only have one layer of quoting, into strings.
-
-
- Second, when using MERGE-PATHNAMES
,
- be wary of the treatment of the HOST
component,
- which matters a lot on non-Unix platforms
- (and even on some Unix implementations).
- You probably should be using
- UIOP:MERGE-PATHNAMES*
or UIOP:SUBPATHNAME
- instead of MERGE-PATHNAMES
,
- especially if your expectations for relative pathnames
- are informed by the way they work in Unix or Windows;
- otherwise you might hit weird bugs whereby on some implementations,
- merging a relative pathnames with an absolute pathname
- results in overriding the absolute pathname's host
- and replace it with the host from the value of
- *DEFAULT-PATHNAME-DEFAULTS*
- at the time the relative pathname was created.
-
-
- Third, be aware that DIRECTORY
- is not portable across implementations
- in how it handles wildcards, sub-directories, symlinks, etc.
- There again, UIOP
provides several
- common abstractions to deal with pathnames,
- but only does so good a job.
- For a complete portable solution, use IOLib —
- though its Windows support lags behind.
-
-
- LOGICAL-PATHNAME
s are not a portable abstraction,
- and should not be used in portable code.
- Many implementations have bugs in them, when they are supported at all.
- SBCL implements them very well,
- but strictly enforces the limitations on characters
- allowed by the standard, which restricts their applicability.
- Other implementations allow arbitrary characters in such pathnames,
- but in doing so are not being conformant,
- and are still incompatible with each other in many ways.
- You should use other pathname abstractions,
- such as ASDF:SYSTEM-RELATIVE-PATHNAME
or
- the underlying UIOP:SUBPATHNAME
and
- UIOP:PARSE-UNIX-NAMESTRING
.
-
-
-
- Finally, be aware that paths may change between
- the time you build the Lisp image for your application,
- and the time you run the application from its image.
- You should be careful to reset your image
- to forget irrelevant build-time paths and
- reinitialize any search path from current environment variables.
- ASDF
for instance requires you to reset its paths
- with UIOP:CLEAR-CONFIGURATION
.
- UIOP
provides hooks
- to call functions before an image is dumped,
- from which to reset or makunbound
relevant variables.
-
-
-
-
-
-
- You must be careful when using a SATISFIES
clause in a type specifier.
-
-
-
- Most Common Lisp implementations can't optimize
- based on a SATISFIES
type,
- but many of them offer simple optimizations
- based on a type of the form
- (AND FOO (SATISFIES BAR-P))
- where the first term of the AND
clause
- describes the structure of the object
- without any SATISFIES
- and the second term is the SATISFIES
.
-
-
- (deftype prime-number () (satisfies prime-number-p)) ; Bad
-
-
- (deftype prime-number () (and integer (satisfies prime-number-p)) ; Better
-
-
- However, AND
in the DEFTYPE
language
- isn't a left-to-right short-circuit operator
- as in the expression language;
- it is a symmetrical connector that allows for reordering subterms
- and doesn't guarantee short-circuiting.
- Therefore, in the above example,
- you cannot rely on the test for INTEGER
ness
- to protect the function PRIME-NUMBER-P
- from being supplied non-integer arguments
- to test for being of instances of the type.
- Implementations may, and some will,
- invoke SATISFIES
-specified function
- at compile-time to test various relevant objects.
-
-
- That is why any function specified in a SATISFIES
clause
- MUST accept objects of any type as argument to the function,
- and MUST be defined within an EVAL-WHEN
- (as well as any variable it uses or function it calls):
-
-
- (defun prime-number-p (n) ; Doubly bad!
- (let ((m (abs n)))
- (if (<= m *prime-number-cutoff*)
- (small-prime-number-p m)
- (big-prime-number-p m))))
-
-
- (eval-when (:compile-toplevel :load-toplevel :execute) ; Better
- (defun prime-number-p (n)
- (when (integerp n) ; Better
- (let ((m (abs n)))
- (if (<= m *prime-number-cutoff*)
- (small-prime-number-p m)
- (big-prime-number-p m))))))
-
-
- In particular, the above means that the
- example
- used in the Common Lisp Standard is erroneous:
- (and integer (satisfies evenp))
- is not a safe, conformant type specifier to use,
- because EVENP
will throw an error
- rather than return NIL
- when passed a non-integer as an argument.
-
-
- Finally, there is a catch when your DEFTYPE
code expands
- to a SATISFIES
with a dynamically generated function:
-
-
- -
- You cannot control when implementations will or will not
- expand a
DEFTYPE
.
-
- -
- The expansion itself cannot contain a function definition
- or any code in the expression language.
-
- -
- You cannot control when the expansion is used,
- it may happen in a different process
- that didn't expand the definition.
-
-
-
- Therefore, you cannot merely create the function
- as a side-effect of expansion
- using EVAL
at type-expansion time.
- The solution is to use
- ASDF-FINALIZERS:EVAL-AT-TOPLEVEL
instead.
- See the very last point
- in the discussion about EVAL.
-
-
- Common Lisp is hard to satisfy.
-
-
-
-
-
-
-
-Credits:
- Adam Worrall, Dan Pierson, Matt Marjanovic, Matt Reklaitis,
- Paul Weiss, Scott McKay, Sundar Narasimhan,
- and several other people contributed.
- Special thanks to Steve Hain,
- and to the previous editors,
- in reverse chronological order Dan Weinreb and Jeremy Brown.
-
-
-
-Revision 1.28
-
-
-
-
-Robert Brown
-
-
-
- François-René Rideau
-
-
-
-
-
diff --git a/objcguide.asciidoc b/objcguide.asciidoc
new file mode 100644
index 0000000..d55328d
--- /dev/null
+++ b/objcguide.asciidoc
@@ -0,0 +1,1286 @@
+= Google Objective-C Style Guide
+
+:sectlinks:
+
+Revision 2.59
+
+Mike Pinkerton +
+ Greg Miller +
+ Dave MacLachlan
+
+
+
+
+
+Table of Contents
+
+[width="100%",cols="50%,50%",]
+|===================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
+a|
+link:#example[Example]
+
+ a|
+a|
+link:#spacing-and-formatting[Spacing And Formatting]
+
+ a|
+link:#spaces-vs-tabs[Spaces vs. Tabs] link:#line-length[Line Length] link:#method-declarations-and-definitions[Method Declarations and Definitions] link:#method-invocations[Method Invocations] link:#@public_and_@private[@public and @private] link:#exceptions[Exceptions] link:#protocols[Protocols] link:#blocks[Blocks] link:#container-literals[Container Literals]
+
+a|
+link:#naming[Naming]
+
+ a|
+link:#file-names[File Names] link:#Objective-C++[Objective-C++] link:#class-names[Class Names] link:#category-names[Category Names] link:#Objective-C_Method_Names[Objective-C Method Names] link:#variable-names[Variable Names]
+
+a|
+link:#comments[Comments]
+
+ a|
+link:#file-comments[File Comments] link:#declaration-comments[Declaration Comments] link:#implementation-comments[Implementation Comments] link:#object-ownership[Object Ownership]
+
+a|
+link:#Cocoa_and_Objective-C_Features[Cocoa and Objective-C Features]
+
+ a|
+link:#Instance_Variables_In_Headers_Should_Be_@private[Instance Variables In Headers Should Be @private] link:#identify-designated-initializer[Identify Designated Initializer] link:#override-designated-initializer[Override Designated Initializer] link:#overridden-nsobject-method-placement[Overridden NSObject Method Placement] link:#initialization[Initialization] link:#Avoid_+new[Avoid +new] link:#keep-the-public-api_simple[Keep the Public API Simple] link:#-import-and-_include[#import and #include] link:#use-root-frameworks[Use Root Frameworks] link:#prefer-to-autorelease-at_time_of_creation[Prefer To autorelease At Time of Creation] link:#autorelease-then-retain[Autorelease Then Retain] link:#avoid-accessors-during-init_and_dealloc[Avoid Accessors During init and dealloc] link:#dealloc-instance-variables-in_declaration______________________order[Dealloc Instance Variables in Declaration Order] link:#setters-copy-nsstrings[Setters copy NSStrings] link:#avoid-throwing-exceptions[Avoid Throwing Exceptions] link:#nil-checks[nil Checks] link:#bool-pitfalls[BOOL Pitfalls] link:#properties[Properties] link:#interfaces-without-instance-variables[Interfaces Without Instance Variables] link:#automatically-synthesized-instance-variables[Automatically Synthesized Instance Variables] link:#automatic-reference-counting-_arc_[Automatic Reference Counting (ARC)] link:#nsnumber-literals[NSNumber Literals]
+
+a|
+link:#cocoa-patterns[Cocoa Patterns]
+
+ a|
+link:#delegate-pattern[Delegate Pattern] link:#model-view/controller[Model/View/Controller]
+
+a|
+link:#historical-notes[Historical Notes]
+
+ a|
+link:#trailing-vs-leading-underscores[Trailing vs Leading Underscores]
+
+|===================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
+
+[[Important_Note]]
+== Important Note
+
+=== Displaying Hidden Details in this Guide
+
+
+
+This style guide contains many details that are initially hidden from view. They are marked by the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear below.
+
+Hooray! Now you know you can expand points to get more details. Alternatively, there's an "expand all" at the top of this document.
+
+[[Background]]
+== Background
+
+Objective-C is a very dynamic, object-oriented extension of C. It's designed to be easy to use and read, while enabling sophisticated object-oriented design. It is the primary development language for new applications on Mac OS X and the iPhone.
+
+Cocoa is one of the main application frameworks on Mac OS X. It is a collection of Objective-C classes that provide for rapid development of full-featured Mac OS X applications.
+
+Apple has already written a very good, and widely accepted, coding guide for Objective-C. Google has also written a similar guide for C++. This Objective-C guide aims to be a very natural combination of Apple's and Google's general recommendations. So, before reading this guide, please make sure you've read:
+
+
+* http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/index.html[Apple's Cocoa Coding Guidelines]
+
+* http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml[Google's Open Source C++ Style Guide]
+
+_Note that all things that are banned in Google's C++ guide are also banned in Objective-C++, unless explicitly noted in this document._
+
+The purpose of this document is to describe the Objective-C (and Objective-C++) coding guidelines and practices that should be used for all Mac OS X code. Many of these guidelines have evolved and been proven over time on other projects and teams. Open-source projects developed by Google conform to the requirements in this guide.
+
+Google has already released open-source code that conforms to these guidelines as part of the http://code.google.com/p/google-toolbox-for-mac/[Google Toolbox for Mac project] (abbreviated GTM throughout this document). Code meant to be shared across different projects is a good candidate to be included in this repository.
+
+Note that this guide is not an Objective-C tutorial. We assume that the reader is familiar with the language. If you are new to Objective-C or need a refresher, please read http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html[Programming with Objective-C].
+
+[[Example]]
+== Example
+
+They say an example is worth a thousand words so let's start off with an example that should give you a feel for the style, spacing, naming, etc.
+
+An example header file, demonstrating the correct commenting and spacing for an `@interface` declaration
+
+--------------------------------------------------------------------------
+#import
+
+// A sample class demonstrating good Objective-C style. All interfaces,
+// categories, and protocols (read: all non-trivial top-level declarations
+// in a header) MUST be commented. Comments must also be adjacent to the
+// object they're documenting.
+//
+// (no blank line between this comment and the interface)
+@interface Foo : NSObject
+
+// Returns an autoreleased instance of Foo. See -initWithBar: for details
+// about |bar|.
++ (instancetype)fooWithBar:(NSString *)bar;
+
+// Designated initializer. |bar| is a thing that represents a thing that
+// does a thing.
+- (instancetype)initWithBar:(NSString *)bar;
+
+// Gets and sets |_bar|.
+- (NSString *)bar;
+- (void)setBar:(NSString *)bar;
+
+// Does some work with |blah| and returns YES if the work was completed
+// successfully, and NO otherwise.
+- (BOOL)doWorkWithBlah:(NSString *)blah;
+
+@end
+--------------------------------------------------------------------------
+
+An example source file, demonstrating the correct commenting and spacing for the `@implementation` of an interface. It also includes the reference implementations for important methods like getters and setters, `init`, and `dealloc`.
+
+---------------------------------------------------------
+#import "Foo.h"
+
+
+@implementation Foo {
+ NSString *_bar;
+ NSString *_foo;
+}
+
++ (instancetype)fooWithBar:(NSString *)bar {
+ return [[[self alloc] initWithBar:bar] autorelease];
+}
+
+// Must always override super's designated initializer.
+- (instancetype)init {
+ return [self initWithBar:nil];
+}
+
+- (instancetype)initWithBar:(NSString *)bar {
+ if ((self = [super init])) {
+ _bar = [bar copy];
+ _bam = [[NSString alloc] initWithFormat:@"hi %d", 3];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [_bar release];
+ [_bam release];
+ [super dealloc];
+}
+
+- (NSString *)bar {
+ return _bar;
+}
+
+- (void)setBar:(NSString *)bar {
+ [_bar autorelease];
+ _bar = [bar copy];
+}
+
+- (BOOL)doWorkWithBlah:(NSString *)blah {
+ // ...
+ return NO;
+}
+
+@end
+---------------------------------------------------------
+
+Blank lines before and after `@interface`, `@implementation`, and `@end` are optional. If your `@interface` declares instance variables, a blank line should come after the closing brace (`}`).
+
+Unless an interface or implementation is very short, such as when declaring a handful of private methods or a bridge class, adding blank lines usually helps readability.
+
+[[Spacing_And_Formatting]]
+== Spacing And Formatting
+
+=== Spaces vs. Tabs
+
+
+
+Use only spaces, and indent 2 spaces at a time.
+
+We use spaces for indentation. Do not use tabs in your code. You should set your editor to emit spaces when you hit the tab key.
+
+=== Line Length
+
+
+
+The maximum line length for Objective-C and Objective-C++ files is 100 columns. Projects may opt to use an 80 column limit for consistency with the C++ style guide.
+
+You can make violations easier to spot by enabling _Preferences > Text Editing > Page guide at column: 100_ in Xcode.
+
+=== Method Declarations and Definitions
+
+
+
+One space should be used between the `-` or `+` and the return type, and no spacing in the parameter list except between parameters.
+
+Methods should look like this:
+
+-----------------------------------------------------
+- (void)doSomethingWithString:(NSString *)theString {
+ ...
+}
+-----------------------------------------------------
+
+The spacing before the asterisk is optional. When adding new code, be consistent with the surrounding file's style.
+
+If you have too many parameters to fit on one line, giving each its own line is preferred. If multiple lines are used, align each using the colon before the parameter.
+
+--------------------------------------------
+- (void)doSomethingWith:(GTMFoo *)theFoo
+ rect:(NSRect)theRect
+ interval:(float)theInterval {
+ ...
+}
+--------------------------------------------
+
+When the first keyword is shorter than the others, indent the later lines by at least four spaces, maintaining colon alignment:
+
+--------------------------------------------
+- (void)short:(GTMFoo *)theFoo
+ longKeyword:(NSRect)theRect
+ evenLongerKeyword:(float)theInterval
+ error:(NSError **)theError {
+ ...
+}
+--------------------------------------------
+
+=== Method Invocations
+
+
+
+Method invocations should be formatted much like method declarations. When there's a choice of formatting styles, follow the convention already used in a given source file.
+
+Invocations should have all arguments on one line:
+
+-----------------------------------------------
+[myObject doFooWith:arg1 name:arg2 error:arg3];
+-----------------------------------------------
+
+or have one argument per line, with colons aligned:
+
+--------------------------
+[myObject doFooWith:arg1
+ name:arg2
+ error:arg3];
+--------------------------
+
+Don't use any of these styles:
+
+-------------------------------------------------------------
+[myObject doFooWith:arg1 name:arg2 // some lines with >1 arg
+ error:arg3];
+
+[myObject doFooWith:arg1
+ name:arg2 error:arg3];
+
+[myObject doFooWith:arg1
+ name:arg2 // aligning keywords instead of colons
+ error:arg3];
+-------------------------------------------------------------
+
+As with declarations and definitions, when the first keyword is shorter than the others, indent the later lines by at least four spaces, maintaining colon alignment:
+
+----------------------------
+[myObj short:arg1
+ longKeyword:arg2
+ evenLongerKeyword:arg3
+ error:arg4];
+----------------------------
+
+Invocations containing inlined link:#blocks[blocks] may have their segments left-aligned at a four space indent.
+
+=== @public and @private
+
+
+
+The `@public` and `@private` access modifiers should be indented by 1 space.
+
+This is similar to `public`, `private`, and `protected` in C++.
+
+-------------------------------
+@interface MyClass : NSObject {
+ @public
+ ...
+ @private
+ ...
+}
+@end
+-------------------------------
+
+=== Exceptions
+
+
+
+Format exceptions with each `@` label on its own line and a space between the `@` label and the opening brace (`{`), as well as between the `@catch` and the caught object declaration.
+
+If you must use Obj-C exceptions, format them as follows. However, see link:#avoid-throwing-exceptions[Avoid Throwing Exceptions] for reasons why you should not be using exceptions.
+
+--------------------------
+@try {
+ foo();
+}
+@catch (NSException *ex) {
+ bar(ex);
+}
+@finally {
+ baz();
+}
+--------------------------
+
+=== Protocols
+
+
+
+There should not be a space between the type identifier and the name of the protocol encased in angle brackets.
+
+This applies to class declarations, instance variables, and method declarations. For example:
+
+-----------------------------------------------------------
+@interface MyProtocoledClass : NSObject {
+ @private
+ id _delegate;
+}
+- (void)setDelegate:(id)aDelegate;
+@end
+-----------------------------------------------------------
+
+=== Blocks
+
+
+
+Code inside blocks should be indented four spaces.
+
+There are several appropriate style rules, depending on how long the block is:
+
+
+* If the block can fit on one line, no wrapping is necessary.
+
+* If it has to wrap, the closing brace should line up with the first character of the line on which the block is declared.
+
+* Code within the block should be indented four spaces.
+
+* If the block is large, e.g. more than 20 lines, it is recommended to move it out-of-line into a local variable.
+
+* If the block takes no parameters, there are no spaces between the characters `^{`. If the block takes parameters, there is no space between the `^(` characters, but there is one space between the `) {` characters.
+
+* Invocations containing inlined blocks may have their segments left-aligned at a four-space indent. This helps when invocations contain multiple inlined blocks.
+
+* Two space indents inside blocks are also allowed, but should only be used when it's consistent with the rest of the project's code.
+
+----------------------------------------------------------------------
+// The entire block fits on one line.
+[operation setCompletionBlock:^{ [self onOperationDone]; }];
+
+// The block can be put on a new line, indented four spaces, with the
+// closing brace aligned with the first character of the line on which
+// block was declared.
+[operation setCompletionBlock:^{
+ [self.delegate newDataAvailable];
+}];
+
+// Using a block with a C API follows the same alignment and spacing
+// rules as with Objective-C.
+dispatch_async(_fileIOQueue, ^{
+ NSString* path = [self sessionFilePath];
+ if (path) {
+ // ...
+ }
+});
+
+// An example where the parameter wraps and the block declaration fits
+// on the same line. Note the spacing of |^(SessionWindow *window) {|
+// compared to |^{| above.
+[[SessionService sharedService]
+ loadWindowWithCompletionBlock:^(SessionWindow *window) {
+ if (window) {
+ [self windowDidLoad:window];
+ } else {
+ [self errorLoadingWindow];
+ }
+ }];
+
+// An example where the parameter wraps and the block declaration does
+// not fit on the same line as the name.
+[[SessionService sharedService]
+ loadWindowWithCompletionBlock:
+ ^(SessionWindow *window) {
+ if (window) {
+ [self windowDidLoad:window];
+ } else {
+ [self errorLoadingWindow];
+ }
+ }];
+
+// Large blocks can be declared out-of-line.
+void (^largeBlock)(void) = ^{
+ // ...
+};
+[_operationQueue addOperationWithBlock:largeBlock];
+
+// An example with multiple inlined blocks in one invocation.
+[myObject doSomethingWith:arg1
+ firstBlock:^(Foo *a) {
+ // ...
+ }
+ secondBlock:^(Bar *b) {
+ // ...
+ }];
+----------------------------------------------------------------------
+
+=== Container Literals
+
+
+
+For projects using Xcode 4.4 or later and clang, the use of container (array and dictionary) literals is encouraged. If split across multiple lines, the contents should be indented two spaces.
+
+If the collection fits on one line, put a single space after the opening and before the closing brackets.
+
+------------------------------------------------------------------------------
+NSArray* array = @[ [foo description], @"Another String", [bar description] ];
+
+NSDictionary* dict = @{ NSForegroundColorAttributeName : [NSColor redColor] };
+------------------------------------------------------------------------------
+
+Not:
+
+---------------------------------------------------------------------------
+NSArray* array = @[[foo description], [bar description]];
+
+NSDictionary* dict = @{NSForegroundColorAttributeName: [NSColor redColor]};
+---------------------------------------------------------------------------
+
+If the collection spans more than a single line, place the opening bracket on the same line as the declaration, indent the body by two spaces, and place the closing bracket on a new line that is indented to the same level as the opening bracket.
+
+------------------------------------------------------------------------
+NSArray* array = @[
+ @"This",
+ @"is",
+ @"an",
+ @"array"
+];
+
+NSDictionary* dictionary = @{
+ NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12],
+ NSForegroundColorAttributeName : fontColor
+};
+------------------------------------------------------------------------
+
+For dictionary literals, there should be one space before the colon and at least one space after it (to optionally align the values).
+
+--------------------------------------------------------------------------
+NSDictionary* option1 = @{
+ NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12],
+ NSForegroundColorAttributeName : fontColor
+};
+
+NSDictionary* option2 = @{
+ NSFontAttributeName : [NSFont fontWithName:@"Arial" size:12],
+ NSForegroundColorAttributeName : fontColor
+};
+--------------------------------------------------------------------------
+
+The following are all incorrect:
+
+-------------------------------------------------------------------
+// There should be a space before the colon.
+NSDictionary* wrong = @{
+ AKey: @"b",
+ BLongerKey: @"c",
+};
+
+// The items should each be on a new line, or the entire expression
+// should fit on one line.
+NSDictionary* alsoWrong= @{ AKey : @"a",
+ BLongerKey : @"b" };
+
+// There should be no variable space before the colon, only after.
+NSDictionary* stillWrong = @{
+ AKey : @"b",
+ BLongerKey : @"c",
+};
+-------------------------------------------------------------------
+
+[[Naming]]
+== Naming
+
+Naming rules are very important in maintainable code. Objective-C method names tend to be very long, but this has the benefit that a block of code can almost read like prose, thus rendering many comments unnecessary.
+
+When writing pure Objective-C code, we mostly follow standard http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html[Objective-C naming rules]. These naming guidelines may differ significantly from those outlined in the C++ style guide. For example, Google's C++ style guide recommends the use of underscores between words in variable names, whereas this guide recommends the use of intercaps, which is standard in the Objective-C community.
+
+Any class, category, method, or variable name may use all capitals for http://en.wikipedia.org/wiki/Initialism[initialisms] within the name. This follows Apple's standard of using all capitals within a name for initialisms such as URL, TIFF, and EXIF.
+
+When writing Objective-C++, however, things are not so cut and dry. Many projects need to implement cross-platform C++ APIs with some Objective-C or Cocoa, or bridge between a C++ back-end and a native Cocoa front-end. This leads to situations where the two guides are directly at odds.
+
+Our solution is that the style follows that of the method/function being implemented. If you're in an `@implementation` block, use the Objective-C naming rules. If you're implementing a method for a C++ `class`, use the C++ naming rules. This avoids the situation where instance variable and local variable naming rules are mixed within a single function, which would be a serious detriment to readability.
+
+=== File Names
+
+
+
+File names should reflect the name of the class implementation that they contain—including case. Follow the convention that your project uses.
+
+File extensions should be as follows:
+
+[cols=",",]
+|========================================
+|`.h` |C/C++/Objective-C header file
+|`.m` |Objective-C implementation file
+|`.mm` |Objective-C++ implementation file
+|`.cc` |Pure C++ implementation file
+|`.c` |C implementation file
+|========================================
+
+File names for categories should include the name of the class being extended, e.g. `GTMNSString+Utils.h` or `GTMNSTextView+Autocomplete.h`
+
+=== Objective-C++
+
+
+
+Within a source file, Objective-C++ follows the style of the function/method you're implementing.
+
+In order to minimize clashes between the differing naming styles when mixing Cocoa/Objective-C and C++, follow the style of the method being implemented. If you're in an `@implementation` block, use the Objective-C naming rules. If you're implementing a method for a C++ `class`, use the C++ naming rules.
+
+------------------------------------------------------------------------------
+// file: cross_platform_header.h
+
+class CrossPlatformAPI {
+ public:
+ ...
+ int DoSomethingPlatformSpecific(); // impl on each platform
+ private:
+ int an_instance_var_;
+};
+
+// file: mac_implementation.mm
+#include "cross_platform_header.h"
+
+// A typical Objective-C class, using Objective-C naming.
+@interface MyDelegate : NSObject {
+ @private
+ int _instanceVar;
+ CrossPlatformAPI* _backEndObject;
+}
+- (void)respondToSomething:(id)something;
+@end
+@implementation MyDelegate
+- (void)respondToSomething:(id)something {
+ // bridge from Cocoa through our C++ backend
+ _instanceVar = _backEndObject->DoSomethingPlatformSpecific();
+ NSString* tempString = [NSString stringWithFormat:@"%d", _instanceVar];
+ NSLog(@"%@", tempString);
+}
+@end
+
+// The platform-specific implementation of the C++ class, using
+// C++ naming.
+int CrossPlatformAPI::DoSomethingPlatformSpecific() {
+ NSString* temp_string = [NSString stringWithFormat:@"%d", an_instance_var_];
+ NSLog(@"%@", temp_string);
+ return [temp_string intValue];
+}
+------------------------------------------------------------------------------
+
+=== Class Names
+
+
+
+Class names (along with category and protocol names) should start as uppercase and use mixed case to delimit words.
+
+When designing code to be shared across multiple applications, prefixes are acceptable and recommended (e.g. `GTMSendMessage`). Prefixes are also recommended for classes of large applications that depend on external libraries.
+
+=== Category Names
+
+
+
+Category names should start with a 2 or 3 character prefix identifying the category as part of a project or open for general use. The category name should incorporate the name of the class it's extending.
+
+For example, if we want to create a category on `NSString` for parsing, we would put the category in a file named `GTMNSString+Parsing.h`, and the category itself would be named `GTMStringParsingAdditions` (yes, we know the file name and the category name do not match, but this file could have many separate categories related to parsing). Methods in that category should share the prefix (`gtm_myCategoryMethodOnAString:`) in order to prevent collisions in Objective-C which only has a single namespace. If the code isn't meant to be shared and/or doesn't run in a different address-space, the method naming isn't quite as important.
+
+There should be a single space between the class name and the opening parenthesis of the category.
+
+------------------------------------------------
+// Extending a framework class:
+@interface NSString (GTMStringParsingAdditions)
+- (NSString *)gtm_foobarString;
+@end
+
+// Making your methods and properties private:
+@interface FoobarViewController ()
+@property(nonatomic, retain) NSView *dongleView;
+- (void)performLayout;
+@end
+------------------------------------------------
+
+=== Objective-C Method Names
+
+
+
+Method names should start as lowercase and then use mixed case. Each named parameter should also start as lowercase.
+
+The method name should read like a sentence if possible, meaning you should choose parameter names that flow with the method name. (e.g. `convertPoint:fromRect:` or `replaceCharactersInRange:withString:`). See http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-BCIGIJJF[Apple's Guide to Naming Methods] for more details.
+
+Accessor methods should be named the same as the variable they're "getting", but they should _not_ be prefixed with the word "get". For example:
+
+----------------------------
+- (id)getDelegate; // AVOID
+----------------------------
+
+--------------------------
+- (id)delegate; // GOOD
+--------------------------
+
+This is for Objective-C methods only. C++ method names and functions continue to follow the rules set in the C++ style guide.
+
+=== Variable Names
+
+
+
+Variables names start with a lowercase and use mixed case to delimit words. Instance variables have leading underscores. For example: myLocalVariable, _myInstanceVariable.
+
+Common Variable Names
+
+Do _not_ use Hungarian notation for syntactic attributes, such as the static type of a variable (int or pointer). Give as descriptive a name as possible, within reason. Don't worry about saving horizontal space as it is far more important to make your code immediately understandable by a new reader. For example:
+
+------------------------------------
+int w;
+int nerr;
+int nCompConns;
+tix = [[NSMutableArray alloc] init];
+obj = [someObject object];
+p = [network port];
+------------------------------------
+
+----------------------------------------
+int numErrors;
+int numCompletedConnections;
+tickets = [[NSMutableArray alloc] init];
+userInfo = [someObject object];
+port = [network port];
+----------------------------------------
+
+Instance Variables
+
+Instance variables are mixed case and should be prefixed with an underscore e.g. _usernameTextField. Note that historically the convention was to put the underscore at the end of the name, and projects may opt to continue using trailing underscores in new code in order to maintain consistency within their codebase (see the Historical Notes section). It is recommended you leave old code as-is, unless doing so would create inconsistency within a class.
+
+Constants
+
+Constant names (#defines, enums, const local variables, etc.) should start with a lowercase k and then use mixed case to delimit words. For example:
+
+---------------------------------------
+const int kNumberOfFiles = 12;
+NSString *const kUserKey = @"kUserKey";
+enum DisplayTinge {
+ kDisplayTingeGreen = 1,
+ kDisplayTingeBlue = 2
+};
+---------------------------------------
+
+Because Objective-C does not provide namespacing, constants with global scope should have an appropriate prefix to minimize the chance of name collision, typically like kClassNameFoo.
+
+[[Comments]]
+== Comments
+
+Though a pain to write, they are absolutely vital to keeping our code readable. The following rules describe what you should comment and where. But remember: while comments are very important, the best code is self-documenting. Giving sensible names to types and variables is much better than using obscure names and then trying to explain them through comments.
+
+When writing your comments, write for your audience: the next contributor who will need to understand your code. Be generous—the next one may be you!
+
+Remember that all of the rules and conventions listed in the C++ Style Guide are in effect here, with a few additional points, below.
+
+=== File Comments
+
+
+
+A file may optionally start with a description of its contents.
+
+Every file should contain the following items, in order:
+
+
+* license boilerplate if neccessary. Choose the appropriate boilerplate for the license used by the project (e.g. Apache 2.0, BSD, LGPL, GPL).
+
+* a basic description of the contents of the file if necessary.
+
+If you make significant changes to a file with an author line, consider deleting the author line since revision history already provides a more detailed and accurate record of authorship.
+
+=== Declaration Comments
+
+
+
+Every interface, category, and protocol declaration should have an accompanying comment describing its purpose and how it fits into the larger picture.
+
+-----------------------------------------------------------------
+// A delegate for NSApplication to handle notifications about app
+// launch and shutdown. Owned by the main app controller.
+@interface MyAppDelegate : NSObject {
+ ...
+}
+@end
+-----------------------------------------------------------------
+
+If you have already described an interface in detail in the comments at the top of your file feel free to simply state "See comment at top of file for a complete description", but be sure to have some sort of comment.
+
+Additionally, each method in the public interface should have a comment explaining its function, arguments, return value, and any side effects.
+
+Document the synchronization assumptions the class makes, if any. If an instance of the class can be accessed by multiple threads, take extra care to document the rules and invariants surrounding multithreaded use.
+
+=== Implementation Comments
+
+
+
+Use vertical bars to quote variable names and symbols in comments rather than quotes or naming the symbol inline.
+
+This helps eliminate ambiguity, especially when the symbol is a common word that might make the sentence read like it was poorly constructed. E.g. for a symbol "count":
+
+--------------------------------------------------
+// Sometimes we need |count| to be less than zero.
+--------------------------------------------------
+
+or when quoting something which already contains quotes
+
+--------------------------------------------------------
+// Remember to call |StringWithoutSpaces("foo bar baz")|
+--------------------------------------------------------
+
+=== Object Ownership
+
+
+
+Make the pointer ownership model as explicit as possible when it falls outside the most common Objective-C usage idioms.
+
+Manual Reference Counting
+
+Instance variables which are pointers to objects derived from NSObject are presumed to be retained, and should be either commented as weak or declared with the __weak lifetime qualifier when applicable. Similarly, declared properties must specify an assign property attribute if they are not retained by the class. An exception is instance variables labeled as IBOutlets in desktop Mac software, which are presumed to not be retained.
+
+Where instance variables are pointers to Core Foundation, C++, and other non-Objective-C objects, they should always be declared with `strong` and `weak` comments to indicate which pointers are and are not retained. Core Foundation and other non-Objective-C object pointers require explicit memory management, even when building for automatic reference counting or garbage collection.
+
+Examples of strong and weak declarations:
+
+---------------------------------------------------------------------------------
+@interface MyDelegate : NSObject {
+ @private
+ IBOutlet NSButton *_okButton; // Normal NSControl; implicitly weak on Mac only
+
+ AnObjcObject* _doohickey; // My doohickey
+ __weak MyObjcParent *_parent; // So we can send msgs back (owns me)
+
+ // non-NSObject pointers...
+ CWackyCPPClass *_wacky; // Strong, some cross-platform object
+ CFDictionaryRef *_dict; // Strong
+}
+@property(strong, nonatomic) NSString *doohickey;
+@property(weak, nonatomic) NSString *parent;
+@end
+---------------------------------------------------------------------------------
+
+Automatic Reference Counting
+
+Object ownership and lifetime are explicit when using ARC, so no additional comments are required.
+
+[[Cocoa_and_Objective-C_Features]]
+== Cocoa and Objective-C Features
+
+=== Instance Variables In Headers Should Be @private
+
+
+
+Instance variables should typically be declared in implementation files or auto-synthesized by properties. When ivars are declared in a header file, they should be marked `@private`.
+
+-------------------------------
+@interface MyClass : NSObject {
+ @private
+ id _myInstanceVariable;
+}
+@end
+-------------------------------
+
+=== Identify Designated Initializer
+
+
+
+Comment and clearly identify your designated initializer.
+
+It is important for those who might be subclassing your class that the designated initializer be clearly identified. That way, they only need to subclass a single initializer (of potentially several) to guarantee their subclass' initializer is called. It also helps those debugging your class in the future understand the flow of initialization code if they need to step through it.
+
+=== Override Designated Initializer
+
+
+
+When writing a subclass that requires an `init...` method, make _sure_ you override the superclass' designated initializer.
+
+If you fail to override the superclass' designated initializer, your initializer may not be called in all cases, leading to subtle and very difficult to find bugs.
+
+=== Overridden NSObject Method Placement
+
+
+
+It is strongly recommended and typical practice to place overridden methods of `NSObject` at the top of an `@implementation`.
+
+This commonly applies (but is not limited) to the `init...`, `copyWithZone:`, and `dealloc` methods. `init...` methods should be grouped together, followed by other `NSObject` methods.
+
+Convenience class methods for creating instances may precede the `NSObject` methods.
+
+=== Initialization
+
+
+
+Don't initialize variables to `0` or `nil` in the init method; it's redundant.
+
+All memory for a newly allocated object is initialized to 0 (except for isa), so don't clutter up the `init` method by re-initializing variables to 0 or `nil`.
+
+=== Avoid +new
+
+
+
+Do not invoke the `NSObject` class method `new`, nor override it in a subclass. Instead, use `alloc` and `init` methods to instantiate retained objects.
+
+Modern Objective-C code explicitly calls `alloc` and an `init` method to create and retain an object. As the `new` class method is rarely used, it makes reviewing code for correct memory management more difficult.
+
+=== Keep the Public API Simple
+
+
+
+Keep your class simple; avoid "kitchen-sink" APIs. If a method doesn't need to be public, don't make it so. Use a private category to prevent cluttering the public header.
+
+Unlike C++, Objective-C doesn't have a way to differentiate between public and private methods—everything is public. As a result, avoid placing methods in the public API unless they are actually expected to be used by a consumer of the class. This helps reduce the likelihood they'll be called when you're not expecting it. This includes methods that are being overridden from the parent class. For internal implementation methods, use a category defined in the implementation file as opposed to adding them to the public header.
+
+-----------------------------------------------------------------
+#import "GTMFoo.h"
+
+@interface GTMFoo (PrivateDelegateHandling)
+- (NSString *)doSomethingWithDelegate; // Declare private method
+@end
+
+@implementation GTMFoo (PrivateDelegateHandling)
+...
+- (NSString *)doSomethingWithDelegate {
+ // Implement this method
+}
+...
+@end
+-----------------------------------------------------------------
+
+If you are using Objective-C 2.0, you should instead declare your private category using a http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_5.html#[class extension], for example:
+
+---------------------------
+@interface GMFoo () { ... }
+---------------------------
+
+which will guarantee that the declared methods are implemented in the `@implementation` section by issuing a compiler warning if they are not.
+
+Again, "private" methods are not really private. You could accidentally override a superclass's "private" method, thus making a very difficult bug to squash. In general, private methods should have a fairly unique name that will prevent subclasses from unintentionally overriding them.
+
+Finally, Objective-C categories are a great way to segment a large `@implementation` section into more understandable chunks and to add new, application-specific functionality to the most appropriate class. For example, instead of adding "middle truncation" code to a random object in your app, make a new category on `NSString`).
+
+=== #import and #include
+
+
+
+`#import` Objective-C/Objective-C++ headers, and `#include` C/C++ headers.
+
+Choose between `#import` and `#include` based on the language of the header that you are including.
+
+
+* When including a header that uses Objective-C or Objective-C++, use `#import`.
+
+* When including a standard C or C++ header, use `#include`. The header should provide its own link:cppguide.xml?showone=The__define_Guard#The__define_Guard[#define guard].
+
+Some Objective-C headers lack `#define` guards, and expect to be included only by `#import`. As Objective-C headers may only be included in Objective-C source files and other Objective-C headers, using `#import` across the board is appropriate.
+
+Standard C and C++ headers without any Objective-C in them can expect to be included by ordinary C and C++ files. Since there is no `#import` in standard C or C++, such files will be included by `#include` in those cases. Using `#include` for them in Objective-C source files as well means that these headers will always be included with the same semantics.
+
+This rule helps avoid inadvertent errors in cross-platform projects. A Mac developer introducing a new C or C++ header might forget to add `#define` guards, which would not cause problems on the Mac if the new header were included with `#import`, but would break builds on other platforms where `#include` is used. Being consistent by using `#include` on all platforms means that compilation is more likely to succeed everywhere or fail everywhere, and avoids the frustration of files working only on some platforms.
+
+------------------------------------------
+#import
+#include
+#import "GTMFoo.h"
+#include "base/basictypes.h"
+------------------------------------------
+
+=== Use Root Frameworks
+
+
+
+Include root frameworks over individual files.
+
+While it may seem tempting to include individual system headers from a framework such as Cocoa or Foundation, in fact it's less work on the compiler if you include the top-level root framework. The root framework is generally pre-compiled and can be loaded much more quickly. In addition, remember to use `#import` rather than `#include` for Objective-C frameworks.
+
+---------------------------------------------
+#import // good
+---------------------------------------------
+
+----------------------------------------------
+#import // avoid
+#import
+...
+----------------------------------------------
+
+=== Prefer To autorelease At Time of Creation
+
+
+
+When creating new temporary objects, `autorelease` them on the same line as you create them rather than a separate `release` later in the same method.
+
+While ever so slightly slower, this prevents someone from accidentally removing the `release` or inserting a `return` before it and introducing a memory leak. E.g.:
+
+----------------------------------------------------------
+// AVOID (unless you have a compelling performance reason)
+MyController* controller = [[MyController alloc] init];
+// ... code here that might return ...
+[controller release];
+----------------------------------------------------------
+
+---------------------------------------------------------------------
+// BETTER
+MyController* controller = [[[MyController alloc] init] autorelease];
+---------------------------------------------------------------------
+
+=== Autorelease Then Retain
+
+
+
+Assignment of objects follows the `autorelease` then `retain` pattern.
+
+When assigning a new object to a variable, one must first release the old object to avoid a memory leak. There are several "correct" ways to handle this. We've chosen the "autorelease then retain" approach because it's less prone to error. Be aware in tight loops it can fill up the autorelease pool, and may be slightly less efficient, but we feel the tradeoffs are acceptable.
+
+-----------------------------------------------------------
+- (void)setFoo:(GMFoo *)aFoo {
+ [_foo autorelease]; // Won't dealloc if |_foo| == |aFoo|
+ _foo = [aFoo retain];
+}
+-----------------------------------------------------------
+
+=== Avoid Accessors During init and dealloc
+
+
+
+Instance subclasses may be in an inconsistent state during `init` and `dealloc` method execution, so code in those methods should avoid invoking accessors.
+
+Subclasses have not yet been initialized or have already deallocated when `init` and `dealloc` methods execute, making accessor methods potentially unreliable. Whenever practical, directly assign to and release ivars in those methods rather than rely on accessors.
+
+---------------------------------------------------
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ _bar = [[NSMutableString alloc] init]; // good
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [_bar release]; // good
+ [super dealloc];
+}
+---------------------------------------------------
+
+--------------------------------------------------
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ self.bar = [NSMutableString string]; // avoid
+ }
+ return self;
+}
+
+- (void)dealloc {
+ self.bar = nil; // avoid
+ [super dealloc];
+}
+--------------------------------------------------
+
+=== Dealloc Instance Variables in Declaration Order
+
+
+
+`dealloc` should process instance variables in the same order the `@interface` declares them, so it is easier for a reviewer to verify.
+
+A code reviewer checking a new or revised `dealloc` implementation needs to make sure that every retained instance variable gets released.
+
+To simplify reviewing `dealloc`, order the code so that the retained instance variables get released in the same order that they are declared in the `@interface`. If `dealloc` invokes other methods that release instance variables, add comments describing what instance variables those methods handle.
+
+=== Setters copy NSStrings
+
+
+
+Setters taking an `NSString`, should always `copy` the string it accepts.
+
+Never just `retain` the string. This avoids the caller changing it under you without your knowledge. Don't assume that because you're accepting an `NSString` that it's not actually an `NSMutableString`.
+
+---------------------------------
+- (void)setFoo:(NSString *)aFoo {
+ [_foo autorelease];
+ _foo = [aFoo copy];
+}
+---------------------------------
+
+=== Avoid Throwing Exceptions
+
+
+
+Don't `@throw` Objective-C exceptions, but you should be prepared to catch them from third-party or OS calls.
+
+We do compile with `-fobjc-exceptions` (mainly so we get `@synchronized`), but we don't `@throw`. Use of `@try`, `@catch`, and `@finally` are allowed when required to properly use 3rd party code or libraries. If you do use them please document exactly which methods you expect to throw.
+
+=== nil Checks
+
+
+
+Use `nil` checks for logic flow only.
+
+Use `nil` pointer checks for logic flow of the application, not for preventing crashes when sending messages. With current compilers (http://www.sealiesoftware.com/blog/archive/2012/2/29/objc_explain_return_value_of_message_to_nil.html[as of LLVM 3.0/Xcode 4.2]), sending a message to `nil` reliably returns nil as a pointer, zero as an integer or floating-point value, structs initialized to 0, and `_Complex` values equal to \{0, 0}.
+
+Note that this applies to `nil` as a message target, not as a parameter value. Individual methods may or may not safely handle `nil` parameter values.
+
+Note too that this is distinct from checking C/C++ pointers and block pointers against `NULL`, which the runtime does not handle and will cause your application to crash. You still need to make sure you do not dereference a `NULL` pointer.
+
+=== BOOL Pitfalls
+
+
+
+Be careful when converting general integral values to `BOOL`. Avoid comparing directly with `YES`.
+
+`BOOL` is defined as a signed char in Objective-C which means that it can have values other than `YES` (1) and `NO` (0). Do not cast or convert general integral values directly to `BOOL`. Common mistakes include casting or converting an array's size, a pointer value, or the result of a bitwise logic operation to a `BOOL` which, depending on the value of the last byte of the integral result, could still result in a `NO` value. When converting a general integral value to a `BOOL` use ternery operators to return a `YES` or `NO` value.
+
+You can safely interchange and convert `BOOL`, `_Bool` and `bool` (see C++ Std 4.7.4, 4.12 and C99 Std 6.3.1.2). You cannot safely interchange `BOOL` and `Boolean` so treat `Booleans` as a general integral value as discussed above. Only use `BOOL` in Objective C method signatures.
+
+Using logical operators (`&&`, `||` and `!`) with `BOOL` is also valid and will return values that can be safely converted to `BOOL` without the need for a ternery operator.
+
+---------------------------------------------
+- (BOOL)isBold {
+ return [self fontTraits] & NSFontBoldTrait;
+}
+- (BOOL)isValid {
+ return [self stringValue];
+}
+---------------------------------------------
+
+----------------------------------------------------------
+- (BOOL)isBold {
+ return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
+}
+- (BOOL)isValid {
+ return [self stringValue] != nil;
+}
+- (BOOL)isEnabled {
+ return [self isValid] && [self isBold];
+}
+----------------------------------------------------------
+
+Also, don't directly compare `BOOL` variables directly with `YES`. Not only is it harder to read for those well-versed in C, the first point above demonstrates that return values may not always be what you expect.
+
+---------------------------
+BOOL great = [foo isGreat];
+if (great == YES)
+ // ...be great!
+---------------------------
+
+---------------------------
+BOOL great = [foo isGreat];
+if (great)
+ // ...be great!
+---------------------------
+
+=== Properties
+
+
+
+Use of the @property directive is preferred, with the following caveat: properties are an Objective-C 2.0 feature which will limit your code to running on the iPhone and Mac OS X 10.5 (Leopard) and higher. Dot notation is allowed only for access to a declared `@property`.
+
+Naming
+
+A property's associated instance variable's name must conform to the leading _ requirement. The property's name should be the same as its associated instance variable without the leading _. The optional space between the `@property` and the opening parenthesis should be omitted, as seen in the examples.
+
+-------------------------------------------------
+@interface MyClass : NSObject
+@property(copy, nonatomic) NSString *name;
+@end
+
+@implementation MyClass
+// No code required for auto-synthesis, else use:
+// @synthesize name = _name;
+@end
+-------------------------------------------------
+
+Location
+
+A property's declaration must come immediately after the instance variable block of a class interface. A property's definition (if not using automatic synthesis) must come immediately after the `@implementation` block in a class definition. They are indented at the same level as the `@interface` or `@implementation` statements that they are enclosed in.
+
+------------------------------------------
+@interface MyClass : NSObject {
+ @private
+ NSString *_name;
+}
+@property(copy, nonatomic) NSString *name;
+@end
+
+@implementation MyClass
+@synthesize name = _name;
+
+- (instancetype)init {
+ ...
+}
+@end
+------------------------------------------
+
+Use Copy Attribute For Strings
+
+NSString properties should always be declared with the `copy` attribute.
+
+This logically follows from the requirement that setters for NSStrings always must use `copy` instead of `retain`.
+
+Atomicity
+
+Be aware of the overhead of properties. By default, all synthesized setters and getters are atomic. This gives each set and get calls a substantial amount of synchronization overhead. Declare your properties `nonatomic` unless you require atomicity.
+
+Dot notation
+
+Dot notation is idiomatic style for Objective-C 2.0. It may be used when doing simple operations to get and set a `@property` of an object, but should not be used to invoke other object behavior.
+
+----------------------------------
+NSString *oldName = myObject.name;
+myObject.name = @"Alice";
+----------------------------------
+
+-------------------------------------------------------------
+NSArray *array = [[NSArray arrayWithObject:@"hello"] retain];
+
+NSUInteger numberOfItems = array.count; // not a property
+array.release; // not a property
+-------------------------------------------------------------
+
+=== Interfaces Without Instance Variables
+
+
+
+Omit the empty set of braces on interfaces that do not declare any instance variables.
+
+-----------------------------
+@interface MyClass : NSObject
+// Does a lot of stuff
+- (void)fooBarBam;
+@end
+-----------------------------
+
+-------------------------------
+@interface MyClass : NSObject {
+}
+// Does a lot of stuff
+- (void)fooBarBam;
+@end
+-------------------------------
+
+=== Automatically Synthesized Instance Variables
+
+
+
+Use of automatically synthesized instance variables is preferred. Code that must support earlier versions of the compiler toolchain (Xcode 4.3 or earlier or when compiling with GCC) or is using properties inherited from a protocol should prefer the @synthesize directive.
+
+------------------------------------------------
+// Header file
+@protocol Thingy
+@property(nonatomic, copy) NSString *widgetName;
+@end
+
+@interface Foo : NSObject
+// A guy walks into a bar.
+@property(nonatomic, copy) NSString *bar;
+@end
+
+// Implementation file
+@interface Foo ()
+@property(nonatomic, retain) NSArray *baz;
+@end
+
+@implementation Foo
+@synthesize widgetName = _widgetName;
+@end
+------------------------------------------------
+
+Automatically synthesized instance variables take the form of the property's name prefixed with an underscore and so typically conform to the required variable naming style. If your property name is unusual, or you are otherwise unable to use automatically synthesized instance variables, use of the @synthesize directive is preferred, with the instance variable name specified explicitly (as @synthesize does not add a leading underscore by default).
+
+=== Automatic Reference Counting (ARC)
+
+
+
+For projects that use Xcode 4.2 or later and will run only on 64-bit Mac OS X 10.7 and iOS 5.0 and later, ARC is preferred. Use manual reference counting when supporting earlier environments where zeroing weak pointers are not available.
+
+Classes that require ARC should include a preprocessor directive to prevent compilation using manual reference counting.
+
+Ownership qualifiers like `__unsafe_unretained` and `__weak` should precede variable names. Specifying `__strong` for variables is not required since it is the default. Properties, on the other hand, should always specify the `strong` keyword rather than relying on the compiler default.
+
+Files that are compiled using ARC need to have preprocessor directives to prevent compilation without ARC. See the code snippet below for details.
+
+Example of an implementation file enforcing ARC style. Note that declaring instance variables in the @implementation is permitted when using ARC.
+
+-------------------------------------------------------
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+#import "Foo.h"
+
+@implementation Foo {
+ Bar* __weak _bar;
+ Baz* __unsafe_unretained _baz;
+}
+// ...
+@end
+-------------------------------------------------------
+
+=== NSNumber Literals
+
+
+
+For projects that use Xcode 4.4 or later with clang, the use of http://clang.llvm.org/docs/ObjectiveCLiterals.html[NSNumber literals] is allowed. Note however that this will limit the portability of your code to other toolchains.
+
+NSNumber literals are used just like Objective C string literals. Boxing is used when necessary. Code using NSNumber literals can be deployed on any iOS/MacOS system.
+
+----------------------------------
+NSNumber *fortyTwo = @42;
+NSNumber *piOverTwo = @(M_PI / 2);
+enum {
+ kMyEnum = 2;
+};
+NSNumber *myEnum = @(kMyEnum);
+----------------------------------
+
+[[Cocoa_Patterns]]
+== Cocoa Patterns
+
+=== Delegate Pattern
+
+
+
+Delegate objects should not be retained when doing so would create a retain cycle.
+
+A class that implements the delegate pattern should typically:
+
+1. Have an instance variable named _delegate to reference the delegate.
+2. Thus, the accessor methods should be named `delegate` and `setDelegate:`.
+3. The _delegate object should be weak if the class is typically retained by its delegate, such that a strong delegate would create a retain cycle.
+
+=== Model/View/Controller
+
+
+
+Separate the model from the view. Separate the controller from the view and the model. Use `@protocol`s for callback APIs.
+
+
+* Separate model from view: don't build assumptions about the presentation into the model or data source. Keep the interface between the data source and the presentation abstract. Don't give the model knowledge of its view. (A good rule of thumb is to ask yourself if it's possible to have multiple presentations, with different states, on a single instance of your data source.)
+
+* Separate controller from view and model: don't put all of the "business logic" into view-related classes; this makes the code very unusable. Make controller classes to host this code, but ensure that the controller classes don't make too many assumptions about the presentation.
+
+* Define callback APIs with `@protocol`, using `@optional` if not all the methods are required.
+
+[[Historical_Notes]]
+== Historical Notes
+
+=== Trailing vs Leading Underscores
+
+
+
+Trailing underscores were once preferred for instance variable names.
+
+Our style guide used to have a rule saying that instance variables should be named with a trailing underscore, similar to the naming of member variables in C++. This was changed to leading underscores to be consistent with the broader Objective-C community, to better follow Apple's official guidelines, and to allow for use of new compiler features like automatic instance variable synthesis. New projects are strongly encouraged to use leading underscores. Existing projects may continue to use trailing underscores in new code to maintain consistency with the rest of their codebase.
+
+'''''
+
+Revision 2.59
+
+Mike Pinkerton +
+ Greg Miller +
+ Dave MacLachlan +
diff --git a/objcguide.xml b/objcguide.xml
deleted file mode 100644
index 68b6209..0000000
--- a/objcguide.xml
+++ /dev/null
@@ -1,1884 +0,0 @@
-
-
-
-
-
-
-Revision 2.59
-
-
-
-
-
-
- Mike Pinkerton
- Greg Miller
- Dave MacLachlan
-
-
-
-
-
-
-
-
- This style guide contains many details that are initially
- hidden from view. They are marked by the triangle icon, which you
- see here on your left. Click it now.
- You should see "Hooray" appear below.
-
-
-
- Hooray! Now you know you can expand points to get more
- details. Alternatively, there's an "expand all" at the
- top of this document.
-
-
-
-
-
-
-
-
- Objective-C is a very dynamic, object-oriented extension of C. It's
- designed to be easy to use and read, while enabling sophisticated
- object-oriented design. It is the primary development language for new
- applications on Mac OS X and the iPhone.
-
-
-
- Cocoa is one of the main application frameworks on Mac OS X. It is a
- collection of Objective-C classes that provide for rapid development of
- full-featured Mac OS X applications.
-
-
-
- Apple has already written a very good, and widely accepted, coding guide
- for Objective-C. Google has also written a similar guide for C++. This
- Objective-C guide aims to be a very natural combination of Apple's and
- Google's general recommendations. So, before reading this guide, please make
- sure you've read:
-
- -
-
- Apple's Cocoa Coding Guidelines
-
-
- -
-
-
-
-
-
-
-
-
-
- Note that all things that are banned in Google's C++ guide are also
- banned in Objective-C++, unless explicitly noted in this document.
-
-
-
- The purpose of this document is to describe the Objective-C (and
- Objective-C++) coding guidelines and practices that should be used for all
- Mac OS X code. Many of these guidelines have evolved and been proven over
- time on other projects and teams.
-
- Open-source projects developed by Google
- conform to the requirements in this guide.
-
-
-
- Google has already released open-source code that conforms to these
- guidelines as part of the
-
- Google Toolbox for Mac project
-
- (abbreviated GTM throughout this document).
- Code meant to be shared across different projects is a good candidate to
- be included in this repository.
-
-
-
-
-
- Note that this guide is not an Objective-C tutorial. We assume that the
- reader is familiar with the language. If you are new to Objective-C or
- need a refresher, please read
-
- Programming with Objective-C
- .
-
-
-
-
-
-
-
- They say an example is worth a thousand words so let's start off with an
- example that should give you a feel for the style, spacing, naming, etc.
-
-
-
- An example header file, demonstrating the correct commenting and spacing
- for an @interface
declaration
-
-
-
- #import <Foundation/Foundation.h>
-
- // A sample class demonstrating good Objective-C style. All interfaces,
- // categories, and protocols (read: all non-trivial top-level declarations
- // in a header) MUST be commented. Comments must also be adjacent to the
- // object they're documenting.
- //
- // (no blank line between this comment and the interface)
- @interface Foo : NSObject
-
- // Returns an autoreleased instance of Foo. See -initWithBar: for details
- // about |bar|.
- + (instancetype)fooWithBar:(NSString *)bar;
-
- // Designated initializer. |bar| is a thing that represents a thing that
- // does a thing.
- - (instancetype)initWithBar:(NSString *)bar;
-
- // Gets and sets |_bar|.
- - (NSString *)bar;
- - (void)setBar:(NSString *)bar;
-
- // Does some work with |blah| and returns YES if the work was completed
- // successfully, and NO otherwise.
- - (BOOL)doWorkWithBlah:(NSString *)blah;
-
- @end
-
-
-
- An example source file, demonstrating the correct commenting and spacing
- for the @implementation
of an interface. It also includes the
- reference implementations for important methods like getters and setters,
- init
, and dealloc
.
-
-
-
- #import "Foo.h"
-
-
- @implementation Foo {
- NSString *_bar;
- NSString *_foo;
- }
-
- + (instancetype)fooWithBar:(NSString *)bar {
- return [[[self alloc] initWithBar:bar] autorelease];
- }
-
- // Must always override super's designated initializer.
- - (instancetype)init {
- return [self initWithBar:nil];
- }
-
- - (instancetype)initWithBar:(NSString *)bar {
- if ((self = [super init])) {
- _bar = [bar copy];
- _bam = [[NSString alloc] initWithFormat:@"hi %d", 3];
- }
- return self;
- }
-
- - (void)dealloc {
- [_bar release];
- [_bam release];
- [super dealloc];
- }
-
- - (NSString *)bar {
- return _bar;
- }
-
- - (void)setBar:(NSString *)bar {
- [_bar autorelease];
- _bar = [bar copy];
- }
-
- - (BOOL)doWorkWithBlah:(NSString *)blah {
- // ...
- return NO;
- }
-
- @end
-
-
-
- Blank lines before and after @interface
,
- @implementation
, and @end
are optional. If your
- @interface
declares instance variables, a blank
- line should come after the closing brace (}
).
-
-
- Unless an interface or implementation is very short, such as when declaring
- a handful of private methods or a bridge class, adding blank lines usually
- helps readability.
-
-
-
-
-
-
-
-
- Use only spaces, and indent 2 spaces at a time.
-
-
-
- We use spaces for indentation. Do not use tabs in your code.
- You should set your editor to emit spaces when you hit the tab
- key.
-
-
-
-
-
-
- The maximum line length for Objective-C and Objective-C++ files is 100
- columns. Projects may opt to use an 80 column limit for consistency with
- the C++ style guide.
-
-
-
- You can make violations easier to spot by enabling Preferences >
- Text Editing > Page guide at column: 100 in Xcode.
-
-
-
-
-
-
- One space should be used between the -
or +
- and the return type, and no spacing in the parameter list except between
- parameters.
-
-
-
- Methods should look like this:
-
-
- - (void)doSomethingWithString:(NSString *)theString {
- ...
- }
-
-
- The spacing before the asterisk is optional. When adding new code,
- be consistent with the surrounding file's style.
-
-
- If you have too many parameters to fit on one line, giving each its
- own line is preferred. If multiple lines are used, align each using
- the colon before the parameter.
-
-
- - (void)doSomethingWith:(GTMFoo *)theFoo
- rect:(NSRect)theRect
- interval:(float)theInterval {
- ...
- }
-
-
- When the first keyword is shorter than the others, indent the later
- lines by at least four spaces, maintaining colon alignment:
-
-
- - (void)short:(GTMFoo *)theFoo
- longKeyword:(NSRect)theRect
- evenLongerKeyword:(float)theInterval
- error:(NSError **)theError {
- ...
- }
-
-
-
-
-
-
- Method invocations should be formatted much like method declarations.
- When there's a choice of formatting styles, follow the convention
- already used in a given source file.
-
-
-
- Invocations should have all arguments on one line:
-
-
- [myObject doFooWith:arg1 name:arg2 error:arg3];
-
-
- or have one argument per line, with colons aligned:
-
-
- [myObject doFooWith:arg1
- name:arg2
- error:arg3];
-
-
- Don't use any of these styles:
-
-
- [myObject doFooWith:arg1 name:arg2 // some lines with >1 arg
- error:arg3];
-
- [myObject doFooWith:arg1
- name:arg2 error:arg3];
-
- [myObject doFooWith:arg1
- name:arg2 // aligning keywords instead of colons
- error:arg3];
-
-
-
- As with declarations and definitions, when the first keyword is shorter
- than the others, indent the later lines by at least four spaces,
- maintaining colon alignment:
-
-
- [myObj short:arg1
- longKeyword:arg2
- evenLongerKeyword:arg3
- error:arg4];
-
-
- Invocations containing inlined blocks may have
- their segments left-aligned at a four space indent.
-
-
-
-
-
-
- The @public
and @private
access modifiers
- should be indented by 1 space.
-
-
-
- This is similar to public
, private
, and
- protected
in C++.
-
-
- @interface MyClass : NSObject {
- @public
- ...
- @private
- ...
- }
- @end
-
-
-
-
-
-
- Format exceptions with each @
label on its own line and a
- space between the @
label and the opening brace
- ({
), as well as between the @catch
and the
- caught object declaration.
-
-
-
- If you must use Obj-C exceptions, format them as follows. However, see
- Avoid Throwing Exceptions for
- reasons why you should not be using exceptions.
-
-
- @try {
- foo();
- }
- @catch (NSException *ex) {
- bar(ex);
- }
- @finally {
- baz();
- }
-
-
-
-
-
-
- There should not be a space between the type identifier and the name
- of the protocol encased in angle brackets.
-
-
-
- This applies to class declarations, instance variables, and method
- declarations. For example:
-
-
- @interface MyProtocoledClass : NSObject<NSWindowDelegate> {
- @private
- id<MyFancyDelegate> _delegate;
- }
- - (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
- @end
-
-
-
-
-
-
- Code inside blocks should be indented four spaces.
-
-
-
- There are several appropriate style rules, depending on how long the
- block is:
-
-
- - If the block can fit on one line, no wrapping is necessary.
- -
- If it has to wrap, the closing brace should line up with the first
- character of the line on which the block is declared.
-
- - Code within the block should be indented four spaces.
- -
- If the block is large, e.g. more than 20 lines, it is recommended to
- move it out-of-line into a local variable.
-
- -
- If the block takes no parameters, there are no spaces between the
- characters
^{
. If the block takes parameters, there is no
- space between the ^(
characters, but there is one space
- between the ) {
characters.
-
- -
- Invocations containing inlined blocks may have their segments
- left-aligned at a four-space indent. This helps when invocations
- contain multiple inlined blocks.
-
- -
- Two space indents inside blocks are also allowed, but should only
- be used when it's consistent with the rest of the project's code.
-
-
-
- // The entire block fits on one line.
- [operation setCompletionBlock:^{ [self onOperationDone]; }];
-
- // The block can be put on a new line, indented four spaces, with the
- // closing brace aligned with the first character of the line on which
- // block was declared.
- [operation setCompletionBlock:^{
- [self.delegate newDataAvailable];
- }];
-
- // Using a block with a C API follows the same alignment and spacing
- // rules as with Objective-C.
- dispatch_async(_fileIOQueue, ^{
- NSString* path = [self sessionFilePath];
- if (path) {
- // ...
- }
- });
-
- // An example where the parameter wraps and the block declaration fits
- // on the same line. Note the spacing of |^(SessionWindow *window) {|
- // compared to |^{| above.
- [[SessionService sharedService]
- loadWindowWithCompletionBlock:^(SessionWindow *window) {
- if (window) {
- [self windowDidLoad:window];
- } else {
- [self errorLoadingWindow];
- }
- }];
-
- // An example where the parameter wraps and the block declaration does
- // not fit on the same line as the name.
- [[SessionService sharedService]
- loadWindowWithCompletionBlock:
- ^(SessionWindow *window) {
- if (window) {
- [self windowDidLoad:window];
- } else {
- [self errorLoadingWindow];
- }
- }];
-
- // Large blocks can be declared out-of-line.
- void (^largeBlock)(void) = ^{
- // ...
- };
- [_operationQueue addOperationWithBlock:largeBlock];
-
- // An example with multiple inlined blocks in one invocation.
- [myObject doSomethingWith:arg1
- firstBlock:^(Foo *a) {
- // ...
- }
- secondBlock:^(Bar *b) {
- // ...
- }];
-
-
-
-
-
-
- For projects using Xcode 4.4 or later and clang, the use of container
- (array and dictionary) literals is encouraged. If split across multiple
- lines, the contents should be indented two spaces.
-
-
-
- If the collection fits on one line, put a single space after the opening
- and before the closing brackets.
-
-
- NSArray* array = @[ [foo description], @"Another String", [bar description] ];
-
- NSDictionary* dict = @{ NSForegroundColorAttributeName : [NSColor redColor] };
-
-
- Not:
-
-
- NSArray* array = @[[foo description], [bar description]];
-
- NSDictionary* dict = @{NSForegroundColorAttributeName: [NSColor redColor]};
-
-
-
- If the collection spans more than a single line, place the opening
- bracket on the same line as the declaration, indent the body by two
- spaces, and place the closing bracket on a new line that is indented to
- the same level as the opening bracket.
-
-
- NSArray* array = @[
- @"This",
- @"is",
- @"an",
- @"array"
- ];
-
- NSDictionary* dictionary = @{
- NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12],
- NSForegroundColorAttributeName : fontColor
- };
-
-
-
- For dictionary literals, there should be one space before the colon and
- at least one space after it (to optionally align the values).
-
-
- NSDictionary* option1 = @{
- NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12],
- NSForegroundColorAttributeName : fontColor
- };
-
- NSDictionary* option2 = @{
- NSFontAttributeName : [NSFont fontWithName:@"Arial" size:12],
- NSForegroundColorAttributeName : fontColor
- };
-
-
- The following are all incorrect:
-
-
- // There should be a space before the colon.
- NSDictionary* wrong = @{
- AKey: @"b",
- BLongerKey: @"c",
- };
-
- // The items should each be on a new line, or the entire expression
- // should fit on one line.
- NSDictionary* alsoWrong= @{ AKey : @"a",
- BLongerKey : @"b" };
-
- // There should be no variable space before the colon, only after.
- NSDictionary* stillWrong = @{
- AKey : @"b",
- BLongerKey : @"c",
- };
-
-
-
-
-
-
-
-
- Naming rules are very important in maintainable code. Objective-C method
- names tend to be very long, but this has the benefit that a block of code
- can almost read like prose, thus rendering many comments unnecessary.
- When writing pure Objective-C code, we mostly follow standard Objective-C
- naming rules. These naming guidelines may differ
- significantly from those outlined in the C++ style guide. For example,
- Google's C++ style guide recommends the use of underscores between words
- in variable names, whereas this guide recommends the use of intercaps,
- which is standard in the Objective-C community.
-
-
- Any class, category, method, or variable name may use all capitals for
- initialisms
- within the name. This follows Apple's standard of using all capitals
- within a name for initialisms such as URL, TIFF, and EXIF.
-
-
- When writing Objective-C++, however, things are not so cut and dry. Many
- projects need to implement cross-platform C++ APIs with some Objective-C
- or Cocoa, or bridge between a C++ back-end and a native Cocoa front-end.
- This leads to situations where the two guides are directly at odds.
-
-
- Our solution is that the style follows that of the method/function being
- implemented. If you're in an @implementation
block, use the
- Objective-C naming rules. If you're implementing a method for a C++
- class
, use the C++ naming rules. This avoids the situation
- where instance variable and local variable naming rules are mixed within a
- single function, which would be a serious detriment to readability.
-
-
-
-
- File names should reflect the name of the class implementation that
- they contain—including case. Follow the convention that your
-
- project
- uses.
-
-
-
- File extensions should be as follows:
-
-
-
- .h
- C/C++/Objective-C header file
-
-
- .m
- Objective-C implementation file
-
-
- .mm
- Objective-C++ implementation file
-
-
- .cc
- Pure C++ implementation file
-
-
- .c
- C implementation file
-
-
-
- File names for categories should include the name of the class being
- extended, e.g. GTMNSString+Utils.h
or
- GTMNSTextView+Autocomplete.h
-
-
-
-
-
-
- Within a source file, Objective-C++ follows the style of the
- function/method you're implementing.
-
-
-
- In order to minimize clashes between the differing naming styles when
- mixing Cocoa/Objective-C and C++, follow the style of the method being
- implemented. If you're in an @implementation
block, use
- the Objective-C naming rules. If you're implementing a method for a
- C++ class
, use the C++ naming rules.
-
-
- // file: cross_platform_header.h
-
- class CrossPlatformAPI {
- public:
- ...
- int DoSomethingPlatformSpecific(); // impl on each platform
- private:
- int an_instance_var_;
- };
-
- // file: mac_implementation.mm
- #include "cross_platform_header.h"
-
- // A typical Objective-C class, using Objective-C naming.
- @interface MyDelegate : NSObject {
- @private
- int _instanceVar;
- CrossPlatformAPI* _backEndObject;
- }
- - (void)respondToSomething:(id)something;
- @end
- @implementation MyDelegate
- - (void)respondToSomething:(id)something {
- // bridge from Cocoa through our C++ backend
- _instanceVar = _backEndObject->DoSomethingPlatformSpecific();
- NSString* tempString = [NSString stringWithFormat:@"%d", _instanceVar];
- NSLog(@"%@", tempString);
- }
- @end
-
- // The platform-specific implementation of the C++ class, using
- // C++ naming.
- int CrossPlatformAPI::DoSomethingPlatformSpecific() {
- NSString* temp_string = [NSString stringWithFormat:@"%d", an_instance_var_];
- NSLog(@"%@", temp_string);
- return [temp_string intValue];
- }
-
-
-
-
-
-
- Class names (along with category and protocol names) should start as
- uppercase and use mixed case to delimit words.
-
-
-
- When designing code to be shared across multiple applications,
- prefixes are acceptable and recommended (e.g. GTMSendMessage
).
- Prefixes are also recommended for classes of large applications that
- depend on external libraries.
-
-
-
-
-
-
-
- Category names should start with a 2 or 3 character prefix
- identifying the category as part of a project or open for general
- use. The category name should incorporate the name of the class it's
- extending.
-
-
-
- For example, if we want to create a category on NSString
- for parsing, we would put the category in a file named
- GTMNSString+Parsing.h
, and the category itself would be
- named GTMStringParsingAdditions
(yes, we know the file
- name and the category name do not match, but this file could have many
- separate categories related to parsing). Methods in that category
- should share the prefix (gtm_myCategoryMethodOnAString:
)
- in order to prevent collisions in Objective-C which only has a single
- namespace. If the code isn't meant to be shared and/or doesn't run in
- a different address-space, the method naming isn't quite as
- important.
-
-
- There should be a single space between the class name and the opening
- parenthesis of the category.
-
-
- // Extending a framework class:
- @interface NSString (GTMStringParsingAdditions)
- - (NSString *)gtm_foobarString;
- @end
-
- // Making your methods and properties private:
- @interface FoobarViewController ()
- @property(nonatomic, retain) NSView *dongleView;
- - (void)performLayout;
- @end
-
-
-
-
-
-
- Method names should start as lowercase and then use mixed case.
- Each named parameter should also start as lowercase.
-
-
-
- The method name should read like a sentence if possible, meaning you
- should choose parameter names that flow with the method name. (e.g.
- convertPoint:fromRect:
or
- replaceCharactersInRange:withString:
). See Apple's
- Guide to Naming Methods for more details.
-
-
- Accessor methods should be named the same as the variable they're
- "getting", but they should not be prefixed with the word
- "get". For example:
-
- - (id)getDelegate; // AVOID
-
-
- - (id)delegate; // GOOD
-
-
-
- This is for Objective-C methods only. C++ method names and functions
- continue to follow the rules set in the C++ style guide.
-
-
-
-
-
-
- Variables names start with a lowercase and use mixed case to delimit
- words. Instance variables have leading underscores. For example:
- myLocalVariable, _myInstanceVariable.
-
-
-
-
- Do not use Hungarian notation for syntactic attributes,
- such as the static type of a variable (int or pointer). Give as
- descriptive a name as possible, within reason. Don't worry about
- saving horizontal space as it is far more important to make your
- code immediately understandable by a new reader. For example:
-
-
- int w;
- int nerr;
- int nCompConns;
- tix = [[NSMutableArray alloc] init];
- obj = [someObject object];
- p = [network port];
-
-
- int numErrors;
- int numCompletedConnections;
- tickets = [[NSMutableArray alloc] init];
- userInfo = [someObject object];
- port = [network port];
-
-
-
-
-
- Instance variables are mixed case and should be prefixed with an
- underscore e.g. _usernameTextField. Note that historically
- the convention was to put the underscore at the end of the name, and
- projects may opt to continue using trailing underscores in new code
- in order to maintain consistency within their codebase (see the
- Historical Notes section). It is recommended you leave old
- code as-is, unless doing so would create inconsistency within a class.
-
-
-
-
-
- Constant names (#defines, enums, const local variables, etc.) should
- start with a lowercase k and then use mixed case to
- delimit words. For example:
-
-
- const int kNumberOfFiles = 12;
- NSString *const kUserKey = @"kUserKey";
- enum DisplayTinge {
- kDisplayTingeGreen = 1,
- kDisplayTingeBlue = 2
- };
-
-
- Because Objective-C does not provide namespacing, constants with global
- scope should have an appropriate prefix to minimize the chance of name
- collision, typically like kClassNameFoo.
-
-
-
-
-
-
-
-
-
-
- Though a pain to write, they are absolutely vital to keeping our code
- readable. The following rules describe what you should comment and where.
- But remember: while comments are very important, the best code is
- self-documenting. Giving sensible names to types and variables is much
- better than using obscure names and then trying to explain them through
- comments.
-
-
- When writing your comments, write for your audience: the next
-
- contributor
- who will need to understand your code. Be generous—the next
- one may be you!
-
-
- Remember that all of the rules and conventions listed in the C++ Style
- Guide are in effect here, with a few additional points, below.
-
-
-
-
- A file may optionally start with a description of its contents.
-
-
-
-
- Every file should contain the following items, in order:
-
- - license boilerplate if neccessary. Choose the appropriate
- boilerplate for the license used by the project (e.g.
- Apache 2.0, BSD, LGPL, GPL).
- - a basic description of the contents of the file if necessary.
-
-
-
- If you make significant changes to a file with an author line,
- consider deleting the author line since revision history already
- provides a more detailed and accurate record of authorship.
-
-
-
-
-
-
- Every interface, category, and protocol declaration should have an
- accompanying comment describing its purpose and how it fits into the
- larger picture.
-
-
-
- // A delegate for NSApplication to handle notifications about app
- // launch and shutdown. Owned by the main app controller.
- @interface MyAppDelegate : NSObject {
- ...
- }
- @end
-
-
- If you have already described an interface in detail in the
- comments at the top of your file feel free to simply state
- "See comment at top of file for a complete description", but
- be sure to have some sort of comment.
-
-
- Additionally, each method in the public interface should have a
- comment explaining its function, arguments, return value, and any
- side effects.
-
-
- Document the synchronization assumptions the class makes, if
- any. If an instance of the class can be accessed by multiple
- threads, take extra care to document the rules and invariants
- surrounding multithreaded use.
-
-
-
-
-
-
- Use vertical bars to quote variable names and symbols in comments rather
- than quotes or naming the symbol inline.
-
-
-
- This helps eliminate ambiguity, especially when the symbol is a common
- word that might make the sentence read like it was poorly constructed.
- E.g. for a symbol "count":
-
-
- // Sometimes we need |count| to be less than zero.
-
-
- or when quoting something which already contains quotes
-
-
- // Remember to call |StringWithoutSpaces("foo bar baz")|
-
-
-
-
-
-
- Make the pointer ownership model as explicit as possible when it falls
- outside the most common Objective-C usage idioms.
-
-
-
-
- Instance variables which are pointers to objects derived from NSObject
- are presumed to be retained, and should be either commented as weak or
- declared with the __weak lifetime qualifier when applicable.
- Similarly, declared properties must specify an assign property
- attribute if they are not retained by the class. An exception is
- instance variables labeled as IBOutlets in desktop Mac software,
- which are presumed to not be retained.
-
-
- Where instance variables are pointers to Core Foundation, C++, and
- other non-Objective-C objects, they should always be declared with
- strong
and weak
comments to indicate which
- pointers are and are not retained. Core Foundation and other
- non-Objective-C object pointers require explicit memory management,
- even when building for automatic reference counting or garbage
- collection.
-
-
- Examples of strong and weak declarations:
-
- @interface MyDelegate : NSObject {
- @private
- IBOutlet NSButton *_okButton; // Normal NSControl; implicitly weak on Mac only
-
- AnObjcObject* _doohickey; // My doohickey
- __weak MyObjcParent *_parent; // So we can send msgs back (owns me)
-
- // non-NSObject pointers...
- CWackyCPPClass *_wacky; // Strong, some cross-platform object
- CFDictionaryRef *_dict; // Strong
- }
- @property(strong, nonatomic) NSString *doohickey;
- @property(weak, nonatomic) NSString *parent;
- @end
-
-
-
-
-
- Object ownership and lifetime are explicit when using ARC, so no
- additional comments are required.
-
-
-
-
-
-
-
-
-
-
-
- Instance variables should typically be declared in implementation files
- or auto-synthesized by properties. When ivars are declared in a header
- file, they should be marked @private
.
-
-
-
- @interface MyClass : NSObject {
- @private
- id _myInstanceVariable;
- }
- @end
-
-
-
-
-
-
- Comment and clearly identify your designated initializer.
-
-
-
- It is important for those who might be subclassing your class that the
- designated initializer be clearly identified. That way, they only need
- to subclass a single initializer (of potentially several) to guarantee
- their subclass' initializer is called. It also helps those debugging
- your class in the future understand the flow of initialization code if
- they need to step through it.
-
-
-
-
-
-
- When writing a subclass that requires an init...
method,
- make sure you override the superclass' designated initializer.
-
-
-
- If you fail to override the superclass' designated initializer, your
- initializer may not be called in all cases, leading to subtle and
- very difficult to find bugs.
-
-
-
-
-
-
- It is strongly recommended and typical practice to place overridden
- methods of NSObject
at the top of an
- @implementation
.
-
-
-
- This commonly applies (but is not limited) to the init...
,
- copyWithZone:
, and dealloc
methods.
- init...
methods should be grouped together, followed by
- other NSObject
methods.
-
-
- Convenience class methods for creating instances may precede the
- NSObject
methods.
-
-
-
-
-
-
- Don't initialize variables to 0
or nil
in the
- init method; it's redundant.
-
-
-
- All memory for a newly allocated object is initialized to 0 (except
- for isa), so don't clutter up the init
method
- by re-initializing variables to 0 or nil
.
-
-
-
-
-
-
- Do not invoke the NSObject
class method new
,
- nor override it in a subclass. Instead, use alloc
and
- init
methods to instantiate retained objects.
-
-
-
- Modern Objective-C code explicitly calls alloc
and an
- init
method to create and retain an object. As the
- new
class method is rarely used, it makes reviewing code
- for correct memory management more difficult.
-
-
-
-
-
-
- Keep your class simple; avoid "kitchen-sink" APIs. If a method doesn't
- need to be public, don't make it so. Use a private category to prevent
- cluttering the public header.
-
-
-
- Unlike C++, Objective-C doesn't have a way to differentiate between
- public and private methods—everything is public. As a result,
- avoid placing methods in the public API unless they are actually
- expected to be used by a consumer of the class. This helps reduce the
- likelihood they'll be called when you're not expecting it. This includes
- methods that are being overridden from the parent class. For internal
- implementation methods, use a category defined in the implementation
- file as opposed to adding them to the public header.
-
-
- #import "GTMFoo.h"
-
- @interface GTMFoo (PrivateDelegateHandling)
- - (NSString *)doSomethingWithDelegate; // Declare private method
- @end
-
- @implementation GTMFoo (PrivateDelegateHandling)
- ...
- - (NSString *)doSomethingWithDelegate {
- // Implement this method
- }
- ...
- @end
-
-
- If you are using Objective-C 2.0, you should instead declare your
- private category using a class
- extension, for example:
-
-
- @interface GMFoo () { ... }
-
-
- which will guarantee that the declared methods are implemented in the
- @implementation
section by issuing a compiler warning if
- they are not.
-
-
- Again, "private" methods are not really private. You could
- accidentally override a superclass's "private" method, thus making a
- very difficult bug to squash. In general, private methods should have
- a fairly unique name that will prevent subclasses from unintentionally
- overriding them.
-
-
- Finally, Objective-C categories are a great way to segment a large
- @implementation
section into more understandable chunks
- and to add new, application-specific functionality to the most
- appropriate class. For example, instead of adding "middle truncation"
- code to a random object in your app, make a new category on
- NSString
).
-
-
-
-
-
-
- #import
Objective-C/Objective-C++ headers, and
- #include
C/C++ headers.
-
-
-
- Choose between #import
and #include
based
- on the language of the header that you are including.
-
-
- - When including a header that uses Objective-C or Objective-C++,
- use
#import
.
- - When including a standard C or C++ header, use
-
#include
. The header should provide its own #define
- guard.
-
-
- Some Objective-C headers lack #define
guards, and expect
- to be included only by #import
. As Objective-C headers
- may only be included in Objective-C source files and other Objective-C
- headers, using #import
across the board is appropriate.
-
-
- Standard C and C++ headers without any Objective-C in them can expect
- to be included by ordinary C and C++ files. Since there is no
- #import
in standard C or C++, such files will be
- included by #include
in those cases. Using
- #include
for them in Objective-C source files as well
- means that these headers will always be included with the same
- semantics.
-
-
- This rule helps avoid inadvertent errors in cross-platform
- projects. A Mac developer introducing a new C or C++ header might
- forget to add #define
guards, which would not cause
- problems on the Mac if the new header were included with
- #import
, but would break builds on other platforms
- where #include
is used. Being consistent by using
- #include
on all platforms means that compilation is
- more likely to succeed everywhere or fail everywhere, and avoids
- the frustration of files working only on some platforms.
-
-
- #import <Cocoa/Cocoa.h>
- #include <CoreFoundation/CoreFoundation.h>
- #import "GTMFoo.h"
- #include "base/basictypes.h"
-
-
-
-
-
-
- Include root frameworks over individual files.
-
-
-
- While it may seem tempting to include individual system headers from a
- framework such as Cocoa or Foundation, in fact it's less work on the
- compiler if you include the top-level root framework. The root
- framework is generally pre-compiled and can be loaded much more
- quickly. In addition, remember to use #import
rather than
- #include
for Objective-C frameworks.
-
-
- #import <Foundation/Foundation.h> // good
-
-
- #import <Foundation/NSArray.h> // avoid
- #import <Foundation/NSString.h>
- ...
-
-
-
-
-
-
- When creating new temporary objects, autorelease
them on
- the same line as you create them rather than a separate
- release
later in the same method.
-
-
-
- While ever so slightly slower, this prevents someone from accidentally
- removing the release
or inserting a return
- before it and introducing a memory leak. E.g.:
-
-
- // AVOID (unless you have a compelling performance reason)
- MyController* controller = [[MyController alloc] init];
- // ... code here that might return ...
- [controller release];
-
-
- // BETTER
- MyController* controller = [[[MyController alloc] init] autorelease];
-
-
-
-
-
-
- Assignment of objects follows the autorelease
then
- retain
pattern.
-
-
-
- When assigning a new object to a variable, one must first release the
- old object to avoid a memory leak. There are several "correct" ways to
- handle this. We've chosen the "autorelease then retain" approach
- because it's less prone to error. Be aware in tight loops it can fill
- up the autorelease pool, and may be slightly less efficient, but we
- feel the tradeoffs are acceptable.
-
-
- - (void)setFoo:(GMFoo *)aFoo {
- [_foo autorelease]; // Won't dealloc if |_foo| == |aFoo|
- _foo = [aFoo retain];
- }
-
-
-
-
-
-
- Instance subclasses may be in an inconsistent state during
- init
and dealloc
method execution, so code in
- those methods should avoid invoking accessors.
-
-
-
- Subclasses have not yet been initialized or have already deallocated
- when init
and dealloc
methods execute, making
- accessor methods potentially unreliable. Whenever practical, directly
- assign to and release ivars in those methods rather than rely on
- accessors.
-
-
- - (instancetype)init {
- self = [super init];
- if (self) {
- _bar = [[NSMutableString alloc] init]; // good
- }
- return self;
- }
-
- - (void)dealloc {
- [_bar release]; // good
- [super dealloc];
- }
-
-
- - (instancetype)init {
- self = [super init];
- if (self) {
- self.bar = [NSMutableString string]; // avoid
- }
- return self;
- }
-
- - (void)dealloc {
- self.bar = nil; // avoid
- [super dealloc];
- }
-
-
-
-
-
-
- dealloc
should process instance variables in the same order
- the @interface
declares them, so it is easier for a reviewer
- to verify.
-
-
-
- A code reviewer checking a new or revised dealloc
- implementation needs to make sure that every retained instance
- variable gets released.
-
-
- To simplify reviewing dealloc
, order the code so that
- the retained instance variables get released in the same order that
- they are declared in the @interface
. If
- dealloc
invokes other methods that release instance
- variables, add comments describing what instance variables those
- methods handle.
-
-
-
-
-
-
- Setters taking an NSString
, should always copy
- the string it accepts.
-
-
-
- Never just retain
the string. This avoids the caller
- changing it under you without your knowledge. Don't assume that
- because you're accepting an NSString
that it's not
- actually an NSMutableString
.
-
-
- - (void)setFoo:(NSString *)aFoo {
- [_foo autorelease];
- _foo = [aFoo copy];
- }
-
-
-
-
-
-
- Don't @throw
Objective-C exceptions, but you should be
- prepared to catch them from third-party or OS calls.
-
-
-
- We do compile with -fobjc-exceptions
(mainly so we get
- @synchronized
), but we don't @throw
. Use of
- @try
, @catch
, and @finally
are
- allowed when required to properly use 3rd party code or libraries. If
- you do use them please document exactly which methods you expect to
- throw.
-
-
-
-
-
-
-
- Use nil
checks for logic flow only.
-
-
-
- Use nil
pointer checks for logic flow of the application,
- not for preventing crashes when sending messages. With current compilers
- (
- as of LLVM 3.0/Xcode 4.2), sending a message to nil
- reliably returns nil as a pointer, zero as an integer or floating-point
- value, structs initialized to 0, and _Complex
values equal
- to {0, 0}.
-
-
- Note that this applies to nil
as a message target, not as
- a parameter value. Individual methods may or may not safely handle
- nil
parameter values.
-
-
- Note too that this is distinct from checking C/C++ pointers and block
- pointers against NULL
, which the runtime does not handle
- and will cause your application to crash. You still need to make sure
- you do not dereference a NULL
pointer.
-
-
-
-
-
-
- Be careful when converting general integral values to BOOL
.
- Avoid comparing directly with YES
.
-
-
-
- BOOL
is defined as a signed char in Objective-C which means
- that it can have values other than YES
(1) and
- NO
(0). Do not cast or convert general integral values
- directly to BOOL
. Common mistakes include casting or
- converting an array's size, a pointer value, or the result of a bitwise
- logic operation to a BOOL
which, depending on the value of
- the last byte of the integral result, could still result in a
- NO
value. When converting a general integral value to a
- BOOL
use ternery operators to return a YES
or
- NO
value.
-
-
- You can safely interchange and convert BOOL
,
- _Bool
and bool
(see C++ Std 4.7.4, 4.12 and
- C99 Std 6.3.1.2). You cannot safely interchange BOOL
and
- Boolean
so treat Booleans
as a general
- integral value as discussed above. Only use BOOL
in
- Objective C method signatures.
-
-
- Using logical operators (&&
, ||
and
- !
) with BOOL
is also valid and will return
- values that can be safely converted to BOOL
without the
- need for a ternery operator.
-
-
- - (BOOL)isBold {
- return [self fontTraits] & NSFontBoldTrait;
- }
- - (BOOL)isValid {
- return [self stringValue];
- }
-
-
- - (BOOL)isBold {
- return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
- }
- - (BOOL)isValid {
- return [self stringValue] != nil;
- }
- - (BOOL)isEnabled {
- return [self isValid] && [self isBold];
- }
-
-
- Also, don't directly compare BOOL
variables directly
- with YES
. Not only is it harder to read for those
- well-versed in C, the first point above demonstrates that return
- values may not always be what you expect.
-
-
- BOOL great = [foo isGreat];
- if (great == YES)
- // ...be great!
-
-
- BOOL great = [foo isGreat];
- if (great)
- // ...be great!
-
-
-
-
-
-
-
- Use of the @property directive is preferred, with the following caveat:
- properties are an Objective-C 2.0 feature which will limit your code to
- running on the iPhone and Mac OS X 10.5 (Leopard) and higher. Dot notation
- is allowed only for access to a declared @property
.
-
-
-
-
- A property's associated instance variable's name must conform to the
- leading _ requirement. The property's name should be the same as its
- associated instance variable without the leading _. The optional space
- between the @property
and the opening parenthesis
- should be omitted, as seen in the examples.
-
-
-
- @interface MyClass : NSObject
- @property(copy, nonatomic) NSString *name;
- @end
-
- @implementation MyClass
- // No code required for auto-synthesis, else use:
- // @synthesize name = _name;
- @end
-
-
-
-
- A property's declaration must come immediately after the instance
- variable block of a class interface. A property's definition (if
- not using automatic synthesis) must come immediately after the
- @implementation
block in a class definition. They are
- indented at the same level as the @interface
or
- @implementation
statements that they are enclosed in.
-
-
- @interface MyClass : NSObject {
- @private
- NSString *_name;
- }
- @property(copy, nonatomic) NSString *name;
- @end
-
- @implementation MyClass
- @synthesize name = _name;
-
- - (instancetype)init {
- ...
- }
- @end
-
-
-
-
- NSString properties should always be declared with the
- copy
attribute.
-
-
- This logically follows from the requirement that setters for
- NSStrings always must use copy
instead of
- retain
.
-
-
-
-
- Be aware of the overhead of properties. By default, all synthesized
- setters and getters are atomic. This gives each set and get calls a
- substantial amount of synchronization overhead. Declare your
- properties nonatomic
unless you require atomicity.
-
-
-
-
- Dot notation is idiomatic style for Objective-C 2.0. It may be used
- when doing simple operations to get and set a @property
- of an object, but should not be used to invoke other object behavior.
-
-
- NSString *oldName = myObject.name;
- myObject.name = @"Alice";
-
-
- NSArray *array = [[NSArray arrayWithObject:@"hello"] retain];
-
- NSUInteger numberOfItems = array.count; // not a property
- array.release; // not a property
-
-
-
-
-
-
-
- Omit the empty set of braces on interfaces that do not declare any
- instance variables.
-
-
-
- @interface MyClass : NSObject
- // Does a lot of stuff
- - (void)fooBarBam;
- @end
-
-
- @interface MyClass : NSObject {
- }
- // Does a lot of stuff
- - (void)fooBarBam;
- @end
-
-
-
-
-
-
-
- Use of automatically synthesized instance variables is preferred. Code
- that must support earlier versions of the compiler toolchain (Xcode 4.3
- or earlier or when compiling with GCC) or is using properties inherited
- from a protocol should prefer the @synthesize directive.
-
-
-
-
- // Header file
- @protocol Thingy
- @property(nonatomic, copy) NSString *widgetName;
- @end
-
- @interface Foo : NSObject<Thingy>
- // A guy walks into a bar.
- @property(nonatomic, copy) NSString *bar;
- @end
-
- // Implementation file
- @interface Foo ()
- @property(nonatomic, retain) NSArray *baz;
- @end
-
- @implementation Foo
- @synthesize widgetName = _widgetName;
- @end
-
-
-
- Automatically synthesized instance variables take the form of the
- property's name prefixed with an underscore and so typically conform to
- the required variable naming style. If your property name is unusual,
- or you are otherwise unable to use automatically synthesized instance
- variables, use of the @synthesize directive is preferred, with the
- instance variable name specified explicitly (as @synthesize does not add
- a leading underscore by default).
-
-
-
-
-
-
-
- For projects that use Xcode 4.2 or later and will run only on 64-bit
- Mac OS X 10.7 and iOS 5.0 and later, ARC is preferred. Use manual
- reference counting when supporting earlier environments where zeroing
- weak pointers are not available.
-
-
- Classes that require ARC should include a preprocessor directive to
- prevent compilation using manual reference counting.
-
-
- Ownership qualifiers like __unsafe_unretained
and
- __weak
should precede variable names. Specifying
- __strong
for variables is not required since it is
- the default. Properties, on the other hand, should always specify the
- strong
keyword rather than relying on the compiler default.
-
-
- Files that are compiled using ARC need to have preprocessor directives
- to prevent compilation without ARC. See the code snippet below for
- details.
-
-
-
-
- Example of an implementation file enforcing ARC style. Note that
- declaring instance variables in the @implementation is permitted when
- using ARC.
-
- #if !defined(__has_feature) || !__has_feature(objc_arc)
- #error "This file requires ARC support."
- #endif
-
- #import "Foo.h"
-
- @implementation Foo {
- Bar* __weak _bar;
- Baz* __unsafe_unretained _baz;
- }
- // ...
- @end
-
-
-
-
-
-
-
-
- For projects that use Xcode 4.4 or later with clang, the use of
- NSNumber literals
- is allowed. Note however that this will limit the portability of your
- code to other toolchains.
-
-
-
-
- NSNumber literals are used just like Objective C string literals.
- Boxing is used when necessary. Code using NSNumber literals can be
- deployed on any iOS/MacOS system.
-
- NSNumber *fortyTwo = @42;
- NSNumber *piOverTwo = @(M_PI / 2);
- enum {
- kMyEnum = 2;
- };
- NSNumber *myEnum = @(kMyEnum);
-
-
-
-
-
-
-
-
-
-
-
- Delegate objects should not be retained when doing so would create
- a retain cycle.
-
-
-
- A class that implements the delegate pattern should typically:
-
- -
- Have an instance variable named _delegate to reference
- the delegate.
-
- -
- Thus, the accessor methods should be named
delegate
- and setDelegate:
.
-
- -
- The _delegate object should be weak if the class
- is typically retained by its delegate, such that a strong delegate
- would create a retain cycle.
-
-
-
-
-
-
-
-
- Separate the model from the view. Separate the controller from the
- view and the model. Use @protocol
s for callback APIs.
-
-
-
-
- -
- Separate model from view: don't build assumptions about the
- presentation into the model or data source. Keep the interface
- between the data source and the presentation abstract. Don't give
- the model knowledge of its view. (A good rule of thumb is to ask
- yourself if it's possible to have multiple presentations, with
- different states, on a single instance of your data source.)
-
- -
- Separate controller from view and model: don't put all of the
- "business logic" into view-related classes; this makes the code
- very unusable. Make controller classes to host this code, but
- ensure that the controller classes don't make too many assumptions
- about the presentation.
-
- -
- Define callback APIs with
@protocol
, using
- @optional
if not all the methods are required.
-
-
-
-
-
-
-
-
-
-
-
-
- Trailing underscores were once preferred for instance variable names.
-
-
-
- Our style guide used to have a rule saying that instance variables
- should be named with a trailing underscore, similar to the naming of
- member variables in C++. This was changed to leading underscores to
- be consistent with the broader Objective-C community, to better follow
- Apple's official guidelines, and to allow for use of new compiler
- features like automatic instance variable synthesis. New projects are
- strongly encouraged to use leading underscores. Existing projects may
- continue to use trailing underscores in new code to maintain
- consistency with the rest of their codebase.
-
-
-
-
-
-
-
-
-
-Revision 2.59
-
-
-
-
-
-Mike Pinkerton
-Greg Miller
-Dave MacLachlan
-
-
diff --git a/pyguide.asciidoc b/pyguide.asciidoc
new file mode 100644
index 0000000..34e43b6
--- /dev/null
+++ b/pyguide.asciidoc
@@ -0,0 +1,1250 @@
+= Google Python Style Guide
+:sectlinks:
+
+Revision 2.59
+
+Amit Patel +
+ Antoine Picard +
+ Eugene Jhong +
+ Jeremy Hylton +
+ Matt Smart +
+ Mike Shields +
+
+
+
+
+
+Table of Contents
+
+[width="100%",cols="50%,50%",]
+|=======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
+a|
+link:#python-language-rules[Python Language Rules]
+
+ a|
+link:#lint[Lint] link:#imports[Imports] link:#packages[Packages] link:#exceptions[Exceptions] link:#global-variables[Global variables] link:#nested-local-inner-classes-and-functions[Nested/Local/Inner Classes and Functions] link:#list-comprehensions[List Comprehensions] link:#default-iterators-and-operators[Default Iterators and Operators] link:#generators[Generators] link:#lambda-functions[Lambda Functions] link:#conditional-expressions[Conditional Expressions] link:#default-argument-values[Default Argument Values] link:#properties[Properties] link:#true-false-evaluations[True/False evaluations] link:#deprecated-language-features[Deprecated Language Features] link:#lexical-scoping[Lexical Scoping] link:#function-and-method-decorators[Function and Method Decorators] link:#threading[Threading] link:#power-features[Power Features]
+
+a|
+link:#python-style-rules[Python Style Rules]
+
+ a|
+link:#semicolons[Semicolons] link:#line-length[Line length] link:#parentheses[Parentheses] link:#indentation[Indentation] link:#blank-lines[Blank Lines] link:#whitespace[Whitespace] link:#shebang-line[Shebang Line] link:#comments[Comments] link:#classes[Classes] link:#strings[Strings] link:#files-and-sockets[Files and Sockets] link:#todo-comments[TODO Comments] link:#imports-formatting[Imports formatting] link:#statements[Statements] link:#access-control[Access Control] link:#naming[Naming] link:#main[Main]
+
+|=======================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
+
+[[Important_Note]]
+== Important Note
+
+=== Displaying Hidden Details in this Guide
+
+
+
+This style guide contains many details that are initially hidden from view. They are marked by the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear below.
+
+Hooray! Now you know you can expand points to get more details. Alternatively, there's a "toggle all" at the top of this document.
+
+[[Background]]
+== Background
+
+Python is the main scripting language used at Google. This style guide is a list of __do__s and __don't__s for Python programs.
+
+To help you format code correctly, we've created a link:google_python_style.vim[settings file for Vim]. For Emacs, the default settings should be fine.
+
+[[Python_Language_Rules]]
+== Python Language Rules
+
+=== Lint
+
+
+
+Run `pylint` over your code.
+
+Definition: pylint is a tool for finding bugs and style problems in Python source code. It finds problems that are typically caught by a compiler for less dynamic languages like C and C++. Because of the dynamic nature of Python, some warnings may be incorrect; however, spurious warnings should be fairly infrequent.
+
+Pros: Catches easy-to-miss errors like typos, using-vars-before-assignment, etc.
+
+Cons: `pylint` isn't perfect. To take advantage of it, we'll need to sometimes: a) Write around it b) Suppress its warnings or c) Improve it.
+
+Decision: Make sure you run `pylint` on your code. Suppress warnings if they are inappropriate so that other issues are not hidden.
+
+To suppress warnings, you can set a line-level comment:
+
+-------------------------------------------------------------------------
+dict = 'something awful' # Bad Idea... pylint: disable=redefined-builtin
+-------------------------------------------------------------------------
+
+pylint warnings are each identified by a alphanumeric code (`C0112`) and a symbolic name (`empty-docstring`). Prefer the symbolic names in new code or when updating existing code.
+
+If the reason for the suppression is not clear from the symbolic name, add an explanation.
+
+Suppressing in this way has the advantage that we can easily search for suppressions and revisit them.
+
+You can get a list of pylint warnings by doing `pylint --list-msgs`. To get more information on a particular message, use `pylint --help-msg=C6409`.
+
+Prefer `pylint: disable` to the deprecated older form `pylint: disable-msg`.
+
+Unused argument warnings can be suppressed by using `_' as the identifier for the unused argument or prefixing the argument name with `unused_'. In situations where changing the argument names is infeasible, you can mention them at the beginning of the function. For example:
+
+-----------------------------------------------
+def foo(a, unused_b, unused_c, d=None, e=None):
+ _ = d, e
+ return a
+-----------------------------------------------
+
+=== Imports
+
+
+
+Use `import`s for packages and modules only.
+
+Definition: Reusability mechanism for sharing code from one module to another.
+
+Pros: The namespace management convention is simple. The source of each identifier is indicated in a consistent way; `x.Obj` says that object `Obj` is defined in module `x`.
+
+Cons: Module names can still collide. Some module names are inconveniently long.
+
+Decision: Use `import x` for importing packages and modules. +
+ Use `from x import y` where `x` is the package prefix and `y` is the module name with no prefix. +
+ Use `from x import y as z` if two modules named `y` are to be imported or if `y` is an inconveniently long name.
+
+For example the module `sound.effects.echo` may be imported as follows:
+
+--------------------------------------------------
+from sound.effects import echo
+...
+echo.EchoFilter(input, output, delay=0.7, atten=4)
+--------------------------------------------------
+
+Do not use relative names in imports. Even if the module is in the same package, use the full package name. This helps prevent unintentionally importing a package twice.
+
+=== Packages
+
+
+
+Import each module using the full pathname location of the module.
+
+Pros: Avoids conflicts in module names. Makes it easier to find modules.
+
+Cons: Makes it harder to deploy code because you have to replicate the package hierarchy.
+
+Decision: All new code should import each module by its full package name.
+
+Imports should be as follows:
+
+------------------------------------------------------
+# Reference in code with complete name.
+import sound.effects.echo
+
+# Reference in code with just module name (preferred).
+from sound.effects import echo
+------------------------------------------------------
+
+=== Exceptions
+
+
+
+Exceptions are allowed but must be used carefully.
+
+Definition: Exceptions are a means of breaking out of the normal flow of control of a code block to handle errors or other exceptional conditions.
+
+Pros: The control flow of normal operation code is not cluttered by error-handling code. It also allows the control flow to skip multiple frames when a certain condition occurs, e.g., returning from N nested functions in one step instead of having to carry-through error codes.
+
+Cons: May cause the control flow to be confusing. Easy to miss error cases when making library calls.
+
+Decision: Exceptions must follow certain conditions:
+
+* Raise exceptions like this: `raise MyException('Error message')` or `raise MyException`. Do not use the two-argument form (`raise MyException, 'Error message'`) or deprecated string-based exceptions (`raise 'Error message'`).
+* Modules or packages should define their own domain-specific base exception class, which should inherit from the built-in Exception class. The base exception for a module should be called `Error`.
++
+-----------------------
+class Error(Exception):
+ pass
+-----------------------
+* Never use catch-all `except:` statements, or catch `Exception` or `StandardError`, unless you are re-raising the exception or in the outermost block in your thread (and printing an error message). Python is very tolerant in this regard and `except:` will really catch everything including misspelled names, sys.exit() calls, Ctrl+C interrupts, unittest failures and all kinds of other exceptions that you simply don't want to catch.
+* Minimize the amount of code in a `try`/`except` block. The larger the body of the `try`, the more likely that an exception will be raised by a line of code that you didn't expect to raise an exception. In those cases, the `try`/`except` block hides a real error.
+* Use the `finally` clause to execute code whether or not an exception is raised in the `try` block. This is often useful for cleanup, i.e., closing a file.
+* When capturing an exception, use `as` rather than a comma. For example:
++
+----------------------
+try:
+ raise Error
+except Error as error:
+ pass
+----------------------
+
+=== Global variables
+
+
+
+Avoid global variables.
+
+Definition: Variables that are declared at the module level.
+
+Pros: Occasionally useful.
+
+Cons: Has the potential to change module behavior during the import, because assignments to module-level variables are done when the module is imported.
+
+Decision: Avoid global variables in favor of class variables. Some exceptions are:
+
+* Default options for scripts.
+* Module-level constants. For example: `PI = 3.14159`. Constants should be named using all caps with underscores; see link:#naming[Naming] below.
+* It is sometimes useful for globals to cache values needed or returned by functions.
+* If needed, globals should be made internal to the module and accessed through public module level functions; see link:#naming[Naming] below.
+
+=== Nested/Local/Inner Classes and Functions
+
+
+
+Nested/local/inner classes and functions are fine.
+
+Definition: A class can be defined inside of a method, function, or class. A function can be defined inside a method or function. Nested functions have read-only access to variables defined in enclosing scopes.
+
+Pros: Allows definition of utility classes and functions that are only used inside of a very limited scope. Very http://en.wikipedia.org/wiki/Abstract_data_type[ADT]-y.
+
+Cons: Instances of nested or local classes cannot be pickled.
+
+Decision: They are fine.
+
+=== List Comprehensions
+
+
+
+Okay to use for simple cases.
+
+Definition: List comprehensions and generator expressions provide a concise and efficient way to create lists and iterators without resorting to the use of `map()`, `filter()`, or `lambda`.
+
+Pros: Simple list comprehensions can be clearer and simpler than other list creation techniques. Generator expressions can be very efficient, since they avoid the creation of a list entirely.
+
+Cons: Complicated list comprehensions or generator expressions can be hard to read.
+
+Decision: Okay to use for simple cases. Each portion must fit on one line: mapping expression, `for` clause, filter expression. Multiple `for` clauses or filter expressions are not permitted. Use loops instead when things get more complicated.
+
+-----------------------------------------------------
+Yes:
+ result = []
+ for x in range(10):
+ for y in range(5):
+ if x * y > 10:
+ result.append((x, y))
+
+ for x in xrange(5):
+ for y in xrange(5):
+ if x != y:
+ for z in xrange(5):
+ if y != z:
+ yield (x, y, z)
+
+ return ((x, complicated_transform(x))
+ for x in long_generator_function(parameter)
+ if x is not None)
+
+ squares = [x * x for x in range(10)]
+
+ eat(jelly_bean for jelly_bean in jelly_beans
+ if jelly_bean.color == 'black')
+-----------------------------------------------------
+
+----------------------------------------------------------------------
+No:
+ result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
+
+ return ((x, y, z)
+ for x in xrange(5)
+ for y in xrange(5)
+ if x != y
+ for z in xrange(5)
+ if y != z)
+----------------------------------------------------------------------
+
+=== Default Iterators and Operators
+
+
+
+Use default iterators and operators for types that support them, like lists, dictionaries, and files.
+
+Definition: Container types, like dictionaries and lists, define default iterators and membership test operators ("in" and "not in").
+
+Pros: The default iterators and operators are simple and efficient. They express the operation directly, without extra method calls. A function that uses default operators is generic. It can be used with any type that supports the operation.
+
+Cons: You can't tell the type of objects by reading the method names (e.g. has_key() means a dictionary). This is also an advantage.
+
+Decision: Use default iterators and operators for types that support them, like lists, dictionaries, and files. The built-in types define iterator methods, too. Prefer these methods to methods that return lists, except that you should not mutate a container while iterating over it.
+
+---------------------------------------
+Yes: for key in adict: ...
+ if key not in adict: ...
+ if obj in alist: ...
+ for line in afile: ...
+ for k, v in dict.iteritems(): ...
+---------------------------------------
+
+----------------------------------------
+No: for key in adict.keys(): ...
+ if not adict.has_key(key): ...
+ for line in afile.readlines(): ...
+----------------------------------------
+
+=== Generators
+
+
+
+Use generators as needed.
+
+Definition: A generator function returns an iterator that yields a value each time it executes a yield statement. After it yields a value, the runtime state of the generator function is suspended until the next value is needed.
+
+Pros: Simpler code, because the state of local variables and control flow are preserved for each call. A generator uses less memory than a function that creates an entire list of values at once.
+
+Cons: None.
+
+Decision: Fine. Use "Yields:" rather than "Returns:" in the doc string for generator functions.
+
+=== Lambda Functions
+
+
+
+Okay for one-liners.
+
+Definition: Lambdas define anonymous functions in an expression, as opposed to a statement. They are often used to define callbacks or operators for higher-order functions like `map()` and `filter()`.
+
+Pros: Convenient.
+
+Cons: Harder to read and debug than local functions. The lack of names means stack traces are more difficult to understand. Expressiveness is limited because the function may only contain an expression.
+
+Decision: Okay to use them for one-liners. If the code inside the lambda function is any longer than 60–80 chars, it's probably better to define it as a regular (nested) function.
+
+For common operations like multiplication, use the functions from the `operator` module instead of lambda functions. For example, prefer `operator.mul` to `lambda x, y: x * y`.
+
+=== Conditional Expressions
+
+
+
+Okay for one-liners.
+
+Definition: Conditional expressions are mechanisms that provide a shorter syntax for if statements. For example: `x = 1 if cond else 2`.
+
+Pros: Shorter and more convenient than an if statement.
+
+Cons: May be harder to read than an if statement. The condition may be difficult to locate if the expression is long.
+
+Decision: Okay to use for one-liners. In other cases prefer to use a complete if statement.
+
+=== Default Argument Values
+
+
+
+Okay in most cases.
+
+Definition: You can specify values for variables at the end of a function's parameter list, e.g., `def foo(a, b=0):`. If `foo` is called with only one argument, `b` is set to 0. If it is called with two arguments, `b` has the value of the second argument.
+
+Pros: Often you have a function that uses lots of default values, but—rarely—you want to override the defaults. Default argument values provide an easy way to do this, without having to define lots of functions for the rare exceptions. Also, Python does not support overloaded methods/functions and default arguments are an easy way of "faking" the overloading behavior.
+
+Cons: Default arguments are evaluated once at module load time. This may cause problems if the argument is a mutable object such as a list or a dictionary. If the function modifies the object (e.g., by appending an item to a list), the default value is modified.
+
+Decision: Okay to use with the following caveat:
+
+Do not use mutable objects as default values in the function or method definition.
+
+------------------------
+Yes: def foo(a, b=None):
+ if b is None:
+ b = []
+------------------------
+
+-------------------------------------------------------------------------
+No: def foo(a, b=[]):
+ ...
+No: def foo(a, b=time.time()): # The time the module was loaded???
+ ...
+No: def foo(a, b=FLAGS.my_thing): # sys.argv has not yet been parsed...
+ ...
+-------------------------------------------------------------------------
+
+=== Properties
+
+
+
+Use properties for accessing or setting data where you would normally have used simple, lightweight accessor or setter methods.
+
+Definition: A way to wrap method calls for getting and setting an attribute as a standard attribute access when the computation is lightweight.
+
+Pros: Readability is increased by eliminating explicit get and set method calls for simple attribute access. Allows calculations to be lazy. Considered the Pythonic way to maintain the interface of a class. In terms of performance, allowing properties bypasses needing trivial accessor methods when a direct variable access is reasonable. This also allows accessor methods to be added in the future without breaking the interface.
+
+Cons: Properties are specified after the getter and setter methods are declared, requiring one to notice they are used for properties farther down in the code (except for readonly properties created with the `@property` decorator - see below). Must inherit from `object`. Can hide side-effects much like operator overloading. Can be confusing for subclasses.
+
+Decision: Use properties in new code to access or set data where you would normally have used simple, lightweight accessor or setter methods. Read-only properties should be created with the `@property` link:#function-and-method-decorators[decorator].
+
+ Inheritance with properties can be non-obvious if the property itself is not overridden. Thus one must make sure that accessor methods are called indirectly to ensure methods overridden in subclasses are called by the property (using the Template Method DP).
+
+------------------------------------------------------------------------------------
+Yes: import math
+
+ class Square(object):
+ """A square with two properties: a writable area and a read-only perimeter.
+
+ To use:
+ >>> sq = Square(3)
+ >>> sq.area
+ 9
+ >>> sq.perimeter
+ 12
+ >>> sq.area = 16
+ >>> sq.side
+ 4
+ >>> sq.perimeter
+ 16
+ """
+
+ def __init__(self, side):
+ self.side = side
+
+ def __get_area(self):
+ """Calculates the 'area' property."""
+ return self.side ** 2
+
+ def ___get_area(self):
+ """Indirect accessor for 'area' property."""
+ return self.__get_area()
+
+ def __set_area(self, area):
+ """Sets the 'area' property."""
+ self.side = math.sqrt(area)
+
+ def ___set_area(self, area):
+ """Indirect setter for 'area' property."""
+ self.__set_area(area)
+
+ area = property(___get_area, ___set_area,
+ doc="""Gets or sets the area of the square.""")
+
+ @property
+ def perimeter(self):
+ return self.side * 4
+------------------------------------------------------------------------------------
+
+=== True/False evaluations
+
+
+
+Use the "implicit" false if at all possible.
+
+Definition: Python evaluates certain values as `false` when in a boolean context. A quick "rule of thumb" is that all "empty" values are considered `false` so `0, None, [], {}, ''` all evaluate as `false` in a boolean context.
+
+Pros: Conditions using Python booleans are easier to read and less error-prone. In most cases, they're also faster.
+
+Cons: May look strange to C/C++ developers.
+
+Decision: Use the "implicit" false if at all possible, e.g., `if foo:` rather than `if foo != []:`. There are a few caveats that you should keep in mind though:
+
+* Never use `==` or `!=` to compare singletons like `None`. Use `is` or `is not`.
+* Beware of writing `if x:` when you really mean `if x is not None:`—e.g., when testing whether a variable or argument that defaults to `None` was set to some other value. The other value might be a value that's false in a boolean context!
+* Never compare a boolean variable to `False` using `==`. Use `if not x:` instead. If you need to distinguish `False` from `None` then chain the expressions, such as `if not x and x is not None:`.
+* For sequences (strings, lists, tuples), use the fact that empty sequences are false, so `if not seq:` or `if seq:` is preferable to `if len(seq):` or `if not len(seq):`.
+* When handling integers, implicit false may involve more risk than benefit (i.e., accidentally handling `None` as 0). You may compare a value which is known to be an integer (and is not the result of `len()`) against the integer 0.
++
+--------------------------------------
+Yes: if not users:
+ print 'no users'
+
+ if foo == 0:
+ self.handle_zero()
+
+ if i % 10 == 0:
+ self.handle_multiple_of_ten()
+--------------------------------------
++
+--------------------------------------
+No: if len(users) == 0:
+ print 'no users'
+
+ if foo is not None and not foo:
+ self.handle_zero()
+
+ if not i % 10:
+ self.handle_multiple_of_ten()
+--------------------------------------
+* Note that `'0'` (i.e., `0` as string) evaluates to true.
+
+=== Deprecated Language Features
+
+
+
+Use string methods instead of the `string` module where possible. Use function call syntax instead of `apply`. Use list comprehensions and `for` loops instead of `filter` and `map` when the function argument would have been an inlined lambda anyway. Use `for` loops instead of `reduce`.
+
+Definition: Current versions of Python provide alternative constructs that people find generally preferable.
+
+Decision: We do not use any Python version which does not support these features, so there is no reason not to use the new styles.
+
+----------------------------------------------------------------
+Yes: words = foo.split(':')
+
+ [x[1] for x in my_list if x[2] == 5]
+
+ map(math.sqrt, data) # Ok. No inlined lambda expression.
+
+ fn(*args, **kwargs)
+----------------------------------------------------------------
+
+--------------------------------------------------------------
+No: words = string.split(foo, ':')
+
+ map(lambda x: x[1], filter(lambda x: x[2] == 5, my_list))
+
+ apply(fn, args, kwargs)
+--------------------------------------------------------------
+
+=== Lexical Scoping
+
+
+
+Okay to use.
+
+Definition: A nested Python function can refer to variables defined in enclosing functions, but can not assign to them. Variable bindings are resolved using lexical scoping, that is, based on the static program text. Any assignment to a name in a block will cause Python to treat all references to that name as a local variable, even if the use precedes the assignment. If a global declaration occurs, the name is treated as a global variable.
+
+An example of the use of this feature is:
+
+-----------------------------------------------------------------
+def get_adder(summand1):
+ """Returns a function that adds numbers to a given number."""
+ def adder(summand2):
+ return summand1 + summand2
+
+ return adder
+-----------------------------------------------------------------
+
+Pros: Often results in clearer, more elegant code. Especially comforting to experienced Lisp and Scheme (and Haskell and ML and …) programmers.
+
+Cons: Can lead to confusing bugs. Such as this example based on http://www.python.org/dev/peps/pep-0227/[PEP-0227]:
+
+--------------------------------------------------------------------
+i = 4
+def foo(x):
+ def bar():
+ print i,
+ # ...
+ # A bunch of code here
+ # ...
+ for i in x: # Ah, i *is* local to Foo, so this is what Bar sees
+ print i,
+ bar()
+--------------------------------------------------------------------
+
+So `foo([1, 2, 3])` will print `1 2 3 3`, not `1 2 3 4`.
+
+Decision: Okay to use.
+
+=== Function and Method Decorators
+
+
+
+Use decorators judiciously when there is a clear advantage.
+
+Definition: http://www.python.org/doc/2.4.3/whatsnew/node6.html[Decorators for Functions and Methods] (a.k.a "the `@` notation"). The most common decorators are `@classmethod` and `@staticmethod`, for converting ordinary methods to class or static methods. However, the decorator syntax allows for user-defined decorators as well. Specifically, for some function `my_decorator`, this:
+
+-------------------------
+class C(object):
+ @my_decorator
+ def method(self):
+ # method body ...
+-------------------------
+
+is equivalent to:
+
+---------------------------------
+class C(object):
+ def method(self):
+ # method body ...
+ method = my_decorator(method)
+---------------------------------
+
+Pros: Elegantly specifies some transformation on a method; the transformation might eliminate some repetitive code, enforce invariants, etc.
+
+Cons: Decorators can perform arbitrary operations on a function's arguments or return values, resulting in surprising implicit behavior. Additionally, decorators execute at import time. Failures in decorator code are pretty much impossible to recover from.
+
+Decision: Use decorators judiciously when there is a clear advantage. Decorators should follow the same import and naming guidelines as functions. Decorator pydoc should clearly state that the function is a decorator. Write unit tests for decorators.
+
+Avoid external dependencies in the decorator itself (e.g. don't rely on files, sockets, database connections, etc.), since they might not be available when the decorator runs (at import time, perhaps from `pydoc` or other tools). A decorator that is called with valid parameters should (as much as possible) be guaranteed to succeed in all cases.
+
+Decorators are a special case of "top level code" - see link:#main[main] for more discussion.
+
+=== Threading
+
+
+
+Do not rely on the atomicity of built-in types.
+
+While Python's built-in data types such as dictionaries appear to have atomic operations, there are corner cases where they aren't atomic (e.g. if `__hash__` or `__eq__` are implemented as Python methods) and their atomicity should not be relied upon. Neither should you rely on atomic variable assignment (since this in turn depends on dictionaries).
+
+Use the Queue module's `Queue` data type as the preferred way to communicate data between threads. Otherwise, use the threading module and its locking primitives. Learn about the proper use of condition variables so you can use `threading.Condition` instead of using lower-level locks.
+
+=== Power Features
+
+
+
+Avoid these features.
+
+Definition: Python is an extremely flexible language and gives you many fancy features such as metaclasses, access to bytecode, on-the-fly compilation, dynamic inheritance, object reparenting, import hacks, reflection, modification of system internals, etc.
+
+Pros: These are powerful language features. They can make your code more compact.
+
+Cons: It's very tempting to use these "cool" features when they're not absolutely necessary. It's harder to read, understand, and debug code that's using unusual features underneath. It doesn't seem that way at first (to the original author), but when revisiting the code, it tends to be more difficult than code that is longer but is straightforward.
+
+Decision: Avoid these features in your code.
+
+[[Python_Style_Rules]]
+== Python Style Rules
+
+=== Semicolons
+
+
+
+Do not terminate your lines with semi-colons and do not use semi-colons to put two commands on the same line.
+
+=== Line length
+
+
+
+Maximum line length is __80 characters__.
+
+Exceptions:
+
+* Long import statements.
+* URLs in comments.
+
+Do not use backslash line continuation.
+
+Make use of Python's http://docs.python.org/reference/lexical_analysis.html#implicit-line-joining[implicit line joining inside parentheses, brackets and braces]. If necessary, you can add an extra pair of parentheses around an expression.
+
+----------------------------------------------------------------------
+Yes: foo_bar(self, width, height, color='black', design=None, x='foo',
+ emphasis=None, highlight=0)
+
+ if (width == 0 and height == 0 and
+ color == 'red' and emphasis == 'strong'):
+----------------------------------------------------------------------
+
+When a literal string won't fit on a single line, use parentheses for implicit line joining.
+
+--------------------------------------------
+x = ('This will build a very long long '
+ 'long long long long long long string')
+--------------------------------------------
+
+Within comments, put long URLs on their own line if necessary.
+
+--------------------------------------------------------------------------------------------------------------------------
+Yes: # See details at
+ # http://www.example.com/us/developer/documentation/api/content/v2.0/csv_file_name_extension_full_specification.html
+--------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------
+No: # See details at
+ # http://www.example.com/us/developer/documentation/api/content/\
+ # v2.0/csv_file_name_extension_full_specification.html
+----------------------------------------------------------------------
+
+Make note of the indentation of the elements in the line continuation examples above; see the link:#indentation[indentation] section for explanation.
+
+=== Parentheses
+
+
+
+Use parentheses sparingly.
+
+Do not use them in return statements or conditional statements unless using parentheses for implied line continuation. (See above.) It is however fine to use parentheses around tuples.
+
+------------------------------------
+Yes: if foo:
+ bar()
+ while x:
+ x = bar()
+ if x and y:
+ bar()
+ if not x:
+ bar()
+ return foo
+ for (x, y) in dict.items(): ...
+------------------------------------
+
+-----------------
+No: if (x):
+ bar()
+ if not(x):
+ bar()
+ return (foo)
+-----------------
+
+=== Indentation
+
+
+
+Indent your code blocks with __4 spaces__.
+
+Never use tabs or mix tabs and spaces. In cases of implied line continuation, you should align wrapped elements either vertically, as per the examples in the link:#line-length[line length] section; or using a hanging indent of 4 spaces, in which case there should be no argument on the first line.
+
+-------------------------------------------------------
+Yes: # Aligned with opening delimiter
+ foo = long_function_name(var_one, var_two,
+ var_three, var_four)
+
+ # Aligned with opening delimiter in a dictionary
+ foo = {
+ long_dictionary_key: value1 +
+ value2,
+ ...
+ }
+
+ # 4-space hanging indent; nothing on first line
+ foo = long_function_name(
+ var_one, var_two, var_three,
+ var_four)
+
+ # 4-space hanging indent in a dictionary
+ foo = {
+ long_dictionary_key:
+ long_dictionary_value,
+ ...
+ }
+-------------------------------------------------------
+
+-------------------------------------------------
+No: # Stuff on first line forbidden
+ foo = long_function_name(var_one, var_two,
+ var_three, var_four)
+
+ # 2-space hanging indent forbidden
+ foo = long_function_name(
+ var_one, var_two, var_three,
+ var_four)
+
+ # No hanging indent in a dictionary
+ foo = {
+ long_dictionary_key:
+ long_dictionary_value,
+ ...
+ }
+-------------------------------------------------
+
+=== Blank Lines
+
+
+
+Two blank lines between top-level definitions, one blank line between method definitions.
+
+Two blank lines between top-level definitions, be they function or class definitions. One blank line between method definitions and between the `class` line and the first method. Use single blank lines as you judge appropriate within functions or methods.
+
+=== Whitespace
+
+
+
+Follow standard typographic rules for the use of spaces around punctuation.
+
+No whitespace inside parentheses, brackets or braces.
+
+--------------------------------
+Yes: spam(ham[1], {eggs: 2}, [])
+--------------------------------
+
+---------------------------------------
+No: spam( ham[ 1 ], { eggs: 2 }, [ ] )
+---------------------------------------
+
+No whitespace before a comma, semicolon, or colon. Do use whitespace after a comma, semicolon, or colon except at the end of the line.
+
+-------------------
+Yes: if x == 4:
+ print x, y
+ x, y = y, x
+-------------------
+
+--------------------
+No: if x == 4 :
+ print x , y
+ x , y = y , x
+--------------------
+
+No whitespace before the open paren/bracket that starts an argument list, indexing or slicing.
+
+------------
+Yes: spam(1)
+------------
+
+-------------
+No: spam (1)
+-------------
+
+------------------------------
+Yes: dict['key'] = list[index]
+------------------------------
+
+--------------------------------
+No: dict ['key'] = list [index]
+--------------------------------
+
+Surround binary operators with a single space on either side for assignment (`=`), comparisons (`==, <, >, !=, <>, <=, >=, in, not in, is, is not`), and Booleans (`and, or, not`). Use your better judgment for the insertion of spaces around arithmetic operators but always be consistent about whitespace on either side of a binary operator.
+
+-----------
+Yes: x == 1
+-----------
+
+--------
+No: x<1
+--------
+
+Don't use spaces around the '=' sign when used to indicate a keyword argument or a default parameter value.
+
+--------------------------------------------------------------
+Yes: def complex(real, imag=0.0): return magic(r=real, i=imag)
+--------------------------------------------------------------
+
+--------------------------------------------------------------------
+No: def complex(real, imag = 0.0): return magic(r = real, i = imag)
+--------------------------------------------------------------------
+
+Don't use spaces to vertically align tokens on consecutive lines, since it becomes a maintenance burden (applies to `:`, `#`, `=`, etc.):
+
+-----------------------------------------------------
+Yes:
+ foo = 1000 # comment
+ long_name = 2 # comment that should not be aligned
+
+ dictionary = {
+ 'foo': 1,
+ 'long_name': 2,
+ }
+-----------------------------------------------------
+
+--------------------------------------------------------
+No:
+ foo = 1000 # comment
+ long_name = 2 # comment that should not be aligned
+
+ dictionary = {
+ 'foo' : 1,
+ 'long_name': 2,
+ }
+--------------------------------------------------------
+
+=== Shebang Line
+
+
+
+Most `.py` files do not need to start with a `#!` line. Start the main file of a program with `#!/usr/bin/python` with an optional single digit `2` or `3` suffix per http://www.python.org/dev/peps/pep-0394/[PEP-394].
+
+This line is used by the kernel to find the Python interpreter, but is ignored by Python when importing modules. It is only necessary on a file that will be executed directly.
+
+=== Comments
+
+
+
+Be sure to use the right style for module, function, method and in-line comments.
+
+Doc Strings
+
+Python has a unique commenting style using doc strings. A doc string is a string that is the first statement in a package, module, class or function. These strings can be extracted automatically through the `__doc__` member of the object and are used by `pydoc`. (Try running `pydoc` on your module to see how it looks.) We always use the three double-quote `"""` format for doc strings (per http://www.python.org/dev/peps/pep-0257/[PEP 257]). A doc string should be organized as a summary line (one physical line) terminated by a period, question mark, or exclamation point, followed by a blank line, followed by the rest of the doc string starting at the same cursor position as the first quote of the first line. There are more formatting guidelines for doc strings below.
+
+Modules
+
+Every file should contain license boilerplate. Choose the appropriate boilerplate for the license used by the project (for example, Apache 2.0, BSD, LGPL, GPL)
+
+Functions and Methods
+
+As used in this section "function" applies to methods, function, and generators.
+
+A function must have a docstring, unless it meets all of the following criteria:
+
+* not externally visible
+* very short
+* obvious
+
+A docstring should give enough information to write a call to the function without reading the function's code. A docstring should describe the function's calling syntax and its semantics, not its implementation. For tricky code, comments alongside the code are more appropriate than using docstrings.
+
+Certain aspects of a function should be documented in special sections, listed below. Each section begins with a heading line, which ends with a colon. Sections should be indented two spaces, except for the heading.
+
+Args:::
+ List each parameter by name. A description should follow the name, and be separated by a colon and a space. If the description is too long to fit on a single 80-character line, use a hanging indent of 2 or 4 spaces (be consistent with the rest of the file).
+ +
+ The description should mention required type(s) and the meaning of the argument.
+ +
+ If a function accepts *foo (variable length argument lists) and/or **bar (arbitrary keyword arguments), they should be listed as *foo and **bar.
+Returns: (or Yields: for generators)::
+ Describe the type and semantics of the return value. If the function only returns None, this section is not required.
+Raises:::
+ List all exceptions that are relevant to the interface.
+
+--------------------------------------------------------------------------
+def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
+ """Fetches rows from a Bigtable.
+
+ Retrieves rows pertaining to the given keys from the Table instance
+ represented by big_table. Silly things may happen if
+ other_silly_variable is not None.
+
+ Args:
+ big_table: An open Bigtable Table instance.
+ keys: A sequence of strings representing the key of each table row
+ to fetch.
+ other_silly_variable: Another optional variable, that has a much
+ longer name than the other args, and which does nothing.
+
+ Returns:
+ A dict mapping keys to the corresponding table row data
+ fetched. Each row is represented as a tuple of strings. For
+ example:
+
+ {'Serak': ('Rigel VII', 'Preparer'),
+ 'Zim': ('Irk', 'Invader'),
+ 'Lrrr': ('Omicron Persei 8', 'Emperor')}
+
+ If a key from the keys argument is missing from the dictionary,
+ then that row was not found in the table.
+
+ Raises:
+ IOError: An error occurred accessing the bigtable.Table object.
+ """
+ pass
+--------------------------------------------------------------------------
+
+Classes
+
+Classes should have a doc string below the class definition describing the class. If your class has public attributes, they should be documented here in an Attributes section and follow the same formatting as a function's Args section.
+
+----------------------------------------------------------------
+class SampleClass(object):
+ """Summary of class here.
+
+ Longer class information....
+ Longer class information....
+
+ Attributes:
+ likes_spam: A boolean indicating if we like SPAM or not.
+ eggs: An integer count of the eggs we have laid.
+ """
+
+ def __init__(self, likes_spam=False):
+ """Inits SampleClass with blah."""
+ self.likes_spam = likes_spam
+ self.eggs = 0
+
+ def public_method(self):
+ """Performs operation blah."""
+----------------------------------------------------------------
+
+Block and Inline Comments
+
+The final place to have comments is in tricky parts of the code. If you're going to have to explain it at the next http://en.wikipedia.org/wiki/Code_review[code review], you should comment it now. Complicated operations get a few lines of comments before the operations commence. Non-obvious ones get comments at the end of the line.
+
+---------------------------------------------------------------
+# We use a weighted dictionary search to find out where i is in
+# the array. We extrapolate position based on the largest num
+# in the array and the array size and then do binary search to
+# get the exact number.
+
+if i & (i-1) == 0: # true iff i is a power of 2
+---------------------------------------------------------------
+
+To improve legibility, these comments should be at least 2 spaces away from the code.
+
+On the other hand, never describe the code. Assume the person reading the code knows Python (though not what you're trying to do) better than you do.
+
+-------------------------------------------------------------------------
+# BAD COMMENT: Now go through the b array and make sure whenever i occurs
+# the next element is i+1
+-------------------------------------------------------------------------
+
+=== Classes
+
+
+
+If a class inherits from no other base classes, explicitly inherit from `object`. This also applies to nested classes.
+
+--------------------------------------------------------------
+Yes: class SampleClass(object):
+ pass
+
+
+ class OuterClass(object):
+
+ class InnerClass(object):
+ pass
+
+
+ class ChildClass(ParentClass):
+ """Explicitly inherits from another class already."""
+--------------------------------------------------------------
+
+-------------------------
+No: class SampleClass:
+ pass
+
+
+ class OuterClass:
+
+ class InnerClass:
+ pass
+-------------------------
+
+Inheriting from `object` is needed to make properties work properly, and it will protect your code from one particular potential incompatibility with Python 3000. It also defines special methods that implement the default semantics of objects including `__new__`, `__init__`, `__delattr__`, `__getattribute__`, `__setattr__`, `__hash__`, `__repr__`, and `__str__`.
+
+=== Strings
+
+
+
+Use the `format` method or the `%` operator for formatting strings, even when the parameters are all strings. Use your best judgement to decide between `+` and `%` (or `format`) though.
+
+------------------------------------------------
+Yes: x = a + b
+ x = '%s, %s!' % (imperative, expletive)
+ x = '{}, {}!'.format(imperative, expletive)
+ x = 'name: %s; score: %d' % (name, n)
+ x = 'name: {}; score: {}'.format(name, n)
+------------------------------------------------
+
+-------------------------------------------------
+No: x = '%s%s' % (a, b) # use + in this case
+ x = '{}{}'.format(a, b) # use + in this case
+ x = imperative + ', ' + expletive + '!'
+ x = 'name: ' + name + '; score: ' + str(n)
+-------------------------------------------------
+
+Avoid using the `+` and `+=` operators to accumulate a string within a loop. Since strings are immutable, this creates unnecessary temporary objects and results in quadratic rather than linear running time. Instead, add each substring to a list and `''.join` the list after the loop terminates (or, write each substring to a `io.BytesIO` buffer).
+
+---------------------------------------------------------------------------
+Yes: items = ['']
+ for last_name, first_name in employee_list:
+ items.append('%s, %s ' % (last_name, first_name))
+ items.append('
')
+ employee_table = ''.join(items)
+---------------------------------------------------------------------------
+
+------------------------------------------------------------------------------
+No: employee_table = ''
+ for last_name, first_name in employee_list:
+ employee_table += '%s, %s ' % (last_name, first_name)
+ employee_table += '
'
+------------------------------------------------------------------------------
+
+Be consistent with your choice of string quote character within a file. Pick `'` or `"` and stick with it. It is okay to use the other quote character on a string to avoid the need to `\` escape within the string. GPyLint enforces this.
+
+------------------------------------------------------
+Yes:
+ Python('Why are you hiding your eyes?')
+ Gollum("I'm scared of lint errors.")
+ Narrator('"Good!" thought a happy Python reviewer.')
+------------------------------------------------------
+
+------------------------------------------------------
+No:
+ Python("Why are you hiding your eyes?")
+ Gollum('The lint. It burns. It burns us.')
+ Gollum("Always the great lint. Watching. Watching.")
+------------------------------------------------------
+
+Prefer `"""` for multi-line strings rather than `'''`. Projects may choose to use `'''` for all non-docstring multi-line strings if and only if they also use `'` for regular strings. Doc strings must use `"""` regardless. Note that it is often cleaner to use implicit line joining since multi-line strings do not flow with the indentation of the rest of the program:
+
+--------------------------------
+Yes:
+ print ("This is much nicer.\n"
+ "Do it this way.\n")
+--------------------------------
+
+---------------------------------
+ No:
+ print """This is pretty ugly.
+Don't do this.
+"""
+---------------------------------
+
+=== Files and Sockets
+
+
+
+Explicitly close files and sockets when done with them.
+
+Leaving files, sockets or other file-like objects open unnecessarily has many downsides, including:
+
+* They may consume limited system resources, such as file descriptors. Code that deals with many such objects may exhaust those resources unnecessarily if they're not returned to the system promptly after use.
+* Holding files open may prevent other actions being performed on them, such as moves or deletion.
+* Files and sockets that are shared throughout a program may inadvertantly be read from or written to after logically being closed. If they are actually closed, attempts to read or write from them will throw exceptions, making the problem known sooner.
+
+Furthermore, while files and sockets are automatically closed when the file object is destructed, tying the life-time of the file object to the state of the file is poor practice, for several reasons:
+
+* There are no guarantees as to when the runtime will actually run the file's destructor. Different Python implementations use different memory management techniques, such as delayed Garbage Collection, which may increase the object's lifetime arbitrarily and indefinitely.
+* Unexpected references to the file may keep it around longer than intended (e.g. in tracebacks of exceptions, inside globals, etc).
+
+The preferred way to manage files is using the http://docs.python.org/reference/compound_stmts.html#the-with-statement["with" statement]:
+
+-------------------------------------
+with open("hello.txt") as hello_file:
+ for line in hello_file:
+ print line
+-------------------------------------
+
+For file-like objects that do not support the "with" statement, use contextlib.closing():
+
+--------------------------------------------------------------------------------
+import contextlib
+
+with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
+ for line in front_page:
+ print line
+--------------------------------------------------------------------------------
+
+Legacy AppEngine code using Python 2.5 may enable the "with" statement using "from __future__ import with_statement".
+
+=== TODO Comments
+
+
+
+Use `TODO` comments for code that is temporary, a short-term solution, or good-enough but not perfect.
+
+`TODO`s should include the string `TODO` in all caps, followed by the name, e-mail address, or other identifier of the person who can best provide context about the problem referenced by the `TODO`, in parentheses. A colon is optional. A comment explaining what there is to do is required. The main purpose is to have a consistent `TODO` format that can be searched to find the person who can provide more details upon request. A `TODO` is not a commitment that the person referenced will fix the problem. Thus when you create a `TODO`, it is almost always your name that is given.
+
+-----------------------------------------------------------
+# TODO(kl@gmail.com): Use a "*" here for string repetition.
+# TODO(Zeke) Change this to use relations.
+-----------------------------------------------------------
+
+If your `TODO` is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2009") or a very specific event ("Remove this code when all clients can handle XML responses.").
+
+=== Imports formatting
+
+
+
+Imports should be on separate lines.
+
+E.g.:
+
+---------------
+Yes: import os
+ import sys
+---------------
+
+-------------------
+No: import os, sys
+-------------------
+
+Imports are always put at the top of the file, just after any module comments and doc strings and before module globals and constants. Imports should be grouped with the order being most generic to least generic:
+
+* standard library imports
+* third-party imports
+* application-specific imports
+
+Within each grouping, imports should be sorted lexicographically, ignoring case, according to each module's full package path.
+
+------------------------
+import foo
+from foo import bar
+from foo.bar import baz
+from foo.bar import Quux
+from Foob import ar
+------------------------
+
+=== Statements
+
+
+
+Generally only one statement per line.
+
+However, you may put the result of a test on the same line as the test only if the entire statement fits on one line. In particular, you can never do so with `try`/`except` since the `try` and `except` can't both fit on the same line, and you can only do so with an `if` if there is no `else`.
+
+------------------
+Yes:
+
+ if foo: bar(foo)
+------------------
+
+-----------------------------
+No:
+
+ if foo: bar(foo)
+ else: baz(foo)
+
+ try: bar(foo)
+ except ValueError: baz(foo)
+
+ try:
+ bar(foo)
+ except ValueError: baz(foo)
+-----------------------------
+
+=== Access Control
+
+
+
+If an accessor function would be trivial you should use public variables instead of accessor functions to avoid the extra cost of function calls in Python. When more functionality is added you can use `property` to keep the syntax consistent.
+
+On the other hand, if access is more complex, or the cost of accessing the variable is significant, you should use function calls (following the link:#naming[Naming] guidelines) such as `get_foo()` and `set_foo()`. If the past behavior allowed access through a property, do not bind the new accessor functions to the property. Any code still attempting to access the variable by the old method should break visibly so they are made aware of the change in complexity.
+
+=== Naming
+
+
+
+`module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_CONSTANT_NAME, global_var_name, instance_var_name, function_parameter_name, local_var_name.`
+
+Names to Avoid
+
+* single character names except for counters or iterators
+* dashes (`-`) in any package/module name
+* `__double_leading_and_trailing_underscore__` names (reserved by Python)
+
+Naming Convention
+
+* "Internal" means internal to a module or protected or private within a class.
+* Prepending a single underscore (`_`) has some support for protecting module variables and functions (not included with `import * from`). Prepending a double underscore (`__`) to an instance variable or method effectively serves to make the variable or method private to its class (using name mangling).
+* Place related classes and top-level functions together in a module. Unlike Java, there is no need to limit yourself to one class per module.
+* Use CapWords for class names, but lower_with_under.py for module names. Although there are many existing modules named CapWords.py, this is now discouraged because it's confusing when the module happens to be named after a class. ("wait -- did I write `import StringIO` or `from StringIO import StringIO`?")
+
+Guidelines derived from Guido's Recommendations
+
+[width="100%",cols="34%,33%,33%",options="header",]
+|=======================================================================================================
+|Type |Public |Internal
+|Packages |`lower_with_under` |
+|Modules |`lower_with_under` |`_lower_with_under`
+|Classes |`CapWords` |`_CapWords`
+|Exceptions |`CapWords` |
+|Functions |`lower_with_under()` |`_lower_with_under()`
+|Global/Class Constants |`CAPS_WITH_UNDER` |`_CAPS_WITH_UNDER`
+|Global/Class Variables |`lower_with_under` |`_lower_with_under`
+|Instance Variables |`lower_with_under` |`_lower_with_under (protected) or __lower_with_under (private)`
+|Method Names |`lower_with_under()` |`_lower_with_under() (protected) or __lower_with_under() (private)`
+|Function/Method Parameters |`lower_with_under` |
+|Local Variables |`lower_with_under` |
+|=======================================================================================================
+
+=== Main
+
+
+
+Even a file meant to be used as a script should be importable and a mere import should not have the side effect of executing the script's main functionality. The main functionality should be in a main() function.
+
+In Python, `pydoc` as well as unit tests require modules to be importable. Your code should always check `if __name__ == '__main__'` before executing your main program so that the main program is not executed when the module is imported.
+
+--------------------------
+def main():
+ ...
+
+if __name__ == '__main__':
+ main()
+--------------------------
+
+All code at the top level will be executed when the module is imported. Be careful not to call functions, create objects, or perform other operations that should not be executed when the file is being `pydoc`ed.
+
+== Parting Words
+
+__BE CONSISTENT__.
+
+If you're editing code, take a few minutes to look at the code around you and determine its style. If they use spaces around all their arithmetic operators, you should too. If their comments have little boxes of hash marks around them, make your comments have little boxes of hash marks around them too.
+
+The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you're saying rather than on how you're saying it. We present global style rules here so people know the vocabulary, but local style is also important. If code you add to a file looks drastically different from the existing code around it, it throws readers out of their rhythm when they go to read it. Avoid this.
+
+Revision 2.59
+
+Amit Patel +
+ Antoine Picard +
+ Eugene Jhong +
+ Gregory P. Smith +
+ Jeremy Hylton +
+ Matt Smart +
+ Mike Shields +
+ Shane Liebling +
diff --git a/pyguide.html b/pyguide.html
deleted file mode 100644
index 632c9c6..0000000
--- a/pyguide.html
+++ /dev/null
@@ -1,2311 +0,0 @@
-
-
-Google Python Style Guide
-
-
-
-
-
-
-Google Python Style Guide
-
-
- Revision 2.59
-
-
-
- Amit Patel
- Antoine Picard
- Eugene Jhong
- Jeremy Hylton
- Matt Smart
- Mike Shields
-
-
-
- Each style point has a summary for which additional information is available
- by toggling the accompanying arrow button that looks this way:
-
- .
- You may toggle all summaries with the big arrow button:
-
-
-
- Toggle all summaries
-
-
-Table of Contents
-
-
-Important Note
-
-Displaying Hidden Details in this Guide
-
-
- This style guide contains many details that are initially
- hidden from view. They are marked by the triangle icon, which you
- see here on your left. Click it now.
- You should see "Hooray" appear below.
-
-
-
-
-
-Background
-
- Python is the main scripting language used at Google. This
- style guide is a list of dos and don'ts for Python
- programs.
-
-
-
- To help you format code correctly, we've created a settings
- file for Vim. For Emacs, the default settings should be fine.
-
-
-
-
-
-
-Python Language Rules
-
-
-
-
-
-
-Nested/Local/Inner Classes and Functions
-
-
- Nested/local/inner classes and functions are fine.
-
-
-
-
-
-Default Iterators and Operators
-
-
- Use default iterators and operators for types that support them,
- like lists, dictionaries, and files.
-
-
-
-
-
-
-
-
-Properties
-
-
- Use properties for accessing or setting data where you would
- normally have used simple, lightweight accessor or setter methods.
-
-
-
-
-
-Deprecated Language Features
-
-
- Use string methods instead of the string
module
- where possible. Use function call syntax instead
- of apply
. Use list comprehensions
- and for
loops instead of filter
and
- map
when the function argument would have been an
- inlined lambda anyway. Use for
loops instead of
- reduce
.
-
-
-
-
-
-Function and Method Decorators
-
-
- Use decorators judiciously when there is a clear advantage.
-
-
-
-
-
-
-
-Python Style Rules
-
-Semicolons
-
-
- Do not terminate your lines with semi-colons and do not use
- semi-colons to put two commands on the same line.
-
-
-
-
-
-
-
-Blank Lines
-
-
- Two blank lines between top-level definitions, one blank line
- between method definitions.
-
-
-
-
-Whitespace
-
-
- Follow standard typographic rules for the use of spaces around
- punctuation.
-
-
-
-
-
-
-Shebang Line
-
-
- Most .py
files do not need to start with a
- #!
line. Start the main file of a
- program with
- #!/usr/bin/python
with an optional single digit
- 2
or 3
suffix per
- PEP-394.
-
-
-
-
-
-Comments
-
-
- Be sure to use the right style for module, function, method and in-line
- comments.
-
-
-
-
-Classes
-
-
- If a class inherits from no other base classes, explicitly inherit
- from object
. This also applies to nested classes.
-
-
-
-
-Strings
-
-
- Use the format
method or the %
operator for
- formatting strings, even when the parameters are all strings. Use your
- best judgement to decide between +
and %
- (or format
) though.
-
-
-
-
-
-TODO Comments
-
-
- Use TODO
comments for code that is temporary, a
- short-term solution, or good-enough but not perfect.
-
-
-
-
-
-
-Access Control
-
-
- If an accessor function would be trivial you should use public variables
- instead of accessor functions to avoid the extra cost of function
- calls in Python. When more functionality is added you can use
- property
to keep the syntax consistent.
-
-
-
-
-Naming
-
-
- module_name, package_name, ClassName,
- method_name, ExceptionName,
- function_name, GLOBAL_CONSTANT_NAME,
- global_var_name, instance_var_name, function_parameter_name,
- local_var_name.
-
-
-
-
-Main
-
-
- Even a file meant to be used as a script should be importable and a
- mere import should not have the side effect of executing the script's
- main functionality. The main functionality should be in a main()
- function.
-
-
-
-
-
-Parting Words
-
- BE CONSISTENT.
-
-
-
- If you're editing code, take a few minutes to look at the code
- around you and determine its style. If they use spaces around
- all their arithmetic operators, you should too. If their
- comments have little boxes of hash marks around them, make your
- comments have little boxes of hash marks around them too.
-
-
-
- The point of having style guidelines is to have a common vocabulary
- of coding so people can concentrate on what you're saying rather
- than on how you're saying it. We present global style rules here so
- people know the vocabulary, but local style is also important. If
- code you add to a file looks drastically different from the existing
- code around it, it throws readers out of their rhythm when they go to
- read it. Avoid this.
-
-
-
-
-
-Revision 2.59
-
-
-
-
- Amit Patel
- Antoine Picard
- Eugene Jhong
- Gregory P. Smith
- Jeremy Hylton
- Matt Smart
- Mike Shields
- Shane Liebling
-
-
-
diff --git a/shell.asciidoc b/shell.asciidoc
new file mode 100644
index 0000000..74aad7c
--- /dev/null
+++ b/shell.asciidoc
@@ -0,0 +1,889 @@
+= Shell Style Guide
+
+Revision 1.26
+
+Paul Armstrong +
+ Too many more to mention +
+
+Each style point has a summary for which additional information is available by toggling the accompanying arrow button that looks this way: ▶. You may toggle all summaries with the big arrow button:
+
+▶ Toggle all summaries
+
+Table of Contents
+
+[width="100%",cols="50%,50%",]
+|====================================================================================================================================================================================================================================================================================================================================================================
+a|
+link:#shell-files-and-interpreter_invocation[Shell Files and Interpreter Invocation]
+
+ a|
+link:#file-extensions[File Extensions] link:#suid-sgid[SUID/SGID]
+
+a|
+link:#environment[Environment]
+
+ a|
+link:#stdout-vs-stderr[STDOUT vs STDERR]
+
+a|
+link:#comments[Comments]
+
+ a|
+link:#file-header[File Header] link:#function-comments[Function Comments] link:#implementation-comments[Implementation Comments] link:#todo-comments[TODO Comments]
+
+a|
+link:#formatting[Formatting]
+
+ a|
+link:#indentation[Indentation] link:#line-length-and-long_strings[Line Length and Long Strings] link:#pipelines[Pipelines] link:#loops[Loops] link:#case-statement[Case statement] link:#variable-expansion[Variable expansion] link:#quoting[Quoting]
+
+a|
+link:#features-and-bugs[Features and Bugs]
+
+ a|
+link:#command-substitution[Command Substitution] link:#Test,_%5B_and_%5B%5B[Test, [ and [[] link:#testing-strings[Testing Strings] link:#wildcard-expansion-of-filenames[Wildcard Expansion of Filenames] link:#eval[Eval] link:#pipes-to-while[Pipes to While]
+
+a|
+link:#naming-conventions[Naming Conventions]
+
+ a|
+link:#function-names[Function Names] link:#variable-names[Variable Names] link:#constants-and-environment-variable_names[Constants and Environment Variable Names] link:#source-filenames[Source Filenames] link:#Read-only_Variables[Read-only Variables] link:#use-local-variables[Use Local Variables] link:#function-location[Function Location] link:#main[main]
+
+a|
+link:#calling-commands[Calling Commands]
+
+ a|
+link:#checking-return-values[Checking Return Values] link:#Builtin_Commands_vs._External_Commands[Builtin Commands vs. External Commands]
+
+a|
+link:#conclusion[Conclusion]
+
+ a|
+|====================================================================================================================================================================================================================================================================================================================================================================
+
+[[Background]]
+== Background
+
+=== Which Shell to Use
+
+link:?showone=Which_Shell_to_Use#Which_Shell_to_Use[link]▶
+
+`Bash` is the only shell scripting language permitted for executables.
+
+Executables must start with `#!/bin/bash` and a minimum number of flags. Use `set` to set shell options so that calling your script as `bash ` does not break its functionality.
+
+Restricting all executable shell scripts to bash gives us a consistent shell language that's installed on all our machines.
+
+The only exception to this is where you're forced to by whatever you're coding for. One example of this is Solaris SVR4 packages which require plain Bourne shell for any scripts.
+
+=== When to use Shell
+
+link:?showone=When_to_use_Shell#When_to_use_Shell[link]▶
+
+Shell should only be used for small utilities or simple wrapper scripts.
+
+While shell scripting isn't a development language, it is used for writing various utility scripts throughout Google. This style guide is more a recognition of its use rather than a suggestion that it be used for widespread deployment.
+
+Some guidelines:
+
+
+* If you're mostly calling other utilities and are doing relatively little data manipulation, shell is an acceptable choice for the task.
+
+* If performance matters, use something other than shell.
+
+* If you find you need to use arrays for anything more than assignment of `${PIPESTATUS}`, you should use Python.
+
+* If you are writing a script that is more than 100 lines long, you should probably be writing it in Python instead. Bear in mind that scripts grow. Rewrite your script in another language early to avoid a time-consuming rewrite at a later date.
+
+[[Shell_Files_and_Interpreter_Invocation]]
+== Shell Files and Interpreter Invocation
+
+=== File Extensions
+
+link:?showone=File_Extensions#File_Extensions[link]▶
+
+Executables should have no extension (strongly preferred) or a `.sh` extension. Libraries must have a `.sh` extension and should not be executable.
+
+It is not necessary to know what language a program is written in when executing it and shell doesn't require an extension so we prefer not to use one for executables.
+
+However, for libraries it's important to know what language it is and sometimes there's a need to have similar libraries in different languages. This allows library files with identical purposes but different languages to be identically named except for the language-specific suffix.
+
+=== SUID/SGID
+
+link:?showone=SUID/SGID#SUID/SGID[link]▶
+
+SUID and SGID are _forbidden_ on shell scripts.
+
+There are too many security issues with shell that make it nearly impossible to secure sufficiently to allow SUID/SGID. While bash does make it difficult to run SUID, it's still possible on some platforms which is why we're being explicit about banning it.
+
+Use `sudo` to provide elevated access if you need it.
+
+[[Environment]]
+== Environment
+
+=== STDOUT vs STDERR
+
+link:?showone=STDOUT_vs_STDERR#STDOUT_vs_STDERR[link]▶
+
+All error messages should go to `STDERR`.
+
+This makes it easier to separate normal status from actual issues.
+
+A function to print out error messages along with other status information is recommended.
+
+-------------------------------------------------
+err() {
+ echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" >&2
+}
+
+if ! do_something; then
+ err "Unable to do_something"
+ exit "${E_DID_NOTHING}"
+fi
+-------------------------------------------------
+
+[[Comments]]
+== Comments
+
+=== File Header
+
+link:?showone=File_Header#File_Header[link]▶
+
+Start each file with a description of its contents.
+
+Every file must have a top-level comment including a brief overview of its contents. A copyright notice and author information are optional.
+
+Example:
+
+------------------------------------------
+#!/bin/bash
+#
+# Perform hot backups of Oracle databases.
+------------------------------------------
+
+=== Function Comments
+
+link:?showone=Function_Comments#Function_Comments[link]▶
+
+Any function that is not both obvious and short must be commented. Any function in a library must be commented regardless of length or complexity.
+
+It should be possible for someone else to learn how to use your program or to use a function in your library by reading the comments (and self-help, if provided) without reading the code.
+
+All function comments should contain:
+
+
+* Description of the function
+
+* Global variables used and modified
+
+* Arguments taken
+
+* Returned values other than the default exit status of the last command run
+
+Example:
+
+---------------------------------------------------------------
+#!/bin/bash
+#
+# Perform hot backups of Oracle databases.
+
+export PATH='/usr/xpg4/bin:/usr/bin:/opt/csw/bin:/opt/goog/bin'
+
+#######################################
+# Cleanup files from the backup dir
+# Globals:
+# BACKUP_DIR
+# ORACLE_SID
+# Arguments:
+# None
+# Returns:
+# None
+#######################################
+cleanup() {
+ ...
+}
+---------------------------------------------------------------
+
+=== Implementation Comments
+
+link:?showone=Implementation_Comments#Implementation_Comments[link]▶
+
+Comment tricky, non-obvious, interesting or important parts of your code.
+
+This follows general Google coding comment practice. Don't comment everything. If there's a complex algorithm or you're doing something out of the ordinary, put a short comment in.
+
+=== TODO Comments
+
+link:?showone=TODO_Comments#TODO_Comments[link]▶
+
+Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect.
+
+This matches the convention in the link:cppguide.xml?showone=TODO_Comments#TODO_Comments[C++ Guide].
+
+TODOs should include the string TODO in all caps, followed by your username in parentheses. A colon is optional. It's preferable to put a bug/ticket number next to the TODO item as well.
+
+Examples:
+
+-----------------------------------------------------------
+# TODO(mrmonkey): Handle the unlikely edge cases (bug ####)
+-----------------------------------------------------------
+
+[[Formatting]]
+== Formatting
+
+While you should follow the style that's already there for files that you're modifying, the following are required for any new code.
+
+=== Indentation
+
+link:?showone=Indentation#Indentation[link]▶
+
+Indent 2 spaces. No tabs.
+
+Use blank lines between blocks to improve readability. Indentation is two spaces. Whatever you do, don't use tabs. For existing files, stay faithful to the existing indentation.
+
+=== Line Length and Long Strings
+
+link:?showone=Line_Length_and_Long_Strings#Line_Length_and_Long_Strings[link]▶
+
+Maximum line length is 80 characters.
+
+If you have to write strings that are longer than 80 characters, this should be done with a here document or an embedded newline if possible. Literal strings that have to be longer than 80 chars and can't sensibly be split are ok, but it's strongly preferred to find a way to make it shorter.
+
+----------------------------------
+# DO use 'here document's
+cat <&2
+ exit "${E_BAD_MOVE}"
+fi
+
+# Or
+mv "${file_list}" "${dest_dir}/"
+if [[ "$?" -ne 0 ]]; then
+ echo "Unable to move ${file_list} to ${dest_dir}" >&2
+ exit "${E_BAD_MOVE}"
+fi
+-------------------------------------------------------
+
+Bash also has the `PIPESTATUS` variable that allows checking of the return code from all parts of a pipe. If it's only necessary to check success or failure of the whole pipe, then the following is acceptable:
+
+-------------------------------------------------------------------
+tar -cf - ./* | ( cd "${dir}" && tar -xf - )
+if [[ "${PIPESTATUS[0]}" -ne 0 || "${PIPESTATUS[1]}" -ne 0 ]]; then
+ echo "Unable to tar files to ${dir}" >&2
+fi
+-------------------------------------------------------------------
+
+However, as `PIPESTATUS` will be overwritten as soon as you do any other command, if you need to act differently on errors based on where it happened in the pipe, you'll need to assign `PIPESTATUS` to another variable immediately after running the command (don't forget that `[` is a command and will wipe out `PIPESTATUS`).
+
+--------------------------------------------
+tar -cf - ./* | ( cd "${DIR}" && tar -xf - )
+return_codes=(${PIPESTATUS[*]})
+if [[ "${return_codes[0]}" -ne 0 ]]; then
+ do_something
+fi
+if [[ "${return_codes[1]}" -ne 0 ]]; then
+ do_something_else
+fi
+--------------------------------------------
+
+=== Builtin Commands vs. External Commands
+
+link:?showone=Builtin_Commands_vs._External_Commands#Builtin_Commands_vs._External_Commands[link]▶
+
+Given the choice between invoking a shell builtin and invoking a separate process, choose the builtin.
+
+We prefer the use of builtins such as the _Parameter Expansion_ functions in `bash(1)` as it's more robust and portable (especially when compared to things like sed).
+
+Example:
+
+---------------------------------------------------------
+# Prefer this:
+addition=$((${X} + ${Y}))
+substitution="${string/#foo/bar}"
+
+# Instead of this:
+addition="$(expr ${X} + ${Y})"
+substitution="$(echo "${string}" | sed -e 's/^foo/bar/')"
+---------------------------------------------------------
+
+[[Conclusion]]
+== Conclusion
+
+Use common sense and __BE CONSISTENT__.
+
+Please take a few minutes to read the Parting Words section at the bottom of the link:cppguide.xml[C++ Guide].
+
+Revision 1.26
diff --git a/shell.xml b/shell.xml
deleted file mode 100644
index 2e75857..0000000
--- a/shell.xml
+++ /dev/null
@@ -1,1152 +0,0 @@
-
-
-
-
-
-
-Revision 1.26
-
-
-
-
- Paul Armstrong
- Too many more to mention
-
-
-
-
-
-
-
-
-
-
- Bash
is the only shell scripting language permitted for
- executables.
-
-
-
- Executables must start with #!/bin/bash
and a minimum
- number of flags. Use set
to set shell options so that
- calling your script as bash <script_name>
- does not break its functionality.
-
-
- Restricting all executable shell scripts to bash
- gives us a consistent shell language that's installed on all our
- machines.
-
-
- The only exception to this is where you're forced to by whatever
- you're coding for. One example of this is Solaris SVR4 packages which
- require plain Bourne shell for any scripts.
-
-
-
-
-
-
- Shell should only be used for small utilities or simple wrapper
- scripts.
-
-
-
- While shell scripting isn't a development language, it is used for
- writing various utility scripts throughout Google. This
- style guide is more a recognition of its use rather than
- a suggestion that it be used for widespread deployment.
-
-
- Some guidelines:
-
- -
- If you're mostly calling other utilities and are doing relatively
- little data manipulation, shell is an acceptable choice for the
- task.
-
- -
- If performance matters, use something other than shell.
-
- -
- If you find you need to use arrays for anything more than
- assignment of
${PIPESTATUS}
, you should use Python.
-
- -
- If you are writing a script that is more than 100 lines long, you
- should probably be writing it in Python instead. Bear in mind
- that scripts grow. Rewrite your script in another language
- early to avoid a time-consuming rewrite at a later date.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Executables should have no extension (strongly preferred) or a
- .sh
extension.
- Libraries must have a .sh
extension and should not be
- executable.
-
-
-
- It is not necessary to know what language a program is written in when
- executing it and shell doesn't require an extension so we prefer not to
- use one for executables.
-
-
- However, for libraries it's important to know what language it is and
- sometimes there's a need to have similar libraries in different
- languages. This allows library files with identical purposes but
- different languages to be identically named except for the
- language-specific suffix.
-
-
-
-
-
-
- SUID and SGID are forbidden on shell scripts.
-
-
-
- There are too many security issues with shell that make it nearly
- impossible to secure sufficiently to allow SUID/SGID. While bash does
- make it difficult to run SUID, it's still possible on some platforms
- which is why we're being explicit about banning it.
-
-
- Use sudo
to provide elevated access if you need it.
-
-
-
-
-
-
-
-
-
-
- All error messages should go to STDERR
.
-
-
-
- This makes it easier
- to separate normal status from actual issues.
-
-
- A function to print out error messages along with other status
- information is recommended.
-
- err() {
- echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" >&2
- }
-
- if ! do_something; then
- err "Unable to do_something"
- exit "${E_DID_NOTHING}"
- fi
-
-
-
-
-
-
-
-
-
-
-
- Start each file with a description of its contents.
-
-
-
- Every file must have a top-level comment including a brief overview of
- its contents.
- A
- copyright notice
- and author information are optional.
-
-
- Example:
-
- #!/bin/bash
- #
- # Perform hot backups of Oracle databases.
-
-
-
-
-
-
-
-
-
- Any function that is not both obvious and short must be commented. Any
- function in a library must be commented regardless of length or
- complexity.
-
-
-
- It should be possible for someone else to learn how to use your
- program or to use a function in your library by reading the comments
- (and self-help, if provided) without reading the code.
-
-
- All function comments should contain:
-
- -
- Description of the function
-
- -
- Global variables used and modified
-
- -
- Arguments taken
-
- -
- Returned values other than the default exit status of the last
- command run
-
-
-
-
- Example:
-
- #!/bin/bash
- #
- # Perform hot backups of Oracle databases.
-
- export PATH='/usr/xpg4/bin:/usr/bin:/opt/csw/bin:/opt/goog/bin'
-
- #######################################
- # Cleanup files from the backup dir
- # Globals:
- # BACKUP_DIR
- # ORACLE_SID
- # Arguments:
- # None
- # Returns:
- # None
- #######################################
- cleanup() {
- ...
- }
-
-
-
-
-
-
-
- Comment tricky, non-obvious, interesting or important parts of your code.
-
-
-
- This follows general Google coding comment practice. Don't comment
- everything. If there's a complex algorithm or you're doing something
- out of the ordinary, put a short comment in.
-
-
-
-
-
-
- Use TODO comments for code that is temporary, a short-term solution, or
- good-enough but not perfect.
-
-
-
- This matches the convention in the C++
- Guide.
-
-
- TODOs should include the string TODO in all caps, followed by your
- username in parentheses. A colon is optional. It's preferable to put a
- bug/ticket number next to the TODO item as well.
-
-
- Examples:
-
-
- # TODO(mrmonkey): Handle the unlikely edge cases (bug ####)
-
-
-
-
-
-
-
-
-
- While you should follow the style that's already there for files that
- you're modifying, the following are required for any new code.
-
-
-
-
- Indent 2 spaces. No tabs.
-
-
-
- Use blank lines between blocks to improve readability. Indentation is
- two spaces. Whatever you do, don't use tabs. For existing files, stay
- faithful to the existing indentation.
-
-
-
-
-
-
- Maximum line length is 80 characters.
-
-
-
- If you have to write strings that are longer than 80 characters, this
- should be done with a here document or an embedded newline if possible.
- Literal strings that have to be longer than 80 chars and can't sensibly
- be split are ok, but it's strongly preferred to find a way to make it
- shorter.
-
-
-
- # DO use 'here document's
- cat <<END;
- I am an exceptionally long
- string.
- END
-
- # Embedded newlines are ok too
- long_string="I am an exceptionally
- long string."
-
-
-
-
-
-
-
- Pipelines should be split one per line if they don't all fit on one line.
-
-
-
- If a pipeline all fits on one line, it should be on one line.
-
-
- If not, it should be split at one pipe segment per line with the pipe
- on the newline and a 2 space indent for the next section of the pipe.
- This applies to a chain of commands combined using '|' as well as to
- logical compounds using '||' and '&&'.
-
- # All fits on one line
- command1 | command2
-
- # Long commands
- command1 \
- | command2 \
- | command3 \
- | command4
-
-
-
-
-
-
-
- Put ; do
and ; then
on the same line as the
- while
, for
or if
.
-
-
-
- Loops in shell are a bit different, but we follow the same principles
- as with braces when declaring functions. That is: ; then
- and ; do
should be on the same line as the if/for/while.
- else
should be on its own line and closing statements
- should be on their own line vertically aligned with the opening
- statement.
-
-
- Example:
-
- for dir in ${dirs_to_cleanup}; do
- if [[ -d "${dir}/${ORACLE_SID}" ]]; then
- log_date "Cleaning up old files in ${dir}/${ORACLE_SID}"
- rm "${dir}/${ORACLE_SID}/"*
- if [[ "$?" -ne 0 ]]; then
- error_message
- fi
- else
- mkdir -p "${dir}/${ORACLE_SID}"
- if [[ "$?" -ne 0 ]]; then
- error_message
- fi
- fi
- done
-
-
-
-
-
-
-
-
- -
- Indent alternatives by 2 spaces.
-
- -
- A one-line alternative needs a space after the close parenthesis of
- the pattern and before the
;;
.
-
- -
- Long or multi-command alternatives should be split over multiple
- lines with the pattern, actions, and
;;
on separate
- lines.
-
-
-
-
-
- The matching expressions are indented one level from the 'case' and
- 'esac'. Multiline actions are indented another level. In general,
- there is no need to quote match expressions. Pattern expressions
- should not be preceded by an open parenthesis. Avoid the
- ;&
and ;;&
notations.
-
-
- case "${expression}" in
- a)
- variable="..."
- some_command "${variable}" "${other_expr}" ...
- ;;
- absolute)
- actions="relative"
- another_command "${actions}" "${other_expr}" ...
- ;;
- *)
- error "Unexpected expression '${expression}'"
- ;;
- esac
-
-
- Simple commands may be put on the same line as the pattern and
- ;;
as long as the expression remains readable. This is
- often appropriate for single-letter option processing. When the
- actions don't fit on a single line, put the pattern on a line on its
- own, then the actions, then ;;
also on a line of its own.
- When on the same line as the actions, use a space after the close
- parenthesis of the pattern and another before the ;;
.
-
-
- verbose='false'
- aflag=''
- bflag=''
- files=''
- while getopts 'abf:v' flag; do
- case "${flag}" in
- a) aflag='true' ;;
- b) bflag='true' ;;
- f) files="${OPTARG}" ;;
- v) verbose='true' ;;
- *) error "Unexpected option ${flag}" ;;
- esac
- done
-
-
-
-
-
-
- In order of precedence: Stay consistent with what you find;
- quote your variables;
- prefer "${var}" over "$var", but see details.
-
-
-
- These are meant to be guidelines, as the topic seems too controversial for
- a mandatory regulation.
-
- They are listed in order of precedence.
-
-
- -
- Stay consistent with what you find for existing code.
-
- -
- Quote variables, see Quoting section below.
-
- -
-
- Don't brace-quote single character shell
- specials / positional parameters, unless strictly necessary
- or avoiding deep confusion.
-
- Prefer brace-quoting all other variables.
-
- # Section of recommended cases.
-
- # Preferred style for 'special' variables:
- echo "Positional: $1" "$5" "$3"
- echo "Specials: !=$!, -=$-, _=$_. ?=$?, #=$# *=$* @=$@ \$=$$ ..."
-
- # Braces necessary:
- echo "many parameters: ${10}"
-
- # Braces avoiding confusion:
- # Output is "a0b0c0"
- set -- a b c
- echo "${1}0${2}0${3}0"
-
- # Preferred style for other variables:
- echo "PATH=${PATH}, PWD=${PWD}, mine=${some_var}"
- while read f; do
- echo "file=${f}"
- done < <(ls -l /tmp)
-
- # Section of discouraged cases
-
- # Unquoted vars, unbraced vars, brace-quoted single letter
- # shell specials.
- echo a=$avar "b=$bvar" "PID=${$}" "${1}"
-
- # Confusing use: this is expanded as "${1}0${2}0${3}0",
- # not "${10}${20}${30}
- set -- a b c
- echo "$10$20$30"
-
-
-
-
-
-
-
-
-
-
- -
- Always quote strings containing variables, command substitutions,
- spaces or shell meta characters, unless careful unquoted expansion
- is required.
-
- -
- Prefer quoting strings that are "words"
- (as opposed to command options or path names).
-
- -
- Never quote literal integers.
-
- -
- Be aware of the quoting rules for
- pattern matches in [[.
-
- -
- Use "$@" unless you have a specific reason to use $*.
-
-
-
-
-
-
- # 'Single' quotes indicate that no substitution is desired.
- # "Double" quotes indicate that substitution is required/tolerated.
-
- # Simple examples
- # "quote command substitutions"
- flag="$(some_command and its args "$@" 'quoted separately')"
-
- # "quote variables"
- echo "${flag}"
-
- # "never quote literal integers"
- value=32
- # "quote command substitutions", even when you expect integers
- number="$(generate_number)"
-
- # "prefer quoting words", not compulsory
- readonly USE_INTEGER='true'
-
- # "quote shell meta characters"
- echo 'Hello stranger, and well met. Earn lots of $$$'
- echo "Process $$: Done making \$\$\$."
-
- # "command options or path names"
- # ($1 is assumed to contain a value here)
- grep -li Hugo /dev/null "$1"
-
- # Less simple examples
- # "quote variables, unless proven false": ccs might be empty
- git send-email --to "${reviewers}" ${ccs:+"--cc" "${ccs}"}
-
- # Positional parameter precautions: $1 might be unset
- # Single quotes leave regex as-is.
- grep -cP '([Ss]pecial|\|?characters*)$' ${1:+"$1"}
-
- # For passing on arguments,
- # "$@" is right almost everytime, and
- # $* is wrong almost everytime:
- #
- # * $* and $@ will split on spaces, clobbering up arguments
- # that contain spaces and dropping empty strings;
- # * "$@" will retain arguments as-is, so no args
- # provided will result in no args being passed on;
- # This is in most cases what you want to use for passing
- # on arguments.
- # * "$*" expands to one argument, with all args joined
- # by (usually) spaces,
- # so no args provided will result in one empty string
- # being passed on.
- # (Consult 'man bash' for the nit-grits ;-)
-
- set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$*"; echo "$#, $@")
- set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$@"; echo "$#, $@")
-
-
-
-
-
-
-
-
-
-
-
- Use $(command)
instead of backticks.
-
-
-
- Nested backticks require escaping the inner ones with \
.
- The $(command)
format doesn't change when nested and is
- easier to read.
-
-
- Example:
-
- # This is preferred:
- var="$(command "$(command1)")"
-
- # This is not:
- var="`command \`command1\``"
-
-
-
-
-
-
-
- [[ ... ]]
is preferred over [
,
- test
and /usr/bin/[
.
-
-
-
- [[ ... ]]
reduces errors as no pathname expansion or word
- splitting takes place between [[
and ]]
and
- [[ ... ]]
allows for regular expression matching where
- [ ... ]
does not.
-
- # This ensures the string on the left is made up of characters in the
- # alnum character class followed by the string name.
- # Note that the RHS should not be quoted here.
- # For the gory details, see
- # E14 at http://tiswww.case.edu/php/chet/bash/FAQ
- if [[ "filename" =~ ^[[:alnum:]]+name ]]; then
- echo "Match"
- fi
-
- # This matches the exact pattern "f*" (Does not match in this case)
- if [[ "filename" == "f*" ]]; then
- echo "Match"
- fi
-
- # This gives a "too many arguments" error as f* is expanded to the
- # contents of the current directory
- if [ "filename" == f* ]; then
- echo "Match"
- fi
-
-
-
-
-
-
-
- Use quotes rather than filler characters where possible.
-
-
-
- Bash is smart enough to deal with an empty string in a test. So, given
- that the code is much easier to read, use tests for empty/non-empty
- strings or empty strings rather than filler characters.
-
- # Do this:
- if [[ "${my_var}" = "some_string" ]]; then
- do_something
- fi
-
- # -z (string length is zero) and -n (string length is not zero) are
- # preferred over testing for an empty string
- if [[ -z "${my_var}" ]]; then
- do_something
- fi
-
- # This is OK (ensure quotes on the empty side), but not preferred:
- if [[ "${my_var}" = "" ]]; then
- do_something
- fi
-
- # Not this:
- if [[ "${my_var}X" = "some_stringX" ]]; then
- do_something
- fi
-
-
-
- To avoid confusion about what you're testing for, explicitly use
- -z
or -n
.
-
- # Use this
- if [[ -n "${my_var}" ]]; then
- do_something
- fi
-
- # Instead of this as errors can occur if ${my_var} expands to a test
- # flag
- if [[ "${my_var}" ]]; then
- do_something
- fi
-
-
-
-
-
-
-
- Use an explicit path when doing wildcard expansion of filenames.
-
-
-
- As filenames can begin with a -
, it's a lot safer to
- expand wildcards with ./*
instead of *
.
-
- # Here's the contents of the directory:
- # -f -r somedir somefile
-
- # This deletes almost everything in the directory by force
- psa@bilby$ rm -v *
- removed directory: `somedir'
- removed `somefile'
-
- # As opposed to:
- psa@bilby$ rm -v ./*
- removed `./-f'
- removed `./-r'
- rm: cannot remove `./somedir': Is a directory
- removed `./somefile'
-
-
-
-
-
-
-
- eval
should be avoided.
-
-
-
- Eval munges the input when used for assignment to variables and can set
- variables without making it possible to check what those variables
- were.
-
- # What does this set?
- # Did it succeed? In part or whole?
- eval $(set_my_variables)
-
- # What happens if one of the returned values has a space in it?
- variable="$(eval some_function)"
-
-
-
-
-
-
-
- Use process substitution or for loops in preference to piping to while.
- Variables modified in a while loop do not propagate to the parent
- because the loop's commands run in a subshell.
-
-
-
- The implicit subshell in a pipe to while can make it difficult to track
- down bugs.
-
- last_line='NULL'
- your_command | while read line; do
- last_line="${line}"
- done
-
- # This will output 'NULL'
- echo "${last_line}"
-
-
-
- Use a for loop if you are confident that the input will not contain
- spaces or special characters (usually, this means not user input).
-
- total=0
- # Only do this if there are no spaces in return values.
- for value in $(command); do
- total+="${value}"
- done
-
-
-
- Using process substitution allows redirecting output but puts the
- commands in an explicit subshell rather than the implicit subshell that
- bash creates for the while loop.
-
- total=0
- last_file=
- while read count filename; do
- total+="${count}"
- last_file="${filename}"
- done < <(your_command | uniq -c)
-
- # This will output the second field of the last line of output from
- # the command.
- echo "Total = ${total}"
- echo "Last one = ${last_file}"
-
-
-
- Use while loops where it is not necessary to pass complex results
- to the parent shell - this is typically where some more complex
- "parsing" is required. Beware that simple examples are probably
- more easily done with a tool such as awk. This may also be useful
- where you specifically don't want to change the parent scope variables.
-
- # Trivial implementation of awk expression:
- # awk '$3 == "nfs" { print $2 " maps to " $1 }' /proc/mounts
- cat /proc/mounts | while read src dest type opts rest; do
- if [[ ${type} == "nfs" ]]; then
- echo "NFS ${dest} maps to ${src}"
- fi
- done
-
-
-
-
-
-
-
-
-
-
-
- Lower-case, with underscores to separate words. Separate libraries
- with ::
. Parentheses are required after the function name.
- The keyword function
is optional, but must be used
- consistently throughout a project.
-
-
-
- If you're writing single functions, use lowercase and separate words
- with underscore. If you're writing a package, separate package names
- with ::
. Braces must be on the same line as the function
- name (as with other languages at Google) and no space between the
- function name and the parenthesis.
-
- # Single function
- my_func() {
- ...
- }
-
- # Part of a package
- mypackage::my_func() {
- ...
- }
-
-
-
- The function
keyword is extraneous when "()" is present
- after the function name, but enhances quick identification of
- functions.
-
-
-
-
-
-
- As for function names.
-
-
-
- Variables names for loops should be similarly named for any variable
- you're looping through.
-
- for zone in ${zones}; do
- something_with "${zone}"
- done
-
-
-
-
-
-
-
- All caps, separated with underscores, declared at the top of the file.
-
-
-
- Constants and anything exported to the environment should be
- capitalized.
-
- # Constant
- readonly PATH_TO_FILES='/some/path'
-
- # Both constant and environment
- declare -xr ORACLE_SID='PROD'
-
-
-
- Some things become constant at their first setting (for example, via
- getopts). Thus, it's OK to set a constant in getopts or based on a
- condition, but it should be made readonly immediately afterwards.
- Note that declare
doesn't operate on global variables
- within functions, so readonly
or export
is
- recommended instead.
-
-
- VERBOSE='false'
- while getopts 'v' flag; do
- case "${flag}" in
- v) VERBOSE='true' ;;
- esac
- done
- readonly VERBOSE
-
-
-
-
-
-
- Lowercase, with underscores to separate words if desired.
-
-
-
- This is for consistency with other code styles in Google:
- maketemplate
or make_template
but not
- make-template
.
-
-
-
-
-
-
- Use readonly
or declare -r
to ensure they're
- read only.
-
-
-
- As globals are widely used in shell, it's important to catch errors
- when working with them. When you declare a variable that is
- meant to be read-only, make this explicit.
-
- zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)"
- if [[ -z "${zip_version}" ]]; then
- error_message
- else
- readonly zip_version
- fi
-
-
-
-
-
-
-
- Declare function-specific variables with local
. Declaration
- and assignment should be on different lines.
-
-
-
- Ensure that local variables are only seen inside a function and its
- children by using local
when declaring them. This avoids
- polluting the global name space and inadvertently setting variables
- that may have significance outside the function.
-
-
- Declaration and assignment must be separate statements when
- the assignment value is provided by a command substitution; as
- the 'local' builtin does not propagate the exit code from the
- command substitution.
-
- my_func2() {
- local name="$1"
-
- # Separate lines for declaration and assignment:
- local my_var
- my_var="$(my_func)" || return
-
- # DO NOT do this: $? contains the exit code of 'local', not my_func
- local my_var="$(my_func)"
- [[ $? -eq 0 ]] || return
-
- ...
- }
-
-
-
-
-
-
-
- Put all functions together in the file just below constants. Don't hide
- executable code between functions.
-
-
-
- If you've got functions, put them all together near the top of the
- file. Only includes, set
statements and setting constants
- may be done before declaring functions.
-
-
- Don't hide executable code between functions. Doing so makes the code
- difficult to follow and results in nasty surprises when debugging.
-
-
-
-
-
-
- A function called main
is required for scripts long enough
- to contain at least one other function.
-
-
-
- In order to easily find the start of the program, put the main
- program in a function called main
as the bottom most
- function. This provides consistency with the rest of the code base as
- well as allowing you to define more variables as local
- (which can't be done if the main code is not a function). The last
- non-comment line in the file should be a call to main
:
-
- main "$@"
-
-
-
- Obviously, for short scripts where it's just a linear flow,
- main
is overkill and so is not required.
-
-
-
-
-
-
-
-
-
-
- Always check return values and give informative return values.
-
-
-
- For unpiped commands, use $?
or check directly via an
- if
statement to keep it simple.
-
-
- Example:
-
- if ! mv "${file_list}" "${dest_dir}/" ; then
- echo "Unable to move ${file_list} to ${dest_dir}" >&2
- exit "${E_BAD_MOVE}"
- fi
-
- # Or
- mv "${file_list}" "${dest_dir}/"
- if [[ "$?" -ne 0 ]]; then
- echo "Unable to move ${file_list} to ${dest_dir}" >&2
- exit "${E_BAD_MOVE}"
- fi
-
-
-
-
- Bash also has the PIPESTATUS
variable that allows checking
- of the return code from all parts of a pipe. If it's only necessary to
- check success or failure of the whole pipe, then the following is
- acceptable:
-
- tar -cf - ./* | ( cd "${dir}" && tar -xf - )
- if [[ "${PIPESTATUS[0]}" -ne 0 || "${PIPESTATUS[1]}" -ne 0 ]]; then
- echo "Unable to tar files to ${dir}" >&2
- fi
-
-
-
- However, as PIPESTATUS
will be overwritten as soon as you
- do any other command, if you need to act differently on errors based on
- where it happened in the pipe, you'll need to assign
- PIPESTATUS
to another variable immediately after running
- the command (don't forget that [
is a command and will
- wipe out PIPESTATUS
).
-
- tar -cf - ./* | ( cd "${DIR}" && tar -xf - )
- return_codes=(${PIPESTATUS[*]})
- if [[ "${return_codes[0]}" -ne 0 ]]; then
- do_something
- fi
- if [[ "${return_codes[1]}" -ne 0 ]]; then
- do_something_else
- fi
-
-
-
-
-
-
-
- Given the choice between invoking a shell builtin and invoking a separate
- process, choose the builtin.
-
-
-
- We prefer the use of builtins such as the Parameter Expansion
- functions in bash(1)
as it's more robust and portable
- (especially when compared to things like sed).
-
-
- Example:
-
- # Prefer this:
- addition=$((${X} + ${Y}))
- substitution="${string/#foo/bar}"
-
- # Instead of this:
- addition="$(expr ${X} + ${Y})"
- substitution="$(echo "${string}" | sed -e 's/^foo/bar/')"
-
-
-
-
-
-
-
-
-
- Use common sense and BE CONSISTENT.
-
-
- Please take a few minutes to read the Parting Words section at the bottom
- of the C++ Guide.
-
-
-
-
-Revision 1.26
-
-
-
diff --git a/styleguide.css b/styleguide.css
deleted file mode 100644
index adba8f3..0000000
--- a/styleguide.css
+++ /dev/null
@@ -1,147 +0,0 @@
-body {
- background-color: #fff;
- color: #333;
- font-family: sans-serif;
- font-size: 10pt;
- margin-right: 100px;
- margin-left: 100px;
-}
-
-h1, h2, h3, h4, h5, h6, .toc_title {
- color: #06c;
- margin-top: 2em;
- margin-bottom: 1em;
-}
-
-h1 {
- text-align: center;
- font-size: 18pt;
-}
-
-h2, .toc_title {
- font-weight: bold;
- font-size: 12pt;
- margin-left: -40px;
-}
-
-h3, h4, h5, h6 {
- font-size: 10pt;
- margin-left: -20px;
-}
-
-.toc_category, .toc_stylepoint {
- font-size: 10pt;
- padding-top: .3em;
- padding-bottom: .3em;
-}
-
-table {
- border-collapse: collapse;
-}
-
-td, th {
- border: 1px solid #ccc;
- padding: 2px 12px;
- font-size: 10pt;
-}
-
-.toc td, .toc th {
- border-width: 1px 5px;
-}
-
-code, samp, var {
- color: #060;
-}
-
-pre {
- font-size: 10pt;
- display: block;
- color: #060;
- background-color: #f8fff8;
- border-color: #f0fff0;
- border-style: solid;
- border-top-width: 1px;
- border-bottom-width: 1px;
- border-right-width: 1px;
- border-left-width: 5px;
- padding-left: 12px;
- padding-right: 12px;
- padding-top: 4px;
- padding-bottom: 4px;
-}
-
-pre.badcode {
- color: #c00;
- background-color: #fff8f8;
- border-color: #fff0f0;
-}
-
-.showhide_button {
- float: left;
- cursor: pointer;
- border-width: 1px;
- border-style: solid;
- border-color: #ddd #aaa #aaa #ddd;
- padding: 0 3px 1px;
- margin: 0 4px 8px 0;
- border-radius: 3px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
-}
-
-.link_button {
- float: left;
- display: none;
- background-color: #f8f8ff;
- border-color: #f0f0ff;
- border-style: solid;
- border-width: 1px;
- font-size: 75%;
- margin-top: 0;
- margin-left: -50px;
- padding: 4px;
- border-radius: 3px;
- -webkit-border-radius: 3px;
- -moz-border-radius: 3px;
-}
-
-address {
- text-align: right;
-}
-
-hr {
- margin-top: 3.5em;
- border-width: 1px;
- color: #fff;
-}
-
-.stylepoint_section {
- display: block;
- margin-bottom: 1em;
- color: #5588ff;
- font-family: sans-serif;
- font-size: 90%;
- font-weight: bold;
- margin-left: -2%;
-}
-
-.stylepoint_subsection {
- color: #667799;
- font-family: sans-serif;
- font-size: 90%;
- font-weight: bold;
- margin-left: -1%;
-}
-
-.stylepoint_subsubsection {
- color: #667799;
- font-family: sans-serif;
- font-size: 80%;
- font-weight: bold;
- margin-left: 0;
-}
-
-.revision {
- text-align: right;
-}
-
diff --git a/styleguide.xsl b/styleguide.xsl
deleted file mode 100644
index 09a9b95..0000000
--- a/styleguide.xsl
+++ /dev/null
@@ -1,924 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Each style point has a summary for which additional information is available
- by toggling the accompanying arrow button that looks this way:
-
- .
- You may toggle all summaries with the big arrow button:
-
-
-
- Toggle all summaries
-
-
-
-
-
-
-
-
- Parting Words
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- javascript:ShowHideByName('
-
- ')
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- display: inline
- display: none
-
-
-
-
-
-
-
-
-
-
- Definition:
-
-
-
-
-
-
-
- Pros:
-
-
-
-
-
-
-
- Cons:
-
-
-
-
-
-
-
- Decision:
-
-
-
-
-
-
-
-
TODO:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Table of Contents
-
-
-
-
-
-
-
-
-
-
-
-
-
- #
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- _
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/vimscriptfull.asciidoc b/vimscriptfull.asciidoc
new file mode 100644
index 0000000..9726374
--- /dev/null
+++ b/vimscriptfull.asciidoc
@@ -0,0 +1,864 @@
+= Google Vimscript Guide
+
+:sectlinks:
+
+Revision 1.1
+
+Nate Soares +
+ Joshua Hoak +
+ David Barnett +
+
+
+
+
+
+Table of Contents
+
+[width="100%",cols="50%,50%",]
+|=========================================================================================================================================
+a|
+link:#portability[Portability]
+
+ a|
+a|
+link:#language-guide[Language Guide]
+
+ a|
+a|
+link:#structure[Structure]
+
+ a|
+link:#libraries-vs-functionality[Libraries vs. Functionality] link:#configuration[Configuration]
+
+a|
+link:#style-guide[Style Guide]
+
+ a|
+link:#documentation[Documentation] link:#whitespace[Whitespace] link:#variables[Variables] link:#strings[Strings] link:#settings[Settings]
+
+a|
+link:#usage-guide[Usage Guide]
+
+ a|
+link:#commands[Commands] link:#autocommands[Autocommands] link:#functions[Functions] link:#mappings[Mappings]
+
+a|
+link:#conventions[Conventions]
+
+ a|
+link:#dependency-checking[Dependency Checking] link:#statusline-flags[Statusline Flags]
+
+a|
+link:#forbidden-commands[Forbidden Commands]
+
+ a|
+a|
+link:#layout[Layout]
+
+ a|
+a|
+link:#recommended-shortcuts[Recommended Shortcuts]
+
+ a|
+a|
+link:#errata[Errata]
+
+ a|
+link:#compatibility-mode[Compatibility Mode]
+
+|=========================================================================================================================================
+
+[[Background]]
+== Background
+
+This is the in-depth vimscript guide. If you're just a casual user looking to write a plugin, the link:vimscriptguide.html[abbreviated style guide] is for you.
+
+This rather rotund guide dives into justifications and clarifications. It provides an idealized set of rules that are rather too draconian to push on casual scripters.
+
+It's for users who want to know why certain decisions were made in the abbreviated guide and who want to learn a thing or two about using vimscript safely.
+
+Fair warning: Vimscript is a maddening abyss. When you gaze into it, it gazes also into you. Proceed with caution.
+
+[[Portability]]
+== Portability
+
+Vim is highly configurable. Users can change many of the default settings, including the case sensitivity, the regular expression rules, the substitution rules, and more. In order for your vimscript to work for all users, follow these guidelines:
+
+
+* Always prefix regular expressions with one of `\m`, `\v`, `\M`, or `\V` (prefer tersity)
+
+** Users can change the global "magic level" of regular expressions. This changes how atoms are parsed in regular expressions, including `.`, `*`, and `{`.
+
+** Even if your regular expression does not contain characters which are affected by the `magic` setting you must prefix it with one of the magic control atoms. This future-proofs your regular expression against other devs modifying it and forgetting to add the control atom.
+
+** If you have no opinion about what type of regular expression to use, prefer the one which makes your regular expression most concise.
+
+* Avoid using `:s[ubstitute]` in scripts.
+
+** `:substitute` moves the cursor.
+
+** `:substitute` outputs an error message when the match does not exist.
+
+** The meaning of the `g` flag depends upon the `gdefault` setting. If you do use `:substitute` you must save `gdefault`, set it to `0` or `1`, perform the substitution, and then restore it.
+
+** Script authors who want a safe way to replace text in the buffer are encouraged to use `maktaba#buffer#Replace`.
+
+* Always use case-explicit operators for strings (`=~#` and `=~?`, never `=~`).
+
+** This also applies to `!~ == != > >= <` and `<=`
+
+** This only applies for strings. `==` and `>=` are fine for numbers, but `==#` and `>=#` must be used for strings.
+
+** The behavior of `=~` and friends is dependant upon the `ignorecase` setting.
+
+** You may break this rule when you explicitly want to obey the user's `ignorecase` setting. Be prepared to justify your reasoning.
+
+* When using regular expressions as arguments to functions, prepend them with `\c` or `\C`.
+
+** This forces case to be either explicitly matched or ignored.
+
+** This is recommended, but not required, when comparing regexes with operators that specify case sensitivity (`=~#`, etc.).
+
+** This rule applies when your regexes are matching syntax, external APIs, external messages, and most other cases.
+
+** It does not apply when matching text in the buffer. When matching text in the buffer you should honor the `ignorecase` setting.
+
+** You may also ignore this rule any time that you explicitly want to honor the `ignorecase` setting. Be prepared to justify your reasoning.
+
+* Always use `normal!` instead of `normal`.
+
+** If you forgo the `!` the command will use the user's key mappings and you have literally no idea what your macro will do.
+
+* Always use the `noremap` family of commands.
+
+** Your plugins generally shouldn't introduce mappings, but if they do, the `map` command respects the users existing mappings and could do anything.
+
+* When using `catch`, match the error code rather than the error text.
+
+** The error text may be locale-dependant.
+
+** See `:help error-messages`.
+
+In general, guard all commands and functions against user settings.
+
+[[Language_Guide]]
+== Language Guide
+
+
+* Line continuations: Yes
+
+** Plugins that support vi compatibility mode must save and restore compatibility options as described in the Errata section so line continuations work properly.
+
+* Exceptions: Yes, with caution
+
+** Always use an error code in thrown exception messages.
+
+** Prefer the `maktaba#error` codes found in `maktaba`.
+
+** Fall back to the vim error codes. See `:help error-messages`.
+
+** Generate custom error messages using `maktaba#error#Message`.
+
+* Global Variables: As configuration only
+
+** See the plugin guide.
+
+* Messaging: As little as possible.
+
+** Loud scripts are annoying.
+
+** Message the user when an error has occured.
+
+** Message the user when an operation which takes a long time has begun work.
+
+** Avoid messaging otherwise.
+
+* Type checking: Use strict and explicit checks where possible.
+
+** Vimscript has unsafe, unintuitive behavior when dealing with some types. For instance, `0 == 'foo'` evaluates to true.
+
+** Use strict comparison operators where possible. When comparing against a string literal, use the `is#` operator. Otherwise, prefer `maktaba#value#IsEqual` or check `type()` explicitly.
+
+** Check variable types explicitly before using them. Use functions from `maktaba#ensure`, or check `maktaba#value` or `type()` and throw your own errors.
+
+** Use `:unlet` for variables that may change types, particularly those assigned inside loops.
+
+* FuncRefs: No in most cases.
+
+** FuncRefs have inconsistently enforced naming restrictions. (Functions can have names that FuncRefs can not.)
+
+** FuncRefs have inconsistent ability to be reassigned (in Vim 7.2 and before you must unlet a FuncRef before assigning it).
+
+** In most instances where a FuncRef is needed a string works just as well: just pass the string that you would use to make the FuncRef.
+
+** Consider using `maktaba#function` instead to create and manipulate handles to functions.
+
+* Python: Sparingly
+
+** Hurts code reuse since python code embedded in python plugins is awkward to share between plugins.
+
+** Using python introduces python language version dependencies, which are likely to get stale.
+
+** Exception: It's reasonable to use python for plugin functionality that needs to do work in the background, as vimscript can not do this.
+
+* Ruby: No
+
+** We can not assume ruby interoperability.
+
+** You shouldn't depend upon the version of the ruby language that the user has installed.
+
+* Lua: No
+
+** For the same reasons an Ruby.
+
+* Dict Functions: Encouraged
+
+** Vimscript can attach functions to dictionaries. Such functions have access to the `self` parameter which access the dict state.
+
+** Use these where you would use a class in python.
+
+** Do not over-use this feature; it is not necessary for helper functions or API functions, only for encapsulated objects.
+
+All other language features are fair game.
+
+[[Structure]]
+== Structure
+
+
+* Provided functionality should be packed into modular plugins.
+
+** Every function in your plugin should be specific to your plugin.
+
+** General utility functions should be abstracted into library plugins.
+
+** Manage dependencies with `maktaba`.
+
+* `plugin-names-like-this`
+
+** Plugin names should be descriptive and concise.
+
+* Each plugin must consist of one directory (or code repository), sharing a name with the plugin (with a "vim-" prefix or ".vim" suffix if desired).
+
+* Plugin metadata should be declared in the addon-info.json format (see the http://goo.gl/CUXJZC[VAM documentation] for details).
+
+* Functions should go in the `autoload/` subdirectory of your plugin.
+
+** This allows them to be late-loaded, which speeds up startup time.
+
+** This helps vim enforce namespacing conventions.
+
+* Each file in the `plugin/` or `instant/` directory should begin with the boilerplate
++
+-------------------------------------------------------------------
+let [s:plugin, s:enter] = maktaba#plugin#Enter(expand(':p'))
+if !s:enter
+ finish
+endif
+-------------------------------------------------------------------
++
+(This prevents re-entry and allows users to selectively disable functionality.)
+
+* User configuration should be via plugin flags defined in `instant/flags.vim`.
+
+** Define flags with `call s:plugin.Flag('FLAGNAME', DEFAULT_VALUE)`.
+
+** Users can configure these flags using the `:Glaive` command (see https://github.com/google/glaive[glaive]).
+
+* Commands, autocommands, mappings, and settings changes should occur either in the `plugin/` or the `ftplugin/` subdirectories.
+
+** All commands should be defined in `plugin/commands.vim` or `ftplugin/` files.
+
+** Autocommands should be defined in `plugin/autocmds.vim`, inside an augroup.
+
+** Mappings should be defined in `plugin/mappings.vim` and will be disabled unless explicitly enabled by users.
+
+** If the plugin configures any standard vim settings, those should be configured in `plugin/settings.vim` or `instant/settings.vim`.
+
+* Avoid using the `after/` subdirectory.
+
+** `after/` should be reserved for the user.
+
+** It is difficult for the user to add their own overrides when plugins use `after/`.
+
+=== Libraries vs. Functionality
+
+
+
+Separate library-providing plugins from command-providing plugins.
+
+Many plugins provide either user functionality (commands, autocommands, etc) or an API (of autoloaded functions) but not both. This separation is encouraged, as it allows other plugins to pull in a library without also pulling in commands, setting changes, and other plugin functionality that affects the end user.
+
+=== Configuration
+
+
+
+Don't clobber user settings. Provide as much configurability as possible: that's what Vim's all about.
+
+
+* Use maktaba flags for plugin configuration. Users can configure them using the `:Glaive` command.
+
+* Check if configuration variables exist before setting them.
++
+-------------------------------
+if !exists('g:myplugin_option')
+ let g:myplugin_option = 1
+endif
+-------------------------------
+
+[[Style_Guide]]
+== Style Guide
+
+Follow google-wide style conventions. Mimic google python style when in doubt.
+
+=== Documentation
+
+
+
+Use https://github.com/google/vimdoc[vimdoc].
+
+Provide help files generated by https://github.com/google/vimdoc[vimdoc]. Write documentation in .vim files in conformance with the vimdoc standards and include fields like "description" and "author" in the addon-info.json file (see the http://goo.gl/CUXJZC[VAM documentation]).
+
+=== Whitespace
+
+
+
+Follow google-wide conventions.
+
+
+* Use two spaces for indents.
+
+* Do not use tabs.
+
+* Use spaces around operators except for arguments to commands.
+
+** Using spaces around operators for commands is often invalid syntax. This is inconsistently enforced by vimscript. To be safe, always omit whitespace around arguments to commands.
+--------------------------------------------
+let s:variable = "concatenated " . "strings"
+command -range=% MyCommand
+--------------------------------------------
++
+----------------------------------------
+let s:variable="concatenated "."strings"
+command -range = % MyCommand
+----------------------------------------
+
+* Do not introduce trailing whitespace.
+
+** You need not go out of your way to remove it.
+
+* Restrict lines to 80 columns wide.
+
+* Indent continued lines by two tabs (four spaces).
+
+* Do not waste whitespace aligning common segments of similar commands. It is both difficult and expensive to maintain.
+-------------------------------------------
+command -bang MyCommand call myplugin#foo()
+command MyCommand2 call myplugin#bar()
+-------------------------------------------
++
+--------------------------------------------
+command -bang MyCommand call myplugin#foo()
+command MyCommand2 call myplugin#bar()
+--------------------------------------------
+
+Line Continuations
+
+
+* Prefer line continuations on semantic boundaries.
+--------------------------
+command SomeLongCommand
+ \ call some#function()
+--------------------------
++
+----------------------------
+command SomeLongCommand call
+ \ some#function()
+----------------------------
+
+** Use your best judgement.
+
+* Place one space after the backslash denoting a line continuation.
+
+** When continuing a multi-line command a pipe can be substituted for this space as necessary, as follows:
++
+---------------------------------
+autocommand BufEnter
+ \ if !empty(s:var)
+ \| call some#function()
+ \|else
+ \| call some#function(s:var)
+ \|endif
+---------------------------------
+
+* Do not continue multi-line commands when you can avoid it. Prefer function calls.
+
+Comments
+
+
+* Place a space after the `"` before the comment text.
+------------------------
+" I am a line comment.
+call call(s:my_function)
+------------------------
+
+* Do not use inline comments.
+
+** Some commands treat them as comments and others as unclosed quotes. There are many edge cases. It's difficult to get right and difficult to maintain.
+
+** Where you would use an inline comment, put a line comment on the line above.
+
+* When leaving blank lines in comments, include the quote in the blank line.
+---------------------
+" I am one continuous
+"
+" comment block
+---------------------
+
+=== Variables
+
+
+
+`plugin-names-like-this`, `FunctionNamesLikeThis`, `CommandNamesLikeThis`, `augroup_names_like_this`, `variable_names_like_this`.
+
+Prefix all variables with their scope.
+
+
+* `variable_names_like_this`
+
+** FuncRef variables count as functions and should be named like functions.
+
+** This (pathological) convention is enforced by vim itself.
+
+* Prefix global variables with `g:`
+
+** Vimscript allows you to create global variables without prefixing them.
+
+** It is very bad practice to introduce non-prefixed global variables into scope.
+
+** Global variables should only be used for plugin configuration.
+
+** This does not apply to functions defined in `autoload` directories.
+
+* Prefix script-local variables with `s:`
+
+** This prevents namespace collisions between plugins.
+
+** This also applies to script-local functions.
+
+* Prefix function arguments with `a:`
+
+** This is enforced by vim itself.
+
+* Prefix function-local variables with `l:`
+
+** This is not enforced by vimscript but is good practice.
+
+** It helps you remember that all other variables must be prefixed with scope.
+
+** `l:` disambiguates between function-local and vim-predefined variables. For example, `count` refers to `v:count`, not `l:count`.
+
+** It future proofs your scripts against the introduction of new vim-predefined variables.
+
+* Prefix pre-defined vim variables with `v:`
+
+** This is not enforced by vimscript but is good practice.
+
+** It provides context as to where the (undeclared) variable is coming from.
+
+** It reminds you that the variable can not be assigned to.
+
+* Prefix buffer-local variables with `b:`
+
+** This is useful for plugins that keep per-buffer state.
+
+=== Strings
+
+
+
+Prefer single quotes.
+
+Prefer single quoted strings. Specifically, in order of precedence:
+
+
+* Always use single quotes for regular expressions.
+
+** `'\s*'` is not the same as `"\s*"`
+
+** Single quotes will prevent the need for excessive backslashes.
+
+** Double single quotes escape to one single quote in single quoted strings: `'example ('')'` represents the string `example (')`
+
+* If your string requires escape characters (`\n`, `\t`, etc.) use double quotes.
+
+** Escapes can not be expressed in single quoted strings.
+
+** Remember that `'\n'` in a regex does not represent a newline, but rather "\n". You only need to use double quotes when you want to embed the represented character itself (e.g. a newline) in the string.
+
+* If your string contains no escapes nor single quotes, use single quoted strings.
+
+** Most strings in vimscript are regexes, so this provides maximum consistency.
+
+* If your non-regex string contains single quotes but no double quotes, use double quotes.
+
+** Don't bother escaping strings if you don't have to.
+
+** This is similar to the python string rules.
+
+* If your string contains both single and double quotes, use whichever quoting style requires less escaping.
+
+** Break ties in favor of single quotes.
+
+=== Settings
+
+
+
+Prefer long names. Set settings locally.
+
+
+* Prefer long names of built in settings (i.e. `tabstop` over `ts`).
+
+* Set local settings unless you explicitly want to set global settings.
+
+** Use `setlocal` and `&l:` instead of `set` and `&`.
+
+[[Usage_Guide]]
+== Usage Guide
+
+Vim plugins should provide any or all of the following: Commands, Autocommands, Functions, Statusline Flags, and Mappings.
+
+=== Commands
+
+
+
+
+* Define in `plugin/commands.vim`.
+
+* CommandNamesLikeThis.
+
+* Prefer semantic names to a unified prefix.
+
+* Do not use `[!]`
+
+* Extract logic into functions.
+
+
+* `CommandNamesLikeThis`
+
+* Commands should be defined in one block with no whitespace between them.
+
+** Name commands semantically at the expense of a common prefix.
+
+**--------------------------------
+command WhitespaceFixTrailing
+command WhitespaceFixIndentation
+--------------------------------
++
+-----------------------------
+command FixTrailingWhitespace
+command FixIndentation
+-----------------------------
+
+* Use `command` without a bang.
+
+** This notifies users to command name conflicts immediately at startup.
+
+** Command name collisions are an error and should not fail silently.
+
+** Plugins are guarded against re-entry, so a single vim session should never attempt to re-define defined commands.
+
+* Do not put logic in commands.
+
+** Delegate to functions instead.
+
+** Pass non-argument command parameters (``, ``, etc.) before argument parameters (``, etc.).
+
+** Otherwise variable-length argument functions are difficult to implement.
+
+* Do not autoload commands.
+
+** Autoloaded commands will not be available until after a function in the same file is called.
+
+** Commands intended to be used in the .vimrc should be defined in a `instant/commands.vim` file in plugins using maktaba, or explicitly installed via an autoload function in non-maktaba plugins.
+
+Conventions
+
+
+* Pass `` to functions with `'' == '!'`.
+
+** The function should receive a boolean parameter, not a string.
+
+=== Autocommands
+
+
+
+
+* Define in `plugin/autocmds.vim`.
+
+* Use augroups.
+
+* augroup_names_like_this.
+
+* Clear the augroup first.
+
+* Extract logic into functions.
+
+
+* All autocommands should be defined in the `plugin/autocmds.vim` file.
+
+** This allows users to disable your autocommands with `Glaive myplugin !plugin[autocmds]`.
+
+* Declare all autocommands in an `augroup` block.
+
+** This allows your autocommands to be cleared with `autocmd!`.
+
+** If your plugin only has one `augroup`, the `augroup` name should be the same as your plugin name, with underscores in place of any hyphens.
+
+** Otherwise `augroup` names should start with your plugin name followed by an underscore.
+
+* Do not put logic in autocommands.
+
+** Delegate to functions instead.
+
+* When creating a new `augroup`, clear it with `autocmd!`
+
+** This allows your plugins to be re-enterable.
+
+=== Functions
+
+
+
+
+* FunctionNamesLikeThis.
+
+* Autoload all functions.
+
+* Prefix script-local functions with `s:`
+
+* Use `[!]`.
+
+* Use `[abort]`.
+
+
+* `FunctionNamesLikeThis`
+
+* Prefix all script-local functions with `s:`
+
+* Do not provide global functions. Use autoloaded functions instead.
+
+* Place two blank lines between top-level functions.
+
+* Declare all functions with `abort`.
+
+** If you do not do this, the function's behavior depends upon whether it is called within a `try..endtry` block somewhere on the stack.
+
+** The `abort` keyword forces the function to act consistently.
+
+** Without it, the function may (or may not) attempt to continue execution after an error occurs.
+
+* Use `function!` with a bang.
+
+** This allows developers to re-source their scripts and have the functions reloaded without complaint.
+
+** Function names should never collide because functions should always be either script-local or defined in an `autoload` directory.
+
+** Failing to use a bang in any function in an autoload file will lead to cryptic errors if vim tries to re-source the file (e.g., if you refer to an nonexistent autoload function).
+
+* Use `...` for optional arguments, not for lists of arguments.
+
+** Vimscript functions take at most 20 arguments.
+
+** Lists have no such length restriction.
+
+** Your function is likely to break when given too many arguments if you use `...` for a list of arguments.
+
+* Throw exceptions rather than printing errors.
+
+** Printed errors can not be caught.
+
+** Top-level functions expecting errors may catch them and print error messages, but even those should throw their own errors when they choke.
+
+=== Mappings
+
+
+
+
+* Provide opt-in key mappings in `plugin/mappings.vim`.
+
+* `` mappings can be defined in `plugin/plugs.vim` (unlike mappings.vim, plugs.vim is opt-out).
+
+
+* Define key mappings in `plugin/mappings.vim`, using `maktaba#plugin#MapPrefix` to get a prefix.
+
+** Mappings defined in the special `plugin/mappings.vim` file will be disabled by default (by the standard `maktaba#plugin#Enter()` boilerplate).
+
+** Users can enable key mappings with `Glaive myplugin plugin[mappings]`.
+
+* Make all mappings with ``.
+
+** This will inform the user when they have a mapping conflict instead of silently clobbering their existing mappings.
+
+* You may provide pseudo-mappings using `` and your plugin's name in `plugin/plugs.vim` (separate from standard key mappings).
+
+** `` is a sequence which can not be typed.
+
+** You can do something like `noremap namespace#MappingName some_key_sequence` and then users can do `noremap x namespace#MappingName` to take advantage of your pseudo-mapping.
+
+** Pseudo-mappings should not be in `plugin/mappings.vim` or they will be disabled by default.
+
+** Such pseudo-mappings should be named `` followed by your plugin name, a pound sign, and a unique mapping name (CamelCased like a function).
+
+* Always use the `noremap` family of commands. Never use the `map` family.
+
+** `map` depends upon the user's existing mappings, and could do anything.
+
+* Only use `noremap` for commands that both make a motion and take a range.
+
+** `noremap` makes mappings in normal, visual, and operator-pending modes.
+
+** If you don't want all these use `nnoremap` `onoremap` or `vnoremap` explicitly.
+
+* Always use `` in place of `s:` when accessing script locals in mappings.
+
+** Using `s:` will often fail as the mapping attempts to type a literal s and colon.
+
+[[Conventions]]
+== Conventions
+
+=== Dependency Checking
+
+
+
+Declare dependencies in addon-info.json and use `maktaba`.
+
+Declaring dependencies in addon-info.json allows conformant plugin managers (like VAM) to ensure dependencies are installed. See the http://goo.gl/CUXJZC[VAM documentation] for details.
+
+Calling `maktaba#library#Require` from dependent code at runtime ensures that dependencies have been installed and that they don't include unsafe non-library files.
+
+=== Statusline Flags
+
+
+
+Use `#status#Status()` or its finer-grained variants to provide statusline flags.
+
+Following is a convention for exposing statusline flags to the user. A plugin should never modify the user's statusline except for when that is the only purpose of the plugin (powerline, etc.).
+
+
+* Provide the `Info`, `Alert`, `Warning`, and `Error` functions under the `#status` namespace.
+
+* `Info` should provide information about the state of the buffer.
+
+** Example: The current git branch.
+
+* `Alert` should provide a quiet reminder that the buffer is non-standard.
+
+** Example: The readonly setting is on.
+
+* `Warning` should provide a warning about the current state of the buffer.
+
+** Example: The file has been edited elsewhere.
+
+* `Error` should bring to attention a loud issue with the buffer.
+
+** Example: The file does not pass the syntax checker.
+
+* By following these conventions, users can easily build up their own statusline customizing the verbosity and colors to their tastes.
+
+* All functions should take no arguments and should return either empty strings or strings enclosed by square brackets, e.g. `[Google]`. For example:
+
+** A trailing whitespace plugin might return `[$]` if the file contains trailing whitespace
+
+** A prose writing plugin might return `[write]` if vim is in writing mode.
+
+* Consider providing the `#status#Status` function.
+
+** It should return the first non-empty of `Error`, `Warning`, `Alert`, or `Info`.
+
+** This is useful for users who want only the most relevant flag and do not have a colored statusline.
+
+[[Forbidden_Commands]]
+== Forbidden Commands
+
+These are commands which can only be used by a limited number of plugins, and should not in general be used by yours.
+
+
+* Do not use `:match :2match` or `:3match`
+
+** These are reserved for the user and for vim itself.
+
+** Use `matchadd()` to create a matchlevel unique to your plugin.
+
+* Do not use `echoerr`.
+
+** `echoerr` does not print the red error message that you might think it does.
+
+** `echoerr` prints an error message as well as context about the code where `echoerr` was called.
+
+** `echoerr` is best suited for debugging.
+
+** Use `echohl` in tandem with `echomsg` if you want the red error bar.
+
+* Use `echomsg` instead of `echo`.
+
+** `echomsg` messages can be reviewed with the `:messages` command.
+
+** `echo` messages disappear permanently on redraw, which can be very annoying to users who failed to read the message in time.
+
+[[Layout]]
+== Layout
+
+Lay out `plugin/` files in the following sections, if applicable, separated by two blank lines:
+
+
+* Declaration of script constants
+
+* Declaration of configuration variables
+
+* Other declarations (commands in `commands.vim` file, autocommands in `autocmds.vim` file, etc.)
+
+Lay out `autoload/` files in the following sections, if applicable, separated by two blank lines:
+
+
+* `maktaba#library#Require` calls
+
+* Script-local variables
+
+* Script-local functions
+
+* Private autoloaded functions
+
+* Public autoloaded functions
+
+This is recommended convention and is not enforced.
+
+[[Recommended_Shortcuts]]
+== Recommended Shortcuts
+
+Use the following shortcuts:
+
+
+* `catch` over `catch /.*/`
+
+* `return` over `return 0` when the return value has no semantic purpose.
+
+[[Errata]]
+== Errata
+
+This section plumbs some of the darker corners of vimscript, explaining the language pathologies that you wish you didn't have to know.
+
+=== Compatibility Mode
+
+
+
+If you don't support vi-compatibility mode, fail gracefully.
+
+When `compatible` is set, many vim features are not available. The vim feature which most commonly affects vimscript authors is line continuations.
+
+If you want your plugin to work in vim with vi compatibility on, you will need to save the compatibility options at the beginning of each plugin file, clear them, and restore them at the end of each plugin file. See `:help use-cpo-save` for details.
+
+Plugins that depend on maktaba generally don't need to worry about compatible mode since maktaba currently just disables it, printing a warning.
+
+Revision 1.1
+
+Nate Soares +
+ Joshua Hoak +
+ David Barnett +
diff --git a/vimscriptfull.xml b/vimscriptfull.xml
deleted file mode 100644
index 8d233f1..0000000
--- a/vimscriptfull.xml
+++ /dev/null
@@ -1,1534 +0,0 @@
-
-
-
-
-
- Revision 1.1
-
-
-
-
- Nate Soares
- Joshua Hoak
- David Barnett
-
-
-
-
-
- This is the in-depth vimscript guide. If you're just a casual user
- looking to write a plugin, the
- abbreviated style guide is for you.
-
-
- This rather rotund guide dives into justifications and clarifications.
- It provides an idealized set of rules that are rather too draconian to
- push on casual scripters.
-
-
-
- It's for users who want to know why certain decisions were made in the
- abbreviated guide and who want to learn a thing or two about using
- vimscript safely.
-
-
- Fair warning: Vimscript is a maddening abyss. When you gaze into it, it
- gazes also into you. Proceed with caution.
-
-
-
-
-
-
- Vim is highly configurable. Users can change many of the default
- settings, including the case sensitivity, the regular expression rules,
- the substitution rules, and more. In order for your vimscript to work
- for all users, follow these guidelines:
-
-
- -
- Always prefix regular expressions with one of
\m
,
- \v
, \M
, or \V
(prefer
- tersity)
-
- -
- Users can change the global "magic level" of regular expressions.
- This changes how atoms are parsed in regular expressions,
- including
.
, *
, and {
.
-
- -
- Even if your regular expression does not contain characters which
- are affected by the
magic
setting you must prefix it
- with one of the magic control atoms. This future-proofs your
- regular expression against other devs modifying it and forgetting
- to add the control atom.
-
- -
- If you have no opinion about what type of regular expression to
- use, prefer the one which makes your regular expression most
- concise.
-
-
-
- -
- Avoid using
:s[ubstitute]
in scripts.
-
- -
-
:substitute
moves the cursor.
-
- -
-
:substitute
outputs an error message when the match
- does not exist.
-
- -
- The meaning of the
g
flag depends upon the
- gdefault
setting. If you do use
- :substitute
you must save gdefault
, set
- it to 0
or 1
, perform the substitution,
- and then restore it.
-
- -
- Script authors who want a safe way to replace text in the buffer
- are encouraged to use
maktaba#buffer#Replace
.
-
-
-
- -
- Always use case-explicit operators for strings (
=~#
and
- =~?
, never =~
).
-
- -
- This also applies to
!~ == != > >= <
and
- <=
-
- -
- This only applies for strings.
==
and
- >=
are fine for numbers, but ==#
and
- >=#
must be used for strings.
-
- -
- The behavior of
=~
and friends is dependant upon the
- ignorecase
setting.
-
- -
- You may break this rule when you explicitly want to obey the
- user's
ignorecase
setting. Be prepared to justify
- your reasoning.
-
-
-
- -
- When using regular expressions as arguments to functions, prepend them
- with
\c
or \C
.
-
- -
- This forces case to be either explicitly matched or ignored.
-
- -
- This is recommended, but not required, when comparing regexes with
- operators that specify case sensitivity (
=~#
, etc.).
-
- -
- This rule applies when your regexes are matching syntax, external
- APIs, external messages, and most other cases.
-
- -
- It does not apply when matching text in the buffer. When matching
- text in the buffer you should honor the
ignorecase
- setting.
-
- -
- You may also ignore this rule any time that you explicitly want to
- honor the
ignorecase
setting. Be prepared to justify
- your reasoning.
-
-
-
- -
- Always use
normal!
instead of normal
.
-
- -
- If you forgo the
!
the command will use the user's
- key mappings and you have literally no idea what your macro will
- do.
-
-
-
- -
- Always use the
noremap
family of commands.
-
- -
- Your plugins generally shouldn't introduce mappings, but if they
- do, the
map
command respects the users existing
- mappings and could do anything.
-
-
-
- -
- When using
catch
, match the error code rather than the
- error text.
-
- -
- The error text may be locale-dependant.
-
- -
- See
:help error-messages
.
-
-
-
-
-
- In general, guard all commands and functions against user settings.
-
-
-
-
-
-
-
- -
- Line continuations: Yes
-
-
- -
- Plugins that support vi compatibility mode must save and restore
- compatibility options as described in the
- Errata section so line continuations work properly.
-
-
-
- -
- Exceptions: Yes, with caution
-
- -
- Always use an error code in thrown exception messages.
-
- -
- Prefer the
maktaba#error
codes found in
- maktaba
.
-
- -
- Fall back to the vim error codes. See
-
:help error-messages
.
-
- -
- Generate custom error messages using
-
maktaba#error#Message
.
-
-
-
- -
- Global Variables: As configuration only
-
- -
- See the plugin guide.
-
-
-
- -
- Messaging: As little as possible.
-
- -
- Loud scripts are annoying.
-
- -
- Message the user when an error has occured.
-
- -
- Message the user when an operation which takes a long time has
- begun work.
-
- -
- Avoid messaging otherwise.
-
-
-
- -
- Type checking:
- Use strict and explicit checks where possible.
-
- -
- Vimscript has unsafe, unintuitive behavior when dealing with some
- types. For instance,
0 == 'foo'
evaluates to true.
-
- -
- Use strict comparison operators where possible. When comparing
- against a string literal, use the
is#
operator.
- Otherwise, prefer maktaba#value#IsEqual
or check
- type()
explicitly.
-
- -
- Check variable types explicitly before using them. Use functions
- from
maktaba#ensure
, or check
- maktaba#value
or type()
and throw your own
- errors.
-
- -
- Use
:unlet
for variables that may change types,
- particularly those assigned inside loops.
-
-
-
- -
- FuncRefs: No in most cases.
-
- -
- FuncRefs have inconsistently enforced naming restrictions.
- (Functions can have names that FuncRefs can not.)
-
- -
- FuncRefs have inconsistent ability to be reassigned (in Vim
- 7.2 and before you must unlet a FuncRef before assigning it).
-
- -
- In most instances where a FuncRef is needed a string works
- just as well: just pass the string that you would use to make
- the FuncRef.
-
- -
- Consider using
maktaba#function
instead to create and
- manipulate handles to functions.
-
-
-
- -
- Python: Sparingly
-
-
- -
- Hurts code reuse since python code embedded in python plugins is
- awkward to share between plugins.
-
- -
- Using python introduces python language version dependencies, which
- are likely to get stale.
-
- -
- Exception: It's reasonable to use python for plugin functionality
- that needs to do work in the background, as vimscript can not do
- this.
-
-
-
- -
- Ruby: No
-
- -
- We can not assume ruby interoperability.
-
- -
- You shouldn't depend upon the version of the ruby language that the
- user has installed.
-
-
-
- -
- Lua: No
-
- -
- For the same reasons an Ruby.
-
-
-
- -
- Dict Functions: Encouraged
-
- -
- Vimscript can attach functions to dictionaries. Such functions
- have access to the
self
parameter which access
- the dict state.
-
- -
- Use these where you would use a class in python.
-
- -
- Do not over-use this feature; it is not necessary for helper
- functions or API functions, only for encapsulated objects.
-
-
-
-
-
- All other language features are fair game.
-
-
-
-
- -
- Provided functionality should be packed into modular plugins.
-
- -
- Every function in your plugin should be specific to your
- plugin.
-
- -
- General utility functions should be abstracted into library plugins.
-
- -
- Manage dependencies with
maktaba
.
-
-
-
- -
-
plugin-names-like-this
-
- -
- Plugin names should be descriptive and concise.
-
-
-
-
-
- -
- Each plugin must consist of one directory (or code repository), sharing
- a name with the plugin (with a "vim-" prefix or ".vim" suffix if
- desired).
-
- -
- Plugin metadata should be declared in the addon-info.json format (see
- the VAM documentation for details).
-
- -
- Functions should go in the
autoload/
subdirectory of
- your plugin.
-
- -
- This allows them to be late-loaded, which speeds up startup
- time.
-
- -
- This helps vim enforce namespacing conventions.
-
-
-
- -
- Each file in the
plugin/
or instant/
directory
- should begin with the boilerplate
-
- let [s:plugin, s:enter] = maktaba#plugin#Enter(expand('<sfile>:p'))
- if !s:enter
- finish
- endif
-
- (This prevents re-entry and allows users to selectively disable
- functionality.)
-
- -
- User configuration should be via plugin flags defined in
-
instant/flags.vim
.
-
- -
- Define flags with
-
call s:plugin.Flag('FLAGNAME', DEFAULT_VALUE)
.
-
- -
- Users can configure these flags using the
:Glaive
- command (see glaive).
-
-
-
- -
- Commands, autocommands, mappings, and settings changes should
- occur either in the
plugin/
or the
- ftplugin/
subdirectories.
-
- -
- All commands should be defined in
plugin/commands.vim
- or ftplugin/
files.
-
- -
- Autocommands should be defined in
plugin/autocmds.vim
,
- inside an augroup.
-
- -
- Mappings should be defined in
plugin/mappings.vim
and
- will be disabled unless explicitly enabled by users.
-
- -
- If the plugin configures any standard vim settings, those should be
- configured in
plugin/settings.vim
or
- instant/settings.vim
.
-
-
-
- -
- Avoid using the
after/
subdirectory.
-
- -
-
after/
should be reserved for the user.
-
- -
- It is difficult for the user to add their own overrides when
- plugins use
after/
.
-
-
-
-
-
-
-
- Separate library-providing plugins from command-providing plugins.
-
-
-
- Many plugins provide either user functionality (commands,
- autocommands, etc) or an API (of autoloaded functions) but not both.
- This separation is encouraged, as it allows other plugins to pull in a
- library without also pulling in commands, setting changes, and other
- plugin functionality that affects the end user.
-
-
-
-
-
-
- Don't clobber user settings. Provide as much configurability as
- possible: that's what Vim's all about.
-
-
-
- -
- Use maktaba flags for plugin configuration. Users can configure them
- using the
:Glaive
command.
-
-
- -
- Check if configuration variables exist before setting them.
-
- if !exists('g:myplugin_option')
- let g:myplugin_option = 1
- endif
-
-
-
-
-
-
-
-
- Follow google-wide style conventions. Mimic google python style when
- in doubt.
-
-
-
-
-
-
- Use vimdoc.
-
-
-
- Provide help files generated by
- vimdoc. Write
- documentation in .vim files in conformance with the vimdoc standards
- and include fields like "description" and "author" in the
- addon-info.json file (see the
- VAM documentation).
-
-
-
-
-
-
- Follow google-wide conventions.
-
-
-
- -
- Use two spaces for indents.
-
- -
- Do not use tabs.
-
- -
- Use spaces around operators except for arguments to commands.
-
- -
- Using spaces around operators for commands is often invalid
- syntax. This is inconsistently enforced by vimscript. To be
- safe, always omit whitespace around arguments to commands.
-
- -
-
- let s:variable = "concatenated " . "strings"
- command -range=% MyCommand
-
-
- let s:variable="concatenated "."strings"
- command -range = % MyCommand
-
-
-
-
- -
- Do not introduce trailing whitespace.
-
- -
- You need not go out of your way to remove it.
-
-
-
- -
- Restrict lines to 80 columns wide.
-
- -
- Indent continued lines by two tabs (four spaces).
-
- -
- Do not waste whitespace aligning common segments of similar
- commands. It is both difficult and expensive to maintain.
-
- -
-
- command -bang MyCommand call myplugin#foo()
- command MyCommand2 call myplugin#bar()
-
-
- command -bang MyCommand call myplugin#foo()
- command MyCommand2 call myplugin#bar()
-
-
-
-
-
-
-
- -
- Prefer line continuations on semantic boundaries.
-
- -
-
- command SomeLongCommand
- \ call some#function()
-
-
- command SomeLongCommand call
- \ some#function()
-
-
- -
- Use your best judgement.
-
-
-
- -
- Place one space after the backslash denoting a line continuation.
-
- -
- When continuing a multi-line command a pipe can be substituted
- for this space as necessary, as follows:
-
- autocommand BufEnter <buffer>
- \ if !empty(s:var)
- \| call some#function()
- \|else
- \| call some#function(s:var)
- \|endif
-
-
-
-
- -
- Do not continue multi-line commands when you can avoid it. Prefer
- function calls.
-
-
-
-
-
- -
- Place a space after the
"
before the comment text.
-
- -
-
- " I am a line comment.
- call call(s:my_function)
-
-
-
-
- -
- Do not use inline comments.
-
- -
- Some commands treat them as comments and others as unclosed
- quotes. There are many edge cases. It's difficult to get
- right and difficult to maintain.
-
- -
- Where you would use an inline comment, put a line comment on
- the line above.
-
-
-
- -
- When leaving blank lines in comments, include the quote in the
- blank line.
-
- -
-
- " I am one continuous
- "
- " comment block
-
-
-
-
-
-
-
-
-
-
-
-
- plugin-names-like-this
,
- FunctionNamesLikeThis
,
- CommandNamesLikeThis
,
- augroup_names_like_this
,
- variable_names_like_this
.
-
-
- Prefix all variables with their scope.
-
-
-
-
- -
-
variable_names_like_this
-
- -
- FuncRef variables count as functions and should be named like
- functions.
-
- -
- This (pathological) convention is enforced by vim itself.
-
-
-
- -
- Prefix global variables with
g:
-
- -
- Vimscript allows you to create global variables without
- prefixing them.
-
- -
- It is very bad practice to introduce non-prefixed global
- variables into scope.
-
- -
- Global variables should only be used for plugin configuration.
-
- -
- This does not apply to functions defined in
-
autoload
directories.
-
-
-
- -
- Prefix script-local variables with
s:
-
- -
- This prevents namespace collisions between plugins.
-
- -
- This also applies to script-local functions.
-
-
-
- -
- Prefix function arguments with
a:
-
- -
- This is enforced by vim itself.
-
-
-
- -
- Prefix function-local variables with
l:
-
- -
- This is not enforced by vimscript but is good practice.
-
- -
- It helps you remember that all other variables must be
- prefixed with scope.
-
- -
-
l:
disambiguates between function-local and
- vim-predefined variables. For example, count
- refers to
- v:count
, not l:count
.
-
- -
- It future proofs your scripts against the introduction of new
- vim-predefined variables.
-
-
-
- -
- Prefix pre-defined vim variables with
v:
-
- -
- This is not enforced by vimscript but is good practice.
-
- -
- It provides context as to where the (undeclared) variable is
- coming from.
-
- -
- It reminds you that the variable can not be assigned to.
-
-
-
- -
- Prefix buffer-local variables with
b:
-
- -
- This is useful for plugins that keep per-buffer state.
-
-
-
-
-
-
-
-
-
- Prefer single quotes.
-
-
-
- Prefer single quoted strings. Specifically, in order of precedence:
-
-
- -
- Always use single quotes for regular expressions.
-
- -
-
'\s*'
is not the same as "\s*"
-
- -
- Single quotes will prevent the need for excessive backslashes.
-
- -
- Double single quotes escape to one single quote in single
- quoted strings:
'example ('')'
represents the
- string
- example (')
-
-
-
- -
- If your string requires escape characters (
\n
,
- \t
, etc.) use double quotes.
-
- -
- Escapes can not be expressed in single quoted strings.
-
- -
- Remember that
'\n'
in a regex does not represent a
- newline, but rather "\n". You only need to use double quotes
- when you want to embed the represented character itself (e.g. a
- newline) in the string.
-
-
-
- -
- If your string contains no escapes nor single quotes, use single
- quoted strings.
-
- -
- Most strings in vimscript are regexes, so this provides maximum
- consistency.
-
-
-
- -
- If your non-regex string contains single quotes but no double
- quotes, use double quotes.
-
- -
- Don't bother escaping strings if you don't have to.
-
- -
- This is similar to the python string rules.
-
-
-
- -
- If your string contains both single and double quotes, use whichever
- quoting style requires less escaping.
-
- -
- Break ties in favor of single quotes.
-
-
-
-
-
-
-
-
-
- Prefer long names. Set settings locally.
-
-
-
- -
- Prefer long names of built in settings (i.e.
tabstop
- over
- ts
).
-
- -
- Set local settings unless you explicitly want to set global
- settings.
-
- -
- Use
setlocal
and &l:
instead of
- set
and &
.
-
-
-
-
-
-
-
-
-
- Vim plugins should provide any or all of the following:
- Commands, Autocommands,
- Functions, Statusline Flags, and
- Mappings.
-
-
-
-
-
- - Define in
plugin/commands.vim
.
- - CommandNamesLikeThis.
- - Prefer semantic names to a unified prefix.
- - Do not use
[!]
- - Extract logic into functions.
-
-
-
-
- -
-
CommandNamesLikeThis
-
- -
- Commands should be defined in one block with no whitespace between
- them.
-
- -
- Name commands semantically at the expense of a common prefix.
-
- -
-
- command WhitespaceFixTrailing
- command WhitespaceFixIndentation
-
-
- command FixTrailingWhitespace
- command FixIndentation
-
-
-
-
- -
- Use
command
without a bang.
-
- -
- This notifies users to command name conflicts immediately at
- startup.
-
- -
- Command name collisions are an error and should not fail
- silently.
-
- -
- Plugins are guarded against re-entry, so a single vim session
- should never attempt to re-define defined commands.
-
-
-
- -
- Do not put logic in commands.
-
- -
- Delegate to functions instead.
-
- -
- Pass non-argument command parameters (
<bang>
,
- <register>
, etc.) before argument parameters
- (<f-args>
, etc.).
-
- -
- Otherwise variable-length argument functions are difficult to
- implement.
-
-
-
- -
- Do not autoload commands.
-
- -
- Autoloaded commands will not be available until after a function
- in the same file is called.
-
- -
- Commands intended to be used in the .vimrc should be defined in
- a
instant/commands.vim
file in plugins using
- maktaba, or explicitly installed via an autoload function in
- non-maktaba plugins.
-
-
-
-
-
-
- -
- Pass
<bang>
to functions with
- '<bang>' == '!'
.
-
- -
- The function should receive a boolean parameter, not a string.
-
-
-
-
-
-
-
-
-
-
-
- - Define in
plugin/autocmds.vim
.
- - Use augroups.
- - augroup_names_like_this.
- - Clear the augroup first.
- - Extract logic into functions.
-
-
-
-
- -
- All autocommands should be defined in the
-
plugin/autocmds.vim
file.
-
- -
- This allows users to disable your autocommands with
-
Glaive myplugin !plugin[autocmds]
.
-
-
-
- -
- Declare all autocommands in an
augroup
block.
-
- -
- This allows your autocommands to be cleared with
-
autocmd!
.
-
- -
- If your plugin only has one
augroup
, the
- augroup
name should be the same as your plugin
- name, with underscores in place of any hyphens.
-
- -
- Otherwise
augroup
names should start with your
- plugin name followed by an underscore.
-
-
-
- -
- Do not put logic in autocommands.
-
- -
- Delegate to functions instead.
-
-
-
- -
- When creating a new
augroup
, clear it with
- autocmd!
-
- -
- This allows your plugins to be re-enterable.
-
-
-
-
-
-
-
-
-
-
- - FunctionNamesLikeThis.
- - Autoload all functions.
- - Prefix script-local functions with
s:
- - Use
[!]
.
- - Use
[abort]
.
-
-
-
-
- -
-
FunctionNamesLikeThis
-
- -
- Prefix all script-local functions with
s:
-
- -
- Do not provide global functions. Use autoloaded functions instead.
-
- -
- Place two blank lines between top-level functions.
-
- -
- Declare all functions with
abort
.
-
- -
- If you do not do this, the function's behavior depends upon
- whether it is called within a
try..endtry
block
- somewhere on the stack.
-
- -
- The
abort
keyword forces the function to act
- consistently.
-
- -
- Without it, the function may (or may not) attempt to continue
- execution after an error occurs.
-
-
-
- -
- Use
function!
with a bang.
-
- -
- This allows developers to re-source their scripts and have the
- functions reloaded without complaint.
-
- -
- Function names should never collide because functions should
- always be either script-local or defined in an
-
autoload
directory.
-
- -
- Failing to use a bang in any function in an autoload file will
- lead to cryptic errors if vim tries to re-source the file
- (e.g., if you refer to an nonexistent autoload function).
-
-
-
- -
- Use
...
for optional arguments, not for lists of
- arguments.
-
- -
- Vimscript functions take at most 20 arguments.
-
- -
- Lists have no such length restriction.
-
- -
- Your function is likely to break when given too many arguments
- if you use
...
for a list of arguments.
-
-
-
- -
- Throw exceptions rather than printing errors.
-
- -
- Printed errors can not be caught.
-
- -
- Top-level functions expecting errors may catch them and print
- error messages, but even those should throw their own errors
- when they choke.
-
-
-
-
-
-
-
-
-
-
- -
- Provide opt-in key mappings in
plugin/mappings.vim
.
-
- -
-
<Plug>
mappings can be defined in
- plugin/plugs.vim
(unlike mappings.vim, plugs.vim is
- opt-out).
-
-
-
-
-
- -
- Define key mappings in
plugin/mappings.vim
, using
- maktaba#plugin#MapPrefix
to get a prefix.
-
- -
- Mappings defined in the special
plugin/mappings.vim
- file will be disabled by default (by the standard
- maktaba#plugin#Enter()
boilerplate).
-
- -
- Users can enable key mappings with
-
Glaive myplugin plugin[mappings]
.
-
-
-
- -
- Make all mappings with
<unique>
.
-
- -
- This will inform the user when they have a mapping conflict
- instead of silently clobbering their existing mappings.
-
-
-
- -
- You may provide pseudo-mappings using
<Plug>
and
- your plugin's name in plugin/plugs.vim
(separate from
- standard key mappings).
-
- -
-
<Plug>
is a sequence which can not be typed.
-
- -
- You can do something like
-
noremap <Plug>namespace#MappingName
- some_key_sequence
- and then users can do
- noremap <leader>x
- <Plug>namespace#MappingName
- to take advantage of your pseudo-mapping.
-
- -
- Pseudo-mappings should not be in
-
plugin/mappings.vim
or they will be disabled by
- default.
-
- -
- Such pseudo-mappings should be named
<Plug>
- followed by your plugin name, a pound sign, and a unique mapping
- name (CamelCased like a function).
-
-
-
- -
- Always use the
noremap
family of commands. Never use
- the map
family.
-
- -
-
map
depends upon the user's existing mappings, and
- could do anything.
-
-
-
- -
- Only use
noremap
for commands that both make a motion
- and take a range.
-
- -
-
noremap
makes mappings in normal, visual, and
- operator-pending modes.
-
- -
- If you don't want all these use
nnoremap
- onoremap
or vnoremap
explicitly.
-
-
-
- -
- Always use
<SID>
in place of s:
when
- accessing script locals in mappings.
-
- -
- Using
s:
will often fail as the mapping attempts to
- type a literal s and colon.
-
-
-
-
-
-
-
-
-
-
- Declare dependencies in addon-info.json and use maktaba
.
-
-
-
- Declaring dependencies in addon-info.json allows conformant plugin
- managers (like VAM) to ensure dependencies are installed. See the
- VAM documentation for details.
-
-
- Calling maktaba#library#Require
from dependent code at
- runtime ensures that dependencies have been installed and that they
- don't include unsafe non-library files.
-
-
-
-
-
-
- Use <plugin-name>#status#Status()
or its
- finer-grained variants to provide statusline flags.
-
-
-
- Following is a convention for exposing statusline flags to the user. A
- plugin should never modify the user's statusline except for when that
- is the only purpose of the plugin (powerline, etc.).
-
-
- -
- Provide the
-
Info
,
- Alert
,
- Warning
, and
- Error
functions under the
- <plugin-name>#status
namespace.
-
- -
-
Info
should provide information about the
- state of the buffer.
-
- -
- Example: The current git branch.
-
-
-
- -
-
Alert
should provide a quiet reminder
- that the buffer is non-standard.
-
- -
- Example: The readonly setting is on.
-
-
-
- -
-
Warning
should provide a warning about
- the current state of the buffer.
-
- -
- Example: The file has been edited elsewhere.
-
-
-
- -
-
Error
should bring to attention a loud
- issue with the buffer.
-
- -
- Example: The file does not pass the syntax checker.
-
-
-
- -
- By following these conventions, users can easily build up their own
- statusline customizing the verbosity and colors to their tastes.
-
- -
- All functions should take no arguments and should return either
- empty strings or strings enclosed by square brackets, e.g.
-
[Google]
. For example:
-
- -
- A trailing whitespace plugin might return
[$]
if
- the file contains trailing whitespace
-
- -
- A prose writing plugin might return
[write]
if vim
- is in writing mode.
-
-
-
- -
- Consider providing the
-
<plugin-name>#status#Status
function.
-
- -
- It should return the first non-empty of
Error
,
- Warning
, Alert
, or Info
.
-
- -
- This is useful for users who want only the most relevant flag
- and do not have a colored statusline.
-
-
-
-
-
-
-
-
-
- These are commands which can only be used by a limited number of
- plugins, and should not in general be used by yours.
-
-
- -
- Do not use
:match :2match
or :3match
-
- -
- These are reserved for the user and for vim itself.
-
- -
- Use
matchadd()
to create a matchlevel unique to your
- plugin.
-
-
-
- -
- Do not use
echoerr
.
-
- -
-
echoerr
does not print the red error message that you
- might think it does.
-
- -
-
echoerr
prints an error message as well as context
- about the code where echoerr
was called.
-
- -
-
echoerr
is best suited for debugging.
-
- -
- Use
echohl
in tandem with echomsg
if
- you want the red error bar.
-
-
-
- -
- Use
echomsg
instead of echo
.
-
- -
-
echomsg
messages can be reviewed with the
- :messages
command.
-
- -
-
echo
messages disappear permanently on redraw, which
- can be very annoying to users who failed to read the message in
- time.
-
-
-
-
-
-
-
- Lay out plugin/
files in the following sections, if
- applicable, separated by two blank lines:
-
-
- -
- Declaration of script constants
-
- -
- Declaration of configuration variables
-
- -
- Other declarations (commands in
commands.vim
file,
- autocommands in autocmds.vim
file, etc.)
-
-
-
- Lay out autoload/
files in the following sections, if
- applicable, separated by two blank lines:
-
-
- -
-
maktaba#library#Require
calls
-
- -
- Script-local variables
-
- -
- Script-local functions
-
- -
- Private autoloaded functions
-
- -
- Public autoloaded functions
-
-
-
- This is recommended convention and is not enforced.
-
-
-
-
-
-
- Use the following shortcuts:
-
-
- -
-
catch
over catch /.*/
-
- -
-
return
over return 0
when the return value
- has no semantic purpose.
-
-
-
-
-
-
- This section plumbs some of the darker corners of vimscript, explaining
- the language pathologies that you wish you didn't have to know.
-
-
-
-
-
- If you don't support vi-compatibility mode, fail gracefully.
-
-
-
- When compatible
is set, many vim features are not
- available. The vim feature which most commonly affects vimscript
- authors is line continuations.
-
-
- If you want your plugin to work in vim with vi compatibility on, you
- will need to save the compatibility options at the beginning of each
- plugin file, clear them, and restore them at the end of each plugin
- file. See :help use-cpo-save
for details.
-
-
- Plugins that depend on maktaba generally don't need to worry about
- compatible mode since maktaba currently just disables it, printing a
- warning.
-
-
-
-
-
-
- Revision 1.1
-
-
-
-
- Nate Soares
- Joshua Hoak
- David Barnett
-
-
diff --git a/vimscriptguide.asciidoc b/vimscriptguide.asciidoc
new file mode 100644
index 0000000..d9e4909
--- /dev/null
+++ b/vimscriptguide.asciidoc
@@ -0,0 +1,333 @@
+= Google Vimscript Style Guide
+
+:sectlinks:
+
+Revision 1.1
+
+Nate Soares +
+ Joshua Hoak +
+ David Barnett +
+
+
+
+
+
+Table of Contents
+
+[width="100%",cols="50%,50%",]
+|=================================================================================================================================================================================================================================================================================================================================
+a|
+link:#portability[Portability]
+
+ a|
+link:#strings[Strings] link:#matching-strings[Matching Strings] link:#regular-expressions[Regular Expressions] link:#dangerous-commands[Dangerous commands] link:#fragile-commands[Fragile commands] link:#catching-exceptions[Catching Exceptions]
+
+a|
+link:#general-guidelines[General Guidelines]
+
+ a|
+link:#messaging[Messaging] link:#type-checking[Type checking] link:#python[Python] link:#other-languages[Other Languages] link:#boilerplate[Boilerplate] link:#plugin-layout[Plugin layout] link:#functions[Functions] link:#commands[Commands] link:#autocommands[Autocommands] link:#mappings[Mappings] link:#settings[Settings]
+
+a|
+link:#style[Style]
+
+ a|
+link:#whitespace[Whitespace] link:#naming[Naming]
+
+|=================================================================================================================================================================================================================================================================================================================================
+
+[[Background]]
+== Background
+
+This is a casual version of the vimscript style guide, because vimscript is a casual language. When submitting vim plugin code, you must adhere to these rules. For clarifications, justifications, and explanations about the finer points of vimscript, please refer to the link:vimscriptfull.xml[heavy guide].
+
+[[Portability]]
+== Portability
+
+It's hard to get vimscript right. Many commands depend upon the user's settings. By following these guidelines, you can hope to make your scripts portable.
+
+=== Strings
+
+
+
+Prefer single quoted strings
+
+Double quoted strings are semantically different in vimscript, and you probably don't want them (they break regexes).
+
+Use double quoted strings when you need an escape sequence (such as `"\n"`) or if you know it doesn't matter and you need to embed single quotes.
+
+=== Matching Strings
+
+
+
+Use the `=~#` or `=~?` operator families over the `=~` family.
+
+The matching behavior depends upon the user's ignorecase and smartcase settings and on whether you compare them with the `=~`, `=~#`, or `=~?` family of operators. Use the `=~#` and `=~?` operator families explicitly when comparing strings unless you explicitly need to honor the user's case sensitivity settings.
+
+=== Regular Expressions
+
+
+
+Prefix all regexes with `\m\C`.
+
+In addition to the case sensitivity settings, regex behavior depends upon the user's nomagic setting. To make regexes act like nomagic and noignorecase are set, prepend all regexes with `\m\C`.
+
+You are welcome to use other magic levels (`\v`) and case sensitivities (`\c`) so long as they are intentional and explicit.
+
+=== Dangerous commands
+
+
+
+Avoid commands with unintended side effects.
+
+Avoid using `:s[ubstitute]` as it moves the cursor and prints error messages. Prefer functions (such as `search()`) better suited to scripts.
+
+For many vim commands, functions exist that do the same thing with fewer side effects. See `:help functions()` for a list of built-in functions.
+
+=== Fragile commands
+
+
+
+Avoid commands that rely on user settings.
+
+Always use `normal!` instead of `normal`. The latter depends upon the user's key mappings and could do anything.
+
+Avoid `:s[ubstitute]`, as its behavior depends upon a number of local settings.
+
+The same applies to other commands not listed here.
+
+=== Catching Exceptions
+
+
+
+Match error codes, not error text.
+
+Error text may be locale dependant.
+
+[[General_Guidelines]]
+== General Guidelines
+
+=== Messaging
+
+
+
+Message the user infrequently.
+
+Loud scripts are annoying. Message the user only when:
+
+
+* A long-running process has kicked off.
+
+* An error has occurred.
+
+=== Type checking
+
+
+
+Use strict and explicit checks where possible.
+
+Vimscript has unsafe, unintuitive behavior when dealing with some types. For instance, `0 == 'foo'` evaluates to true.
+
+Use strict comparison operators where possible. When comparing against a string literal, use the `is#` operator. Otherwise, prefer `maktaba#value#IsEqual` or check `type()` explicitly.
+
+Check variable types explicitly before using them. Use functions from `maktaba#ensure`, or check `maktaba#value` or `type()` and throw your own errors.
+
+Use `:unlet` for variables that may change types, particularly those assigned inside loops.
+
+=== Python
+
+
+
+Use sparingly.
+
+Use python only when it provides critical functionality, for example when writing threaded code.
+
+=== Other Languages
+
+
+
+Use vimscript instead.
+
+Avoid using other scripting languages such as ruby and lua. We can not guarantee that the end user's vim has been compiled with support for non-vimscript languages.
+
+=== Boilerplate
+
+
+
+Use https://github.com/google/maktaba[maktaba].
+
+maktaba removes boilerplate, including:
+
+
+* Plugin creation
+
+* Error handling
+
+* Dependency checking
+
+=== Plugin layout
+
+
+
+Organize functionality into modular plugins
+
+Group your functionality as a plugin, unified in one directory (or code repository) which shares your plugin's name (with a "vim-" prefix or ".vim" suffix if desired). It should be split into plugin/, autoload/, etc. subdirectories as necessary, and it should declare metadata in the addon-info.json format (see the http://goo.gl/CUXJZC[VAM documentation] for details).
+
+=== Functions
+
+
+
+In the autoload/ directory, defined with `[!]` and `[abort]`.
+
+Autoloading allows functions to be loaded on demand, which makes startuptime faster and enforces function namespacing.
+
+Script-local functions are welcome, but should also live in autoload/ and be called by autoloaded functions.
+
+Non-library plugins should expose commands instead of functions. Command logic should be extracted into functions and autoloaded.
+
+`[!]` allows developers to reload their functions without complaint.
+
+`[abort]` forces the function to halt when it encounters an error.
+
+=== Commands
+
+
+
+In the plugin/commands.vim or under the ftplugin/ directory, defined without `[!]`.
+
+General commands go in `plugin/commands.vim`. Filetype-specific commands go in `ftplugin/`.
+
+Excluding `[!]` prevents your plugin from silently clobbering existing commands. Command conflicts should be resolved by the user.
+
+=== Autocommands
+
+
+
+Place them in plugin/autocmds.vim, within augroups.
+
+Place all autocommands in augroups.
+
+The augroup name should be unique. It should either be, or be prefixed with, the plugin name.
+
+Clear the augroup with `autocmd!` before defining new autocommands in the augroup. This makes your plugin re-entrable.
+
+=== Mappings
+
+
+
+Place them in `plugin/mappings.vim`, using `maktaba#plugin#MapPrefix` to get a prefix.
+
+All key mappings should be defined in `plugin/mappings.vim`.
+
+Partial mappings (see :help using-.) should be defined in `plugin/plugs.vim`.
+
+=== Settings
+
+
+
+Change settings locally
+
+Use `:setlocal` and `&l:` instead of `:set` and `&` unless you have explicit reason to do otherwise.
+
+[[Style]]
+== Style
+
+Follow google style conventions. When in doubt, treat vimscript style like python style.
+
+=== Whitespace
+
+
+
+Similar to python. +
+ +
+
+
+* Use two spaces for indents
+
+* Do not use tabs
+
+* Use spaces around operators
++
+This does not apply to arguments to commands.
++
+--------------------------------------------
+let s:variable = "concatenated " . "strings"
+command -range=% MyCommand
+--------------------------------------------
+
+* Do not introduce trailing whitespace
++
+You need not go out of your way to remove it.
++
+Trailing whitespace is allowed in mappings which prep commands for user input, such as "`noremap gf :grep -f `".
+
+* Restrict lines to 80 columns wide
+
+* Indent continued lines by four spaces
+
+* Do not align arguments of commands
++
+--------------------------------------------
+command -bang MyCommand call myplugin#foo()
+command MyCommand2 call myplugin#bar()
+--------------------------------------------
++
+-------------------------------------------
+command -bang MyCommand call myplugin#foo()
+command MyCommand2 call myplugin#bar()
+-------------------------------------------
+
+=== Naming
+
+
+
+In general, use `plugin-names-like-this`, `FunctionNamesLikeThis`, `CommandNamesLikeThis`, `augroup_names_like_this`, `variable_names_like_this`.
+
+Always prefix variables with their scope.
+
+plugin-names-like-this
+
+Keep them short and sweet.
+
+FunctionNamesLikeThis
+
+Prefix script-local functions with `s:`
+
+Autoloaded functions may not have a scope prefix.
+
+Do not create global functions. Use autoloaded functions instead.
+
+CommandNamesLikeThis
+
+Prefer succinct command names over common command prefixes.
+
+variable_names_like_this
+
+Augroup names count as variables for naming purposes.
+
+Prefix all variables with their scope.
+
+
+* Global variables with `g:`
+
+* Script-local variables with `s:`
+
+* Function arguments with `a:`
+
+* Function-local variables with `l:`
+
+* Vim-predefined variables with `v:`
+
+* Buffer-local variables with `b:`
+
+`g:`, `s:`, and `a:` must always be used.
+
+`b:` changes the variable semantics; use it when you want buffer-local semantics.
+
+`l:` and `v:` should be used for consistency, future proofing, and to avoid subtle bugs. They are not strictly required. Add them in new code but don’t go out of your way to add them elsewhere.
+
+Revision 1.1
+
+Nate Soares +
+ Joshua Hoak +
+ David Barnett +
diff --git a/vimscriptguide.xml b/vimscriptguide.xml
deleted file mode 100644
index d16a3d7..0000000
--- a/vimscriptguide.xml
+++ /dev/null
@@ -1,412 +0,0 @@
-
-
-
-
-
- Revision 1.1
-
-
-
-
- Nate Soares
- Joshua Hoak
- David Barnett
-
-
-
-
-
- This is a casual version of the vimscript style guide, because
- vimscript is a casual language. When submitting vim plugin code, you
- must adhere to these rules. For clarifications, justifications, and
- explanations about the finer points of vimscript, please refer to the
- heavy guide.
-
-
-
-
-
-
- It's hard to get vimscript right. Many commands depend upon the user's
- settings. By following these guidelines, you can hope to make your
- scripts portable.
-
-
- Prefer single quoted strings
-
-
- Double quoted strings are semantically different in vimscript, and
- you probably don't want them (they break regexes).
-
-
- Use double quoted strings when you need an escape sequence (such as
- "\n"
) or if you know it doesn't matter and you need to
- embed single quotes.
-
-
-
-
-
- Use the =~#
or =~?
operator families over the
- =~
family.
-
-
-
- The matching behavior depends upon the user's ignorecase and smartcase
- settings and on whether you compare them with the =~
,
- =~#
, or =~?
family of operators. Use the
- =~#
and =~?
operator families explicitly
- when comparing strings unless you explicitly need to honor the user's
- case sensitivity settings.
-
-
-
-
- Prefix all regexes with \m\C
.
-
-
- In addition to the case sensitivity settings, regex behavior depends
- upon the user's nomagic setting. To make regexes act like nomagic and
- noignorecase are set, prepend all regexes with \m\C
.
-
-
- You are welcome to use other magic levels (\v
) and case
- sensitivities (\c
) so long as they are intentional and
- explicit.
-
-
-
-
- Avoid commands with unintended side effects.
-
-
- Avoid using :s[ubstitute]
as it moves the cursor and
- prints error messages. Prefer functions (such as
- search()
) better suited to scripts.
-
-
- For many vim commands, functions exist that do the same thing with
- fewer side effects. See :help functions()
for a list of
- built-in functions.
-
-
-
-
- Avoid commands that rely on user settings.
-
-
- Always use normal!
instead of normal
. The
- latter depends upon the user's key mappings and could do anything.
-
-
- Avoid :s[ubstitute]
, as its behavior depends upon a
- number of local settings.
-
-
- The same applies to other commands not listed here.
-
-
-
-
- Match error codes, not error text.
-
- Error text may be locale dependant.
-
-
-
-
-
-
-
-
- Message the user infrequently.
-
-
- Loud scripts are annoying. Message the user only when:
-
- - A long-running process has kicked off.
- - An error has occurred.
-
-
-
-
-
- Use strict and explicit checks where possible.
-
-
- Vimscript has unsafe, unintuitive behavior when dealing with some
- types. For instance, 0 == 'foo'
evaluates to true.
-
-
- Use strict comparison operators where possible. When comparing against
- a string literal, use the is#
operator. Otherwise, prefer
- maktaba#value#IsEqual
or check type()
- explicitly.
-
-
- Check variable types explicitly before using them. Use functions from
- maktaba#ensure
, or check maktaba#value
or
- type()
and throw your own errors.
-
-
- Use :unlet
for variables that may change types,
- particularly those assigned inside loops.
-
-
-
-
- Use sparingly.
-
-
- Use python only when it provides critical functionality, for example
- when writing threaded code.
-
-
-
-
- Use vimscript instead.
-
-
- Avoid using other scripting languages such as ruby and lua. We can
- not guarantee that the end user's vim has been compiled with support
- for non-vimscript languages.
-
-
-
-
-
- Use maktaba.
-
-
-
- maktaba removes boilerplate, including:
-
- - Plugin creation
- - Error handling
- - Dependency checking
-
-
-
-
-
- Organize functionality into modular plugins
-
-
- Group your functionality as a plugin, unified in one directory (or
- code repository) which shares your plugin's name (with a "vim-" prefix
- or ".vim" suffix if desired). It should be split into plugin/,
- autoload/, etc. subdirectories as necessary, and it should declare
- metadata in the addon-info.json format (see the
- VAM documentation for details).
-
-
-
-
-
- In the autoload/ directory, defined with [!]
and
- [abort]
.
-
-
-
- Autoloading allows functions to be loaded on demand, which makes
- startuptime faster and enforces function namespacing.
-
-
- Script-local functions are welcome, but should also live in autoload/
- and be called by autoloaded functions.
-
-
- Non-library plugins should expose commands instead of functions.
- Command logic should be extracted into functions and autoloaded.
-
-
- [!]
allows developers to reload their functions
- without complaint.
-
-
- [abort]
forces the function to halt when it encounters
- an error.
-
-
-
-
-
- In the plugin/commands.vim or under the ftplugin/ directory, defined
- without [!]
.
-
-
-
- General commands go in plugin/commands.vim
.
- Filetype-specific commands go in ftplugin/
.
-
-
- Excluding [!]
prevents your plugin from silently
- clobbering existing commands. Command conflicts should be resolved by
- the user.
-
-
-
-
-
- Place them in plugin/autocmds.vim, within augroups.
-
-
-
- Place all autocommands in augroups.
-
-
- The augroup name should be unique. It should either be, or be prefixed
- with, the plugin name.
-
-
- Clear the augroup with autocmd!
before defining new
- autocommands in the augroup. This makes your plugin re-entrable.
-
-
-
-
-
- Place them in plugin/mappings.vim
, using
- maktaba#plugin#MapPrefix
to get a prefix.
-
-
-
- All key mappings should be defined in
- plugin/mappings.vim
.
-
-
- Partial mappings (see :help using-<Plug>.) should be defined in
- plugin/plugs.vim
.
-
-
-
-
- Change settings locally
-
-
- Use :setlocal
and &l:
instead of
- :set
and &
unless you have explicit
- reason to do otherwise.
-
-
-
-
-
-
-
- Follow google style conventions. When in doubt, treat vimscript style
- like python style.
-
-
-
-
- Similar to python.
-
-
-
-
-
-
- - Use two spaces for indents
- - Do not use tabs
- - Use spaces around operators
-
This does not apply to arguments to commands.
-
- let s:variable = "concatenated " . "strings"
- command -range=% MyCommand
-
-
- - Do not introduce trailing whitespace
-
You need not go out of your way to remove it.
-
- Trailing whitespace is allowed in mappings which prep commands
- for user input, such as
- "noremap <leader>gf :grep -f
".
-
-
- - Restrict lines to 80 columns wide
- - Indent continued lines by four spaces
- - Do not align arguments of commands
-
- command -bang MyCommand call myplugin#foo()
- command MyCommand2 call myplugin#bar()
-
-
- command -bang MyCommand call myplugin#foo()
- command MyCommand2 call myplugin#bar()
-
-
-
-
-
-
-
-
-
- In general, use
- plugin-names-like-this
,
- FunctionNamesLikeThis
,
- CommandNamesLikeThis
,
- augroup_names_like_this
,
- variable_names_like_this
.
-
- Always prefix variables with their scope.
-
-
-
- Keep them short and sweet.
-
-
-
- Prefix script-local functions with s:
- Autoloaded functions may not have a scope prefix.
-
- Do not create global functions. Use autoloaded functions
- instead.
-
-
-
- Prefer succinct command names over common command prefixes.
-
-
- Augroup names count as variables for naming purposes.
-
-
-
- - Global variables with
g:
- - Script-local variables with
s:
- - Function arguments with
a:
- - Function-local variables with
l:
- - Vim-predefined variables with
v:
- - Buffer-local variables with
b:
-
-
- g:
, s:
, and a:
must always
- be used.
-
-
- b:
changes the variable semantics; use it when you
- want buffer-local semantics.
-
-
- l:
and v:
should be used for consistency,
- future proofing, and to avoid subtle bugs. They are not strictly
- required. Add them in new code but don’t go out of your way to add
- them elsewhere.
-
-
-
-
-
-
-
- Revision 1.1
-
-
-
-
- Nate Soares
- Joshua Hoak
- David Barnett
-
-
diff --git a/xmlstyle.asciidoc b/xmlstyle.asciidoc
new file mode 100644
index 0000000..f6294b2
--- /dev/null
+++ b/xmlstyle.asciidoc
@@ -0,0 +1,174 @@
+= Google XML Document Format Style Guide
+
+:sectlinks:
+
+Version 1.0 Copyright Google 2008
+
+== Introduction
+
+This document provides a set of guidelines for general use when designing new XML document formats (and to some extent XML documents as well; see Section 11). Document formats usually include both formal parts (DTDs, schemas) and parts expressed in normative English prose. These guidelines apply to new designs, and are not intended to force retroactive changes in existing designs. When participating in the creation of public or private document format designs, the guidelines may be helpful but should not control the group consensus. This guide is meant for the design of XML that is to be generated and consumed by machines rather than human beings. Its rules are _not applicable_ to formats such as XHTML (which should be formatted as much like HTML as possible) or ODF which are meant to express rich text. A document that includes embedded content in XHTML or some other rich-text format, but also contains purely machine-interpretable portions, SHOULD follow this style guide for the machine-interpretable portions. It also does not affect XML document formats that are created by translations from proto buffers or through some other type of format. Brief rationales have been added to most of the guidelines. They are maintained in the same document in hopes that they won't get out of date, but they are not considered normative. The terms MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are used in this document in the sense of http://www.ietf.org/rfc/rfc2119.txt[RFC 2119.]
+
+== To design or not to design, that is the question
+
+1. Attempt to reuse existing XML formats whenever possible, especially those which allow extensions. Creating an entirely new format should be done only with care and consideration; read http://www.tbray.org/ongoing/When/200x/2006/01/08/No-New-XML-Languages[Tim Bray's warnings] first. Try to get wide review of your format, from outside your organization as well, if possible. [__Rationale:__ New document formats have a cost: they must be reviewed, documented, and learned by users.]
+2. If you are reusing or extending an existing format, make _sensible_ use of the prescribed elements and attributes, especially any that are required. Don't completely repurpose them, but do try to see how they might be used in creative ways if the vanilla semantics aren't suitable. As a last resort when an element or attribute is required by the format but is not appropriate for your use case, use some fixed string as its value. [__Rationale:__ Markup reuse is good, markup abuse is bad.]
+3. When extending formats, use the implicit style of the existing format, even if it contradicts this guide. [__Rationale:__ Consistency.]
+
+== Schemas
+
+1. Document formats SHOULD be expressed using a schema language. [__Rationale:__ Clarity and machine-checkability.]
+2. The schema language SHOULD be http://www.relaxng.org/[RELAX NG] http://www.relaxng.org/compact-tutorial-20030326.html[compact syntax]. Embedded http://www.schematron.com/[Schematron] rules MAY be added to the schema for additional fine control. [__Rationale:__ RELAX NG is the most flexible schema language, with very few arbitrary restrictions on designs. The compact syntax is quite easy to read and learn, and can be converted one-to-one to and from the XML syntax when necessary. Schematron handles arbitrary cross-element and cross-attribute constraints nicely.]
+3. Schemas SHOULD use the http://www.xfront.com/GlobalVersusLocal.html#SecondDesign["Salami Slice" style] (one rule per element). Schemas MAY use the http://www.xfront.com/GlobalVersusLocal.html#FirstDesign["Russian Doll" style] (schema resembles document) if they are short and simple. The http://www.xfront.com/GlobalVersusLocal.html#ThirdDesign["Venetian Blind" style] (one rule per element type) is unsuited to RELAX NG and SHOULD NOT be used.
+4. Regular expressions SHOULD be provided to assist in validating complex values.
+5. DTDs and/or W3C XML Schemas MAY be provided for compatibility with existing products, tools, or users. [__Rationale:__ We can't change the world all at once.]
+
+== Namespaces
+
+1. Element names MUST be in a namespace, except when extending pre-existing document types that do not use namespaces. A default namespace SHOULD be used. [__Rationale:__ Namespace-free documents are obsolete; every set of names should be in some namespace. Using a default namespace improves readability.]
+2. Attribute names SHOULD NOT be in a namespace unless they are drawn from a foreign document type or are meant to be used in foreign document types. [__Rationale:__ Attribute names in a namespace must always have a prefix, which is annoying to type and hard to read.]
+3. Namespace names are HTTP URIs. Namespace names SHOULD take the form http://example.com/__whatever__/__year,__ where _whatever_ is a unique value based on the name of the document type, and _year_ is the year the namespace was created. There may be additional URI-path parts before the _year._ [__Rationale:__ Existing convention. Providing the year allows for the possible recycling of code names.]
+4. Namespaces MUST NOT be changed unless the semantics of particular elements or attributes has changed in drastically incompatible ways. [__Rationale:__ Changing the namespace requires changing all client code.]
+5. Namespace prefixes SHOULD be short (but not so short that they are likely to be conflict with another project). Single-letter prefixes MUST NOT be usedPrefixes SHOULD contain only lower-case ASCII letters. [__Rationale:__ Ease of typing and absence of encoding compatibility problems.]
+
+== Names and enumerated values
+
+*Note:* "Names" refers to the names of elements, attributes, and enumerated values.
+
+1. All names MUST use lowerCamelCaseThat is, they start with an initial lower-case letter, then each new word within the name starts with an initial capital letter[__Rationale:__ Adopting a single style provides consistency, which helps when referring to names since the capitalization is known and so does not have to be remembered. It matches Java style, and other languages can be dealt with using automated name conversion.]
+2. Names MUST contain only ASCII letters and digits. [__Rationale:__ Ease of typing and absence of encoding compatibility problems.]
+3. Names SHOULD NOT exceed 25 charactersLonger names SHOULD be avoided by devising concise and informative names. If a name can only remain within this limit by becoming obscure, the limit SHOULD be ignored. [__Rationale:__ Longer names are awkward to use and require additional bandwidth.]
+4. Published standard abbreviations, if sufficiently well-known, MAY be employed in constructing namesAd hoc abbreviations MUST NOT be used. Acronyms MUST be treated as words for camel-casing purposes: informationUri, not informationURI[__Rationale:__ An abbreviation that is well known to one community is often incomprehensible to others who need to use the same document format (and who do understand the full name); treating an acronym as a word makes it easier to see where the word boundaries are.]
+
+== Elements
+
+1. All elements MUST contain either nothing, character content, or child elements. Mixed content MUST NOT be used. [__Rationale:__ Many XML data models don't handle mixed content properly, and its use makes the element order-dependent. As always, textual formats are not covered by this rule.]
+2. XML elements that merely wrap repeating child elements SHOULD NOT be used. [__Rationale:__ They are not used in Atom and add nothing.]
+
+== Attributes
+
+1. Document formats MUST NOT depend on the order of attributes in a start-tag. [__Rationale:__ Few XML parsers report the order, and it is not part of the XML Infoset.]
+2. Elements SHOULD NOT be overloaded with too many attributes (no more than 10 as a rule of thumb). Instead, use child elements to encapsulate closely related attributes. [__Rationale:__ This approach maintains the built-in extensibility that XML provides with elements, and is useful for providing forward compatibility as a specification evolves.]
+3. Attributes MUST NOT be used to hold values in which line breaks are significant. [__Rationale:__ Such line breaks are converted to spaces by conformant XML parsers.]
+4. Document formats MUST allow either single or double quotation marks around attribute values. [__Rationale:__ XML parsers don't report the difference.]
+
+== Values
+
+1. Numeric values SHOULD be 32-bit signed integers, 64-bit signed integers, or 64-bit IEEE doubles, all expressed in base 10. These correspond to the XML Schema types xsd:int, xsd:long, and xsd:double respectively. If required in particular cases, xsd:integer (unlimited-precision integer) values MAY also be used. [__Rationale:__ There are far too many numeric types in XML Schema: these provide a reasonable subset.]
+2. Boolean values SHOULD NOT be used (use enumerations instead). If they must be used, they MUST be expressed as true or false, corresponding to a subset of the XML Schema type xsd:boolean. The alternative xsd:boolean values 1 and 0 MUST NOT be used. [__Rationale:__ Boolean arguments are not extensible. The additional flexibility of allowing numeric values is not abstracted away by any parser.]
+3. Dates should be represented using http://www.ietf.org/rfc/rfc3339.txt[RFC 3339] format, a subset of both ISO 8601 format and XML Schema xsd:dateTime format. UTC times SHOULD be used rather than local times. [__Rationale:__ There are far too many date formats and time zones, although it is recognized that sometimes local time preserves important information.]
+4. Embedded syntax in character content and attribute values SHOULD NOT be used. Syntax in values means XML tools are largely useless. Syntaxes such as dates, URIs, and XPath expressions are exceptions. [__Rationale:__ Users should be able to process XML documents using only an XML parser without requiring additional special-purpose parsers, which are easy to get wrong.]
+5. Be careful with whitespace in values. XML parsers don't strip whitespace in elements, but do convert newlines to spaces in attributes. However, application frameworks may do more aggressive whitespace stripping. Your document format SHOULD give rules for whitespace stripping.
+
+== Key-value pairs
+
+1. Simple key-value pairs SHOULD be represented with an empty element whose name represents the key, with the value attribute containing the valueElements that have a value attribute MAY also have a unit attribute to specify the unit of a measured value. For physical measurements, the http://en.wikipedia.org/wiki/International_System_of_Units[SI system] SHOULD be used. [__Rationale:__ Simplicity and design consistency. Keeping the value in an attribute hides it from the user, since displaying just the value without the key is not useful.]
+2. If the number of possible keys is very large or unbounded, key-value pairs MAY be represented by a single generic element with key, value, and optional unit and scheme attributes (which serve to discriminate keys from different domains). In that case, also provide (not necessarily in the same document) a list of keys with human-readable explanations.
+
+== Binary data
+
+*Note:* There are no hard and fast rules about whether binary data should be included as part of an XML document or not. If it's too large, it's probably better to link to it.
+
+1. Binary data MUST NOT be included directly as-is in XML documents, but MUST be encoded using Base64 encoding. [__Rationale:__ XML does not allow arbitrary binary bytes.]
+2. The line breaks required by Base64 MAY be omitted. [__Rationale:__ The line breaks are meant to keep plain text lines short, but XML is not really plain text.]
+3. An attribute named xsi:type with value xs:base64Binary MAY be attached to this element to signal that the Base64 format is in use. [Rationale: Opaque blobs should have decoding instructions attached.]
+
+== Processing instructions
+
+1. New processing instructions MUST NOT be created except in order to specify purely local processing conventions, and SHOULD be avoided altogether. Existing standardized processing instructions MAY be used. [__Rationale:__ Processing instructions fit awkwardly into XML data models and can always be replaced by elements; they exist primarily to avoid breaking backward compatibility.]
+
+== Representation of XML document instances
+
+*Note:* These points are only guidelines, as the format of program-created instances will often be outside the programmer's control (for example, when an XML serialization library is being used). _In no case_ should XML parsers rely on these guidelines being followed. Use standard XML parsers, not hand-rolled hacks.
+
+1. The character encoding used SHOULD be UTF-8. Exceptions should require extremely compelling circumstances. [__Rationale:__ UTF-8 is universal and in common use.]
+2. Namespaces SHOULD be declared in the root element of a document wherever possible. [__Rationale:__ Clarity and consistency.]
+3. The mapping of namespace URIs to prefixes SHOULD remain constant throughout the document, and SHOULD also be used in documentation of the design. [__Rationale:__ Clarity and consistency.]
+4. Well-known prefixes such as html: (for XHTML), dc: (for Dublin Core metadata), and xs: (for XML Schema) should be used for standard namespaces. [__Rationale:__ Human readability.]
+5. Redundant whitespace in a tag SHOULD NOT be used. Use one space before each attribute in a start-tag; if the start tag is too long, the space MAY be replaced by a newline. [__Rationale:__ Consistency and conciseness.]
+6. Empty elements MAY be expressed as empty tags or a start-tag immediately followed by an end-tagNo distinction should be made between these two formats by any application. [__Rationale:__ They are not distinguished by XML parsers.]
+7. Documents MAY be pretty-printed using 2-space indentation for child elements. Elements that contain character content SHOULD NOT be wrapped. Long start-tags MAY be broken using newlines (possibly with extra indentation) after any attribute value except the last. [__Rationale:__ General compatibility with our style. Wrapping character content affects its value.]
+8. Attribute values MAY be surrounded with either quotation marks or apostrophes. Specifications MUST NOT require or forbid the use of either form. ' and " may be freely used to escape each type of quote. [__Rationale:__ No XML parsers report the distinction.]
+9. Comments MUST NOT be used to carry real data. Comments MAY be used to contain TODOs in hand-written XML. Comments SHOULD NOT be used at all in publicly transmitted documents[__Rationale:__ Comments are often discarded by parsers.]
+10. If comments are nevertheless used, they SHOULD appear only in the document prolog or in elements that contain child elements. If pretty-printing is required, pretty-print comments like elements, but with line wrapping. Comments SHOULD NOT appear in elements that contain character content. [__Rationale:__ Whitespace in and around comments improves readability, but embedding a comment in character content can lead to confusion about what whitespace is or is not in the content.]
+11. Comments SHOULD have whitespace following . [__Rationale:__ Readability.]
+12. CDATA sections MAY be used; they are equivalent to the use of & and <. Specifications MUST NOT require or forbid the use of CDATA sections. [__Rationale:__ Few XML parsers report the distinction, and combinations of CDATA and text are often reported as single objects anyway.]
+13. Entity references other than the XML standard entity references &, <, >, ", and ' MUST NOT be used. Character references MAY be used, but actual characters are preferred, unless the character encoding is not UTF-8. As usual, textual formats are exempt from this rule.
+
+== Elements vsAttributes
+
+*Note:* There are no hard and fast rules for deciding when to use attributes and when to use elements. Here are some of the considerations that designers should take into account; no rationales are given.
+
+=== 12.General points:
+
+1. Attributes are more restrictive than elements, and all designs have some elements, so an all-element design is simplest -- which is not the same as best.
++
+2. In a tree-style data model, elements are typically represented internally as nodes, which use more memory than the strings used to represent attributes. Sometimes the nodes are of different application-specific classes, which in many languages also takes up memory to represent the classes.
++
+3. When streaming, elements are processed one at a time (possibly even piece by piece, depending on the XML parser you are using), whereas all the attributes of an element and their values are reported at once, which costs memory, particularly if some attribute values are very long.
++
+4. Both element content and attribute values need to be escaped appropriately, so escaping should not be a consideration in the design.
++
+5. In some programming languages and libraries, processing elements is easier; in others, processing attributes is easier. Beware of using ease of processing as a criterion. In particular, XSLT can handle either with equal facility.
++
+6. If a piece of data should usually be shown to the user, consider using an element; if not, consider using an attribute. (This rule is often violated for one reason or another.)
++
+7. If you are extending an existing schema, do things by analogy to how things are done in that schema.
++
+8. Sensible schema languages, meaning RELAX NG and Schematron, treat elements and attributes symmetrically. Older and cruderhttp://www.w3.org/TR/2004/REC-xmlschema-0-20041028/[]schema languages such as DTDs and XML Schema, tend to have better support for elements.
+
+=== 12.2 Using elements
+
+1. If something might appear more than once in a data model, use an element rather than introducing attributes with names like foo1, foo2, foo3 ....
++
+2. Use elements to represent a piece of information that can be considered an independent object and when the information is related via a parent/child relationship to another piece of information.
++
+3. Use elements when data incorporates strict typing or relationship rules.
++
+4. If order matters between two pieces of data, use elements for them: attributes are inherently unordered.
++
+5. If a piece of data has, or might have, its own substructure, use it in an element: getting substructure into an attribute is always messy. Similarly, if the data is a constituent part of some larger piece of data, put it in an element.
++
+6. An exception to the previous rule: multiple whitespace-separated tokens can safely be put in an attribute. In principle, the separator can be anything, but schema-language validators are currently only able to handle whitespace, so it's best to stick with that.
++
+7. If a piece of data extends across multiple lines, use an element: XML parsers will change newlines in attribute values into spaces.
+8. If a piece of data is very large, use an element so that its content can be streamed.
+9. If a piece of data is in a natural language, put it in an element so you can use the xml:lang attribute to label the language being used. Some kinds of natural-language text, like Japanese, often make use http://www.w3.org/TR/2001/REC-ruby-20010531[annotations] that are conventionally represented using child elements; right-to-left languages like Hebrew and Arabic may similarly require child elements to manage http://www.w3.org/TR/2001/REC-ruby-20010531[bidirectionality] properly.
++
+
+=== 12.3 Using attributes
+
+1. If the data is a code from an enumeration, code list, or controlled vocabulary, put it in an attribute if possible. For example, language tags, currency codes, medical diagnostic codes, etcare best handled as attributes.
++
+2. If a piece of data is really metadata on some other piece of data (for example, representing a class or role that the main data serves, or specifying a method of processing it), put it in an attribute if possible.
++
+3. In particular, if a piece of data is an ID for some other piece of data, or a reference to such an ID, put the identifying piece in an attribute. When it's an ID, use the name xml:id for the attribute.
++
+4. Hypertext references are conventionally put in href attributes.
++
+5. If a piece of data is applicable to an element and any descendant elements unless it is overridden in some of them, it is conventional to put it in an attribute. Well-known examples are xml:lang, xml:space, xml:base, and namespace declarations.
++
+6. If terseness is really the _most_ important thing, use attributes, but consider gzip compression instead -- it works very well on documents with highly repetitive structures.
+
+== Parting words
+
+Use common sense and __BE CONSISTENT__. Design for extensibility. You _are_ gonna need it. [__Rationale:__ Long and painful experience.]
+
+When designing XML formats, take a few minutes to look at other formats and determine their style. The point of having style guidelines is so that people can concentrate on what you are saying, rather than on how you are saying it
+
+Break _ANY OR ALL_ of these rules (yes, even the ones that say MUST) rather than create a crude, arbitrary, disgusting mess of a design if that's what following them slavishly would give you. In particular, random mixtures of attributes and child elements are hard to follow and hard to use, though it often makes good sense to use both when the data clearly fall into two different groups such as simple/complex or metadata/data.
+
+Newbies always ask:
+
+"Elements or attributes?
+
+Which will serve me best?"
+
+Those who know roar like lions;
+
+Wise hackers smile like tigers.
+
+--a http://en.wikipedia.org/wiki/Waka_%28poetry%29#Tanka[tanka], or extended haiku
+
+[TODO: if a registry of schemas is set up, add a link to it]
+
+ +
diff --git a/xmlstyle.html b/xmlstyle.html
deleted file mode 100644
index ba4a376..0000000
--- a/xmlstyle.html
+++ /dev/null
@@ -1,681 +0,0 @@
-
-
-
-
-
-
-
-
-
-Google XML Document Format Style Guide
Version 1.0
Copyright Google 2008
Introduction
This document provides a set of guidelines for general use when designing new XML document formats (and to some extent XML documents as well; see Section 11). Document formats usually include both formal parts (DTDs, schemas) and parts expressed in normative English prose.
These guidelines apply to new designs, and are not intended to force retroactive changes in existing designs. When participating in the creation of public or private document format designs, the guidelines may be helpful but should not control the group consensus.
This guide is meant for the design of XML that is to be generated and consumed by machines rather than human beings. Its rules are not applicable to formats such as XHTML (which should be formatted as much like HTML as possible) or ODF which are meant to express rich text. A document that includes embedded content in XHTML or some other rich-text format, but also contains purely machine-interpretable portions, SHOULD follow this style guide for the machine-interpretable portions. It also does not affect XML document formats that are created by translations from proto buffers or through some other type of format.
Brief rationales have been added to most of the guidelines. They are maintained in the same document in hopes that they won't get out of date, but they are not considered normative.
The terms MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are used in this document in the sense of RFC 2119.
1. To design or not to design, that is the question
- Attempt to reuse existing XML formats whenever possible, especially those which allow extensions. Creating an entirely new format should be done only with care and consideration; read Tim Bray's warnings first. Try to get wide review of your format, from outside your organization as well, if possible. [Rationale: New document formats have a cost: they must be reviewed, documented, and learned by users.]
- If you are reusing or extending an existing format, make sensible
-
-use of the prescribed elements and attributes, especially any that are
-required. Don't completely repurpose them, but do try to see how they
-might be used in creative ways if the vanilla semantics aren't
-suitable. As a last resort when an element or attribute is required by the format but is not appropriate for your use case, use some
-fixed string as its value. [Rationale: Markup reuse is good, markup abuse is bad.]
- When extending formats, use the implicit style of the existing format, even if it contradicts this guide. [Rationale: Consistency.]
2. Schemas
- Document formats SHOULD be expressed using a schema language. [Rationale: Clarity and machine-checkability.]
- The schema language SHOULD be RELAX NG compact syntax. Embedded Schematron rules MAY be added to the schema for additional fine control. [Rationale:
-
-RELAX NG is the most flexible schema language, with very few arbitrary
-restrictions on designs. The compact syntax is quite easy to read and
-learn, and can be converted one-to-one to and from the XML syntax when
-necessary. Schematron handles arbitrary cross-element and
-cross-attribute constraints nicely.]
- Schemas SHOULD use the "Salami Slice" style (one rule per element). Schemas MAY use the "Russian Doll" style (schema resembles document) if they are short and simple. The "Venetian Blind" style (one rule per element type) is unsuited to RELAX NG and SHOULD NOT be used.
- Regular expressions SHOULD be provided to assist in validating complex values.
- DTDs and/or W3C XML Schemas MAY be provided for compatibility with existing products, tools, or users. [Rationale: We can't change the world all at once.]
3. Namespaces
- Element names MUST be in a namespace, except
-when extending pre-existing document types that do not use namespaces.
-
-A default namespace SHOULD be used. [Rationale: Namespace-free
-documents are obsolete; every set of names should be in some
-namespace. Using a default namespace improves readability.]
- Attribute
-names SHOULD NOT be in a namespace unless they are drawn from a foreign
-document type or are meant to be used in foreign document types. [Rationale: Attribute names in a namespace must always have a prefix, which is annoying to type and hard to read.]
- - Namespace names are HTTP URIs. Namespace names SHOULD take the form http://example.com/whatever/year, where whatever is a unique value based on the name of the document type, and year
-
-is the year the namespace was created. There may be additional URI-path parts
-before the year. [Rationale: Existing convention. Providing the year allows for the possible recycling of code names.]
- Namespaces MUST NOT be changed unless the semantics of particular elements or attributes has changed in drastically incompatible ways. [Rationale: Changing the namespace requires changing all client code.]
- Namespace prefixes SHOULD be short (but not so short that they are likely to be conflict with another project). Single-letter prefixes MUST NOT be used. Prefixes SHOULD contain only lower-case ASCII letters. [Rationale: Ease of typing and absence of encoding compatibility problems.]
-
-4. Names and enumerated values
Note: "Names" refers to the names of elements, attributes, and enumerated values.
- All names MUST use lowerCamelCase. That is, they start with an initial lower-case letter, then each new word within the name starts with an initial capital letter. [Rationale: Adopting a single style provides consistency, which helps when referring to names since the capitalization is known and so does not have to be remembered. It matches Java style, and other languages can be dealt with using automated name conversion.]
- Names MUST contain only ASCII letters and digits.
-[Rationale: Ease of typing and absence of encoding compatibility problems.]
- Names SHOULD NOT exceed 25 characters. Longer names SHOULD be
-avoided by devising concise and informative names. If a name can only remain within this limit by becoming obscure, the limit SHOULD be ignored. [Rationale: Longer names are awkward to use and require additional bandwidth.]
- Published standard abbreviations, if sufficiently well-known, MAY be employed in constructing names. Ad hoc abbreviations MUST NOT be used. Acronyms MUST be treated as words for camel-casing purposes: informationUri, not informationURI. [Rationale: An abbreviation that is well known
-to one community is often incomprehensible to others who need to use
-the same document format (and who do understand the full name); treating an acronym as a word makes it easier to see where the word boundaries are.]
-
-
-5. Elements
- All elements MUST contain either nothing, character content, or child elements. Mixed content MUST NOT be used. [Rationale: Many XML data models don't handle mixed content properly, and its use makes the element order-dependent. As always, textual formats are not covered by this rule.]
- XML elements that merely wrap repeating child elements SHOULD NOT be used. [Rationale: They are not used in Atom and add nothing.]
-
-
6. Attributes
- Document formats MUST NOT depend on the order of attributes in a start-tag. [Rationale: Few XML parsers report the order, and it is not part of the XML Infoset.]
- Elements SHOULD NOT be overloaded with too many attributes (no more
-than 10 as a rule of thumb). Instead, use child elements to
-encapsulate closely related attributes. [Rationale: This
-approach maintains the built-in extensibility that XML provides with
-elements, and is useful for providing forward compatibility as a
-specification evolves.]
- Attributes MUST NOT be used to hold values in which line breaks are significant. [Rationale: Such line breaks are converted to spaces by conformant XML parsers.]
- Document formats MUST allow either single or double quotation marks around attribute values. [Rationale: XML parsers don't report the difference.]
-
-
-
-
-7. Values
- Numeric values SHOULD be 32-bit signed integers, 64-bit signed integers, or 64-bit IEEE doubles, all expressed in base 10. These correspond to the XML Schema types xsd:int, xsd:long, and xsd:double respectively. If required in particular cases, xsd:integer (unlimited-precision integer) values MAY also be used. [Rationale: There are far too many numeric types in XML Schema: these provide a reasonable subset.]
-
-
-Boolean values SHOULD NOT be used (use enumerations instead). If they must be used, they MUST be expressed as true or false, corresponding to a subset of the XML Schema type xsd:boolean. The alternative xsd:boolean values 1 and 0 MUST NOT be used. [Rationale: Boolean arguments are not extensible. The additional flexibility of allowing numeric values is not abstracted away by any parser.]
- Dates should be represented using RFC 3339 format, a subset of both
-ISO 8601 format and XML Schema xsd:dateTime format. UTC times SHOULD be used rather than local times.
-
-[Rationale: There are far too many date formats and time zones, although it is recognized that sometimes local time preserves important information.]
- Embedded syntax in character content and attribute values SHOULD NOT be
-used. Syntax in values means XML tools are largely useless. Syntaxes such as dates, URIs, and
-XPath expressions are exceptions. [Rationale:
-Users should be able to process XML documents using only an XML parser
-without requiring additional special-purpose parsers, which are easy to
-get wrong.]
- Be careful with whitespace in values. XML parsers don't strip whitespace in elements, but do convert newlines to spaces in attributes. However, application frameworks may do more aggressive whitespace stripping. Your document format SHOULD give rules for whitespace stripping.
-
-
-
-
-
8. Key-value pairs
-
-Simple key-value pairs SHOULD be represented with an empty element whose name represents the key, with the value attribute containing the value. Elements that have a value attribute MAY also have a unit attribute to specify the unit of a measured value. For physical measurements, the SI system SHOULD be used. [Rationale:
-
-Simplicity and design consistency. Keeping the value in an attribute
-hides it from the user, since displaying just the value without the key is not useful.]
- If the number of possible keys is very large or unbounded, key-value pairs MAY be represented by a single generic element with key, value, and optional unit and scheme
-attributes (which serve to discriminate keys from different domains).
-In that case, also provide (not necessarily in the same document) a
-list of keys with human-readable explanations.
9. Binary data
Note: There are no hard and fast rules about whether binary data should be included as part of an XML document or not. If it's too large, it's probably better to link to it.
- Binary data MUST NOT be included directly as-is in XML documents, but MUST be encoded using Base64 encoding. [Rationale: XML does not allow arbitrary binary bytes.]
-
-
-The line breaks required by Base64 MAY be omitted. [Rationale: The line breaks are meant to keep plain text lines short, but XML is not really plain text.]
- An attribute named xsi:type with value xs:base64Binary MAY be attached to this element to signal that the Base64 format is in use. [Rationale: Opaque blobs should have decoding instructions attached.]
-10. Processing instructions
- New processing instructions MUST NOT be created except in order to specify purely local processing conventions, and SHOULD be avoided altogether. Existing standardized processing instructions MAY be used. [Rationale: Processing instructions fit awkwardly into XML data models and can always be replaced by elements; they exist primarily to avoid breaking backward compatibility.]
-
-
-
11. Representation of XML document instances
Note: These points are only guidelines, as the format of program-created instances will often be outside the programmer's control (for example, when an XML serialization library is being used). In no case should XML parsers rely on these guidelines being followed. Use standard XML parsers, not hand-rolled hacks.
- The character encoding used SHOULD be UTF-8. Exceptions should require extremely compelling circumstances. [Rationale: UTF-8 is universal and in common use.]
- Namespaces SHOULD be declared in the root element of a document wherever possible. [Rationale: Clarity and consistency.]
- The mapping of namespace URIs to prefixes SHOULD remain constant throughout the document, and SHOULD also be used in documentation of the design. [Rationale: Clarity and consistency.]
- Well-known prefixes such as html: (for XHTML), dc: (for Dublin Core metadata), and xs: (for XML Schema) should be used for standard namespaces. [Rationale: Human readability.]
- Redundant whitespace in a tag SHOULD NOT be
-used. Use one space before each attribute in a start-tag; if the start
-tag is too long, the space MAY be replaced by a newline. [Rationale: Consistency and conciseness.]
- Empty elements MAY be expressed as empty tags or a start-tag
-immediately followed by an end-tag. No distinction should be made
-between these two formats by any application. [Rationale: They are not distinguished by XML parsers.]
- Documents MAY be pretty-printed using 2-space indentation for child
-elements. Elements that contain character content SHOULD NOT be
-wrapped. Long start-tags MAY be broken using newlines (possibly with extra indentation) after any attribute value except the last. [Rationale: General compatibility with our style. Wrapping character content affects its value.]
- Attribute values MAY be surrounded with either quotation marks or apostrophes.
-Specifications MUST NOT require or forbid the use of either form. ' and " may be freely used to escape each type of quote. [Rationale: No XML parsers report the distinction.]
-
- - Comments MUST NOT be used to carry real data. Comments MAY be used to contain TODOs in hand-written XML. Comments SHOULD NOT be used at all in publicly transmitted documents. [Rationale: Comments are often discarded by parsers.]
- If comments are nevertheless used, they SHOULD appear only in the document prolog or in elements that
-contain child elements. If pretty-printing is required, pretty-print
-comments like elements, but with line wrapping. Comments SHOULD NOT
-appear in elements that contain character content. [Rationale: Whitespace in and around comments improves readability, but embedding a
-comment in character content can lead to confusion about what
-whitespace is or is not in the content.]
- Comments SHOULD have whitespace following <!-- and preceding -->. [Rationale: Readability.]
- CDATA sections MAY be used; they are equivalent to the use of & and <. Specifications MUST NOT require or forbid the use of CDATA sections. [Rationale: Few XML parsers report the distinction, and combinations of CDATA and text are often reported as single objects anyway.]
- Entity references other than the XML standard entity references &, <, >, ", and ' MUST NOT be used. Character references MAY be used, but actual characters are preferred, unless the character encoding is not UTF-8. As usual, textual formats are exempt from this rule.
-
-
-
-
-
-12. Elements vs. Attributes
-
-
-Note: There are no hard and fast rules for deciding when to use attributes and when to use elements. Here are some of the considerations that designers should take into account; no rationales are given.
-
-
-12.1. General points:
-
-
-
--
-
-Attributes are more restrictive than elements, and all designs have some elements, so an all-element design is simplest -- which is not the same as best.
-
-
-
-
-
--
-
-In a tree-style data model, elements are typically represented internally as nodes, which use more memory than the strings used to represent attributes. Sometimes the nodes are of different application-specific classes, which in many languages also takes up memory to represent the classes.
-
-
-
-
-
-
--
-
-When streaming, elements are processed one at a time (possibly even piece by piece, depending on the XML parser you are using), whereas all the attributes of an element and their values are reported at once, which costs memory, particularly if some attribute values are very long.
-
-
-
-
-
--
-
-Both element content and attribute values need to be escaped appropriately, so escaping should not be a consideration in the design.
-
-
-
-
-
-
--
-
-In some programming languages and libraries, processing elements is easier; in others, processing attributes is easier. Beware of using ease of processing as a criterion. In particular, XSLT can handle either with equal facility.
-
-
-
-
-
--
-
-If a piece of data should usually be shown to the user, consider using an element; if not, consider using an attribute. (This rule is often violated for one reason or another.)
-
-
-
-
-
-
--
-
-If you are extending an existing schema, do things by analogy to how things are done in that schema.
-
-
-
-
-
--
-
-Sensible schema languages, meaning RELAX NG and Schematron, treat elements and attributes symmetrically. Older and cruder schema languages such as DTDs and XML Schema, tend to have better support for elements.
-
-
-
-
-
-
-
-12.2 Using elements
-
-
--
-
-If something might appear more than once in a data model, use an element rather than introducing attributes with names like foo1, foo2, foo3 ....
-
-
-
-
-
-
--
-
-Use elements to represent a piece of information that can be considered an independent object and when the information is related via a parent/child relationship to another piece of information.
-
-
-
-
-
--
-
-Use elements when data incorporates strict typing or relationship rules.
-
-
-
-
-
-
--
-
-If order matters between two pieces of data, use elements for them: attributes are inherently unordered.
-
-
-
-
-
--
-
-If a piece of data has, or might have, its own substructure, use it in an element: getting substructure into an attribute is always messy. Similarly, if the data is a constituent part of some larger piece of data, put it in an element.
-
-
-
-
-
-
--
-
-An exception to the previous rule: multiple whitespace-separated tokens can safely be put in an attribute. In principle, the separator can be anything, but schema-language validators are currently only able to handle whitespace, so it's best to stick with that.
-
-
-
-
-
--
-
-If a piece of data extends across multiple lines, use an element: XML parsers will change newlines in attribute values into spaces.
-
-
- If a piece of data is very large, use an element so that its content can be streamed.
--
-
-If a piece of data is in a natural language, put it in an element so you can use the xml:lang attribute to label the language being used. Some kinds of natural-language text, like Japanese, often make use annotations that are conventionally represented using child elements; right-to-left languages like Hebrew and Arabic may similarly require child elements to manage bidirectionality properly.
-
-
-
-
-
-
-
-12.3 Using attributes
-
-
--
-
-If the data is a code from an enumeration, code list, or controlled vocabulary, put it in an attribute if possible. For example, language tags, currency codes, medical diagnostic codes, etc. are best handled as attributes.
-
-
-
-
-
-
--
-
-If a piece of data is really metadata on some other piece of data (for example, representing a class or role that the main data serves, or specifying a method of processing it), put it in an attribute if possible.
-
-
-
-
-
--
-
-In particular, if a piece of data is an ID for some other piece of data, or a reference to such an ID, put the identifying piece in an attribute. When it's an ID, use the name xml:id for the attribute.
-
-
-
-
-
-
--
-
-Hypertext references are conventionally put in href attributes.
-
-
-
-
-
--
-
-
-If a piece of data is applicable to an element and any descendant elements unless it is overridden in some of them, it is conventional to put it in an attribute. Well-known examples are xml:lang, xml:space, xml:base, and namespace declarations.
-
-
-
-
-
--
-
-
-If terseness is really the most important thing, use attributes, but consider gzip compression instead -- it works very well on documents with highly repetitive structures.
-
-
13. Parting words
-
-
-
-Use common sense and BE CONSISTENT. Design for extensibility. You are gonna need it. [Rationale: Long and painful experience.]
-
-
-When designing XML formats, take a few minutes to look at other formats and determine their style. The point of having style guidelines is so that people can concentrate on what you are
-saying, rather than on how you are saying it.
-
-Break ANY OR ALL of these rules (yes, even the ones that say MUST) rather than create a crude, arbitrary, disgusting mess of a design if that's what following them slavishly would give you. In particular, random mixtures of attributes and child elements are hard to follow and hard to use, though it often makes good sense to use both when the data clearly fall into two different groups such as simple/complex or metadata/data.
-
-
-
-Newbies always ask:
-
-
-
- "Elements or attributes?
-
-
-Which will serve me best?"
-
-
- Those who know roar like lions;
-
-
- Wise hackers smile like tigers.
-
-
- --a tanka, or extended haiku
-
-
-
-
-
-
-
[TODO: if a registry of schemas is set up, add a link to it]
-
-