| <?xml version="1.0"?> |
| <?xml-stylesheet type="text/xsl" href="styleguide.xsl"?> |
| <GUIDE title="Google Common Lisp Style Guide"> |
| |
| |
| <p align="right"> |
| |
| Revision 1.23 |
| </p> |
| |
| |
| <address> |
| Robert Brown |
| </address> |
| <address> |
| <a HREF="mailto:tunes@google.com">François-René Rideau</a> |
| </address> |
| |
| <address> |
| In memoriam Dan Weinreb |
| </address> |
| |
| <p align="center"> |
| <cite>Patterns mean "I have run out of language."</cite> — Rich Hickey |
| </p> |
| |
| |
| <OVERVIEW> |
| <CATEGORY title="Important Note"> |
| <STYLEPOINT title="Note: Displaying Hidden Details in this Guide"> |
| <SUMMARY> |
| 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. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Hooray! Now you know you can expand points to get more details. |
| Alternatively, there's an "expand all" at the top of this document. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| <CATEGORY title="Background"> |
| <p> |
| Common Lisp is a powerful multiparadigm programming language. |
| With great power comes great responsibility. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| |
| <p> |
| This guide is not a Common Lisp tutorial. |
| For basic information about the language, please consult |
| <a HREF="http://www.gigamonkeys.com/book/">Practical Common Lisp</a>. |
| For a language reference, please consult the |
| <a HREF="http://www.lispworks.com/documentation/HyperSpec/Front/index.htm">Common Lisp HyperSpec</a>. |
| For more detailed style guidance, take (with a pinch of salt) |
| a look at Peter Norvig and Kent Pitman's |
| <a HREF="http://norvig.com/luv-slides.ps">style guide</a>. |
| </p> |
| </CATEGORY> |
| </OVERVIEW> |
| <CATEGORY title="Meta-Guide"> |
| <STYLEPOINT title="Must, Should, May, or Not"> |
| <SUMMARY> |
| Each guideline's level of importance is indicated |
| by use of the following keywords and phrases, adapted from |
| <a href="http://www.ietf.org/rfc/rfc2119.txt">RFC 2119</a>. |
| </SUMMARY> |
| <BODY> |
| <table> |
| <tr> |
| <th valign="top">MUST</th> |
| <td> |
| <p> |
| This word, or the terms "REQUIRED" or "SHALL", |
| means that the guideline is an absolute requirement. |
| You must ask permission to violate a MUST. |
| </p> |
| </td> |
| </tr> |
| <tr> |
| <th valign="top">MUST NOT</th> |
| <td> |
| <p> |
| This phrase, or the phrase "SHALL NOT", |
| means that the guideline is an absolute prohibition. |
| You must ask permission to violate a MUST NOT. |
| </p> |
| </td> |
| </tr> |
| <tr> |
| <th valign="top">SHOULD</th> |
| <td> |
| <p> |
| 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. |
| </p> |
| </td> |
| </tr> |
| <tr> |
| <th valign="top">SHOULD NOT</th> |
| <td> |
| <p> |
| 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. |
| </p> |
| </td> |
| </tr> |
| <tr> |
| <th valign="top">MAY</th> |
| <td> |
| <p> |
| This word, or the adjective "OPTIONAL", |
| means that an item is truly optional. |
| </p> |
| </td> |
| </tr> |
| </table> |
| <p> |
| Unlike RFCs, we don't capitalize every instance of one of the above |
| keywords when it is used. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Permission and Forgiveness"> |
| <SUMMARY> |
| 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. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Permission comes from the owners of your project. |
| </p> |
| |
| <p> |
| 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. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Conventions"> |
| <SUMMARY> |
| You MUST follow conventions. They are not optional. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| Conventional guidelines <em>are</em> 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Old Code"> |
| <SUMMARY> |
| Fix old code as you go. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Future Topics"> |
| <SUMMARY> |
| There are many topics for additional standardization |
| not covered by current version of this document, |
| but deferred to future versions. |
| </SUMMARY> |
| <BODY> |
| <ul> |
| <li> |
| File and directory structure |
| </li> |
| <li> |
| Packages and modularity |
| </li> |
| <li> |
| Threads and locking |
| </li> |
| <li> |
| How to add configurable components |
| </li> |
| <li> |
| CLOS style: initforms, slot and accessor names, etc. |
| </li> |
| <li> |
| Recommendations on max number of slots per class. |
| </li> |
| <li> |
| More concrete examples of good code: |
| <ul> |
| <li> |
| exceptions |
| </li> |
| <li> |
| transactions, with retry |
| </li> |
| <li> |
| XML |
| </li> |
| <li> |
| typing |
| </li> |
| <li> |
| encapsulation / abstraction |
| </li> |
| <li> |
| class and slot names |
| </li> |
| <li> |
| etc. |
| </li> |
| </ul> |
| </li> |
| <li> |
| When (not) to use conditional compilation: |
| <ul> |
| <li> |
| modifying the product |
| </li> |
| <li> |
| conditional debugging/console output/etc. |
| </li> |
| <li> |
| "temporarily" commenting-out blocks of code |
| </li> |
| <li> |
| etc. |
| </li> |
| </ul> |
| </li> |
| </ul> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| <CATEGORY title="General Guidelines"> |
| <STYLEPOINT title="Principles"> |
| <SUMMARY> |
| 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: |
| <ul> |
| <li> |
| 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.) |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| Be precise. |
| </li> |
| <li> |
| Be concise. |
| </li> |
| <li> |
| KISS — Keep It Simple, Stupid. |
| </li> |
| <li> |
| Use the smallest hammer for the job. |
| </li> |
| <li> |
| Use common sense. |
| </li> |
| <li> |
| Keep related code together. |
| Minimize the amount of jumping around |
| someone has to do to understand an area of code. |
| </li> |
| </ul> |
| </SUMMARY> |
| <BODY> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Priorities"> |
| <SUMMARY> |
| <p> |
| When making decisions about how to write a given piece of |
| code, aim for the following -ilities in this priority order: |
| </p> |
| <ul> |
| <li> |
| Usability by the customer |
| </li> |
| <li> |
| Debuggability/Testability |
| </li> |
| <li> |
| Readability/Comprehensibility |
| </li> |
| <li> |
| Extensibility/Modifiability |
| </li> |
| <li> |
| Efficiency (of the Lisp code at runtime) |
| </li> |
| </ul> |
| </SUMMARY> |
| <BODY> |
| <p> |
| Most of these are obvious. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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.) |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Architecture"> |
| <SUMMARY> |
| 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. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| If you don't know or don't care about these issues, |
| ask someone who does. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Using Libraries"> |
| <SUMMARY> |
| 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. |
| </SUMMARY> |
| <BODY> |
| <ul> |
| <li> |
| 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. |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| 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. |
| </li> |
| </ul> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Open-Sourcing Code"> |
| <SUMMARY> |
| <p> |
| 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. |
| </p> |
| |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| |
| <p> |
| 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. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Development Process"> |
| <SUMMARY> |
| 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. |
| </SUMMARY> |
| <BODY> |
| <p> |
| </p> |
| <ul> |
| <li> |
| 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. |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| 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 |
| <code>UIOP:WITH-MUFFLED-COMPILER-CONDITIONS</code> and |
| <code>UIOP:*UNINTERESTING-COMPILER-CONDITIONS*</code> |
| framework (part of <code>UIOP</code>, part of <code>ASDF 3</code>), |
| either around the entire project, or around individual files |
| (using <code>ASDF</code>'s <code>:around-compile</code> hooks). |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| You must run the "precheckin" tests, and each component must pass |
| its unit tests successfully before you commit any code. |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| 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 |
| </li> |
| </ul> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| <CATEGORY title="Formatting"> |
| <STYLEPOINT title="Spelling and Abbreviations"> |
| <SUMMARY> |
| <p> |
| You must use correct spelling in your comments, |
| and most importantly in your identifiers. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| </SUMMARY> |
| <BODY> |
| <p> |
| If you're not sure, consult a dictionary, |
| Google for alternative spellings, |
| or ask a local expert. |
| </p> |
| <p> |
| Here are examples of choosing the correct spelling: |
| </p> |
| <ul> |
| <li> |
| Use "complimentary" in the sense of a meal or beverage |
| that is not paid for by the recipient, not "complementary". |
| </li> |
| <li> |
| Use "existent" and "nonexistent", not "existant". |
| Use "existence", not "existance". |
| </li> |
| <li> |
| Use "hierarchy" not "heirarchy". |
| </li> |
| <li> |
| Use "precede" not "preceed". |
| </li> |
| <li> |
| Use "weird", not "wierd". |
| </li> |
| </ul> |
| <p> |
| Here are examples of choosing the shorter spelling: |
| </p> |
| <ul> |
| <li> |
| Use "canceled", not "cancelled" |
| </li> |
| <li> |
| Use "queuing", not "queueing". |
| </li> |
| <li> |
| Use "signaled", not "signalled"; |
| </li> |
| <li> |
| Use "traveled", not "travelled". |
| </li> |
| <li> |
| Use "aluminum", not "aluminium" |
| </li> |
| <li> |
| Use "oriented", not "orientated" |
| </li> |
| <li> |
| Use "color", not "colour" |
| </li> |
| <li> |
| Use "behavior", not "behaviour" |
| </li> |
| </ul> |
| <p> |
| Make appropriate exceptions for industry standard nomenclature/jargon, |
| including plain misspellings. |
| For instance: |
| </p> |
| <ul> |
| <li> |
| Use "referer", not "referrer", in the context of the HTTP protocol. |
| </li> |
| </ul> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Line length"> |
| <SUMMARY> |
| You should format source code so that no line is longer than 100 characters. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Indentation"> |
| <SUMMARY> |
| <p> |
| Indent your code the way a properly configured GNU Emacs does. |
| </p> |
| <p> |
| Indent carefully to make the code easier to understand. |
| </p> |
| </SUMMARY> |
| <BODY> |
| <p> |
| By default, GNU Emacs does an excellent job indenting Common Lisp code. |
| It can be taught how to indent new defining forms |
| and special rules for domain specific languages. |
| Each project may have some file to customize indentation; use it. |
| </p> |
| |
| |
| <p> |
| 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. |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Bad |
| (do-something first-argument second-argument (lambda (x) |
| (frob x)) fourth-argument last-argument) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (do-something first-argument |
| second-argument |
| #'(lambda (x) (frob x)) |
| fourth-argument |
| last-argument) |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="File Header"> |
| <SUMMARY> |
| <p> |
| You should include a description at the top of each source file. |
| </p> |
| <p> |
| You should include neither authorship nor copyright information in a source file. |
| </p> |
| </SUMMARY> |
| <BODY> |
| <p> |
| Every source file should begin with a brief description |
| of the contents of that file. |
| </p> |
| <p> |
| After that description, every file should start the code itself with an |
| <code>(in-package :<em>package-name</em>)</code> form. |
| </p> |
| <p> |
| After that <code>in-package</code> form, |
| every file should follow with any file-specific |
| <code>(declaim (optimize ...))</code> declaration |
| that is not covered by an <code>ASDF</code> <code>:around-compile</code> hook. |
| </p> |
| <CODE_SNIPPET> |
| ;;;; Author: brown (Robert Brown) |
| |
| ;;;; Variable length encoding for integers and floating point numbers. |
| |
| (in-package #:varint) |
| (declaim #.*optimize-default*) |
| </CODE_SNIPPET> |
| <p> |
| You should not include authorship information at the top of a file, |
| that information is available from version control and |
| <code>OWNERS</code>. |
| </p> |
| <p> |
| You should not include copyright information in individual source code files. |
| An exception is made for files meant to be disseminated as standalone. |
| </p> |
| <p> |
| Each project or library has a single file specifying its license. |
| Absence of a <tt>LICENSE</tt> or <tt>COPYING</tt> file |
| means the project is proprietary code. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Vertical white space"> |
| <SUMMARY> |
| Vertical white space: one blank line between top-level forms. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <CODE_SNIPPET> |
| (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))) |
| </CODE_SNIPPET> |
| <p> |
| 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 <code>;;</code> comment |
| what each of the separated parts of the function does. |
| </p> |
| <p> |
| 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 <code>eval-when</code>, |
| rather than to the <code>eval-when</code> itself. |
| Additionally, <code>defpackage</code> forms may be longer, |
| since they may include long lists of symbols. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Horizontal white space"> |
| <SUMMARY> |
| Horizontal white space: none around parentheses. No tabs. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You must not include extra horizontal whitespace |
| before or after parentheses or around symbols. |
| </p> |
| <p> |
| You must not place right parentheses by themselves on a line. |
| A set of consecutive trailing parentheses must appear on the same line. |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Very Bad |
| ( defun factorial ( limit ) |
| ( let (( product 1 )) |
| ( loop for i from 1 upto limit |
| do (setf product ( * product i ) ) ) |
| product |
| ) |
| ) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (defun factorial (limit) |
| (let ((product 1)) |
| (loop for i from 1 upto limit |
| do (setf product (* product i))) |
| product)) |
| </CODE_SNIPPET> |
| <p> |
| You should use only one space between forms. |
| </p> |
| <p> |
| 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. |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Bad |
| (let* ((low 1) |
| (high 2) |
| (sum (+ (* low low) (* high high)))) |
| ...) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (let* ((low 1) |
| (high 2) |
| (sum (+ (* low low) (* high high)))) |
| ...)) |
| </CODE_SNIPPET> |
| <p> |
| You must align nested forms if they occur across more than one line. |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Bad |
| (defun munge (a b c) |
| (* (+ a b) |
| c)) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (defun munge (a b c) |
| (* (+ a b) |
| c)) |
| </CODE_SNIPPET> |
| <p> |
| 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. |
| </p> |
| <CODE_SNIPPET> |
| (multiple-value-bind (a b c d) |
| (function-returning-four-values x y) |
| (declare (ignore c)) |
| (something-using a) |
| (also-using b d)) |
| </CODE_SNIPPET> |
| <p> |
| An exception to the rule against lonely parentheses |
| is made for an <code>eval-when</code> form around several definitions; |
| in this case, include a comment <code>; eval-when</code> |
| after the closing parenthesis. |
| </p> |
| <p> |
| 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 <code>(setq-default indent-tabs-mode nil)</code>. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="Documentation"> |
| <STYLEPOINT title="Document everything"> |
| <SUMMARY> |
| You should use document strings on all visible functions |
| to explain how to use your code. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Unless some bit of code is painfully self-explanatory, |
| document it with a documentation string (also known as docstring). |
| </p> |
| <p> |
| 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 <code>(describe 'foo)</code>; |
| 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. |
| </p> |
| <p> |
| Supply a documentation string when defining |
| top-level functions, types, classes, variables and macros. |
| Generally, add a documentation string wherever the language allows. |
| </p> |
| <p> |
| 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." |
| </p> |
| <CODE_SNIPPET> |
| (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))))) |
| </CODE_SNIPPET> |
| <CODE_SNIPPET> |
| (defgeneric table-clear (table) |
| (:documentation |
| "Like clrhash, empties the TABLE of all |
| associations, and returns the table itself.")) |
| </CODE_SNIPPET> |
| <p> |
| A long docstring may usefully |
| begin with a short, single-sentence summary, |
| followed by the larger body of the docstring. |
| </p> |
| <p> |
| 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 <kbd>M-.</kbd> |
| will lead to the symbol's definition. |
| </p> |
| <CODE_SNIPPET> |
| (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." |
| ...) |
| </CODE_SNIPPET> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Comment semicolons"> |
| <SUMMARY> |
| You must use the appropriate number of semicolons to introduce comments. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| You must comment anything complicated |
| so that the next developer can understand what's going on. |
| (Again, the "hit by a truck" principle.) |
| </p> |
| <p> |
| Also use comments as a way to guide those who read the code, |
| so they know what to find where. |
| </p> |
| <ul> |
| <li> |
| File headers and important comments |
| that apply to large sections of code in a source file |
| should begin with four semicolons. |
| </li> |
| <li> |
| You should use three semicolons |
| to begin comments that apply to just |
| one top-level form or small group of top-level forms. |
| </li> |
| <li> |
| Inside a top-level form, you should use two semicolons |
| to begin a comment if it appears between lines. |
| </li> |
| <li> |
| 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. |
| </li> |
| </ul> |
| <CODE_SNIPPET> |
| ;;;; 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))))) |
| </CODE_SNIPPET> |
| <p> |
| You should include a space between the semicolon and the text of the comment. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Grammar and punctuation"> |
| <SUMMARY> |
| You should punctuate documentation correctly. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Attention Required"> |
| <SUMMARY> |
| You must follow the convention of using TODO comments |
| for code requiring special attention. |
| For code using unobvious forms, you must include a comment. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| The comments begin with <code>TODO</code> in all capital letters, |
| followed by your email address or other identifier in parentheses, |
| followed by a colon, a space, and |
| an explanation of what additional work is desirable or required. |
| The user name included in the comment is that |
| of a person who understands the deficiency. |
| A TODO comment is not a commitment to fix the problem. |
| </p> |
| <p> |
| 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. |
| |
| </p> |
| <CODE_SNIPPET> |
| ;;--- TODO(george@gmail.com): Refactor to provide a better API. |
| </CODE_SNIPPET> |
| <p> |
| Be specific when indicating times or software releases |
| in a TODO comment: |
| </p> |
| <CODE_SNIPPET> |
| ;;--- TODO(brown): Remove this code after release 1.7 or before November, 2012. |
| </CODE_SNIPPET> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Domain-Specific Languages"> |
| <SUMMARY> |
| You should document DSLs and |
| any terse program in a DSL. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You should design your Domain Specific Language |
| to be easy to read and understand by people familiar with the domain. |
| </p> |
| <p> |
| You must properly document all your Domain Specific Language. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| Notably, when you use regular expressions |
| (e.g. with the <code>CL-PPCRE</code> 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| |
| </CATEGORY> |
| |
| <CATEGORY title="Naming"> |
| <STYLEPOINT title="Symbol guidelines"> |
| <SUMMARY> |
| You should use lower case. |
| You should follow the rules for <a href="#Spelling_and_Abbreviations">Spelling and Abbreviations</a> |
| You should follow punctuation conventions. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Use lower case for all symbols. |
| Consistently using lower case makes searching for symbol names easier |
| and is more readable. |
| </p> |
| <p> |
| Note that Common Lisp is case-converting, |
| and that the <code>symbol-name</code> 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. |
| </p> |
| <p> |
| Place hyphens between all the words in a symbol. |
| If you can't easily say an identifier out loud, |
| it is probably badly named. |
| </p> |
| <p> |
| You must not use <code>"/"</code> or <code>"."</code> |
| instead of <code>"-"</code> |
| unless you have a well-documented overarching reason to, |
| and permission from other hackers who review your proposal. |
| </p> |
| <p> |
| See the section on <a href="#Spelling_and_Abbreviations">Spelling and Abbreviations</a> |
| for guidelines on using abbreviations. |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Bad |
| (defvar *default-username* "Ann") |
| (defvar *max-widget-cnt* 200) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (defvar *default-user-name* "Ann") |
| (defvar *maximum-widget-count* 200) |
| </CODE_SNIPPET> |
| <p> |
| There are conventions in Common Lisp |
| for the use of punctuation in symbols. |
| You should not use punctuation in symbols outside these conventions. |
| </p> |
| <p> |
| Unless the scope of a variable is very small, |
| do not use overly short names like |
| <code>i</code> and <code>zq</code>. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Denote intent, not content"> |
| <SUMMARY> |
| Name your variables according to their intent, |
| not their content. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| Thus, you should avoid embedding |
| data structure or aggregate type names, |
| such as <code>list</code>, <code>array</code>, or |
| <code>hash-table</code> 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 |
| <code>list</code> or <code>array</code>. |
| </p> |
| <p> |
| Indeed, you should be introducing new abstract data types |
| with <code>DEFCLASS</code> or <code>DEFTYPE</code>, |
| 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. |
| </p> |
| <p> |
| For example, if a variable's value is always a row |
| (or is either a row or <code>NIL</code>), |
| it's good to call it <code>row</code> or <code>first-row</code> |
| or something like that. |
| It is alright is <code>row</code> has been |
| <code>DEFTYPE</code>'d to <code>STRING</code> — |
| 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 <code>STRING</code> in this context, |
| except possibly in low-level functions that specifically manipulate |
| the innards of rows to provide the suitable abstraction. |
| </p> |
| <p> |
| Be consistent. |
| If a variable is named <code>row</code> in one function, |
| and its value is being passed to a second function, |
| then call it <code>row</code> rather than, say, <code>value</code> |
| (this was a real case). |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Global variables and constants"> |
| <SUMMARY> |
| Name globals according to convention. |
| </SUMMARY> |
| <BODY> |
| <p> |
| The names of global constants should start and end |
| with plus characters. |
| </p> |
| <p> |
| Global variable names should start and end with asterisks |
| (also known in this context as earmuffs). |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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 <code>DEFINE-SYMBOL-MACRO</code>. |
| You should not use this trick, |
| unless you first publish a library that abstracts it away. |
| </p> |
| <CODE_SNIPPET> |
| (defconstant +hash-results+ #xbd49d10d10cbee50) |
| |
| (defvar *maximum-search-depth* 100) |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Predicate names"> |
| <SUMMARY> |
| Names of predicate functions and variables end with a <code>"P"</code>. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You should name boolean-valued functions and variables with a |
| trailing <code>"P"</code> or <code>"-P"</code>, |
| to indicate they are predicates. |
| Generally, you should use |
| <code>"P"</code> when the rest of the function name is one word |
| and <code>"-P"</code> when it is more than one word. |
| </p> |
| <p> |
| A rationale for this convention is given in |
| <a href="http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node69.html">the CLtL2 chapter on predicates</a>. |
| </p> |
| <p> |
| For uniformity, you should follow the convention above, |
| and not one of the alternatives below. |
| </p> |
| <p> |
| An alternative rule used in some existing packages |
| is to always use <code>"-P"</code>. |
| Another alternative rule used in some existing packages |
| is to always use <code>"?"</code>. |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Omit library prefixes"> |
| <SUMMARY> |
| You should not include a library or package name |
| as a prefix within the name of symbols. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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). |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Bad |
| (in-package #:varint) |
| (defun varint-length64 () ... ) |
| |
| (in-package #:client-code) |
| (defconst +padding+ (varint:varint-length64 +end-token+)) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (in-package #:varint) |
| (defun length64 () ... ) |
| |
| (in-package #:client-code) |
| (defconst +padding+ (varint:length64 +end-token+)) |
| </CODE_SNIPPET> |
| <p> |
| 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, <code>ASDF</code> exports a variable <code>*ASDF-VERBOSE*</code> |
| that controls the verbosity of <code>ASDF</code> only, |
| rather than of the entire Lisp program. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Packages"> |
| <SUMMARY> |
| Use packages appropriately. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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 <code>::</code> construct. |
| (e.g. <code>QUAKE::HIDDEN-FUNCTION</code>). |
| If you need to use double-colons to write real production code, |
| something is wrong and needs to be fixed. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| The <code>::</code> 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| Each package is one of two types: |
| </p> |
| <ul> |
| <li> |
| Intended to be included |
| in the <code>:use</code> specification of other packages. |
| If package <code>A</code> "uses" package <code>B</code>, |
| then the external symbols of package <code>B</code> |
| can be referenced from within package <code>A</code> |
| without a package prefix. |
| We mainly use this for low-level modules |
| that provide widely-used facilities. |
| </li> |
| <li> |
| Not intended to be "used". |
| To reference a facility provided by package <code>B</code>, |
| code in package <code>A</code> must use an explicit package prefix, |
| e.g. <code>B:DO-THIS</code>. |
| </li> |
| </ul> |
| <p> |
| 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 <code>FIFO</code>, |
| and it were in a package of the first type |
| you'd have functions named things like |
| <code>FIFO-ADD-TO</code> and <code>FIFO-CLEAR-ALL</code>. |
| If you used a package of the second type, |
| you'd have names like <code>ADD-TO</code> and <code>CLEAR-ALL</code>, |
| because the callers would be saying |
| <code>FIFO:ADD-TO</code> and <code>FIFO:CLEAR-ALL</code>. |
| (<code>FIFO:FIFO-CLEAR-ALL</code> is redundant and ugly.) |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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: |
| </p> |
| <ul> |
| <li> |
| If you are explicitly replacing a Common Lisp symbol |
| by a safer or more featureful version. |
| </li> |
| <li> |
| 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 <code>log:error</code> and <code>log:warn</code> |
| and so on. |
| </li> |
| </ul> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="Language usage guidelines"> |
| <STYLEPOINT title="Mostly Functional Style"> |
| <SUMMARY> |
| You should avoid side-effects when they are not necessary. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Lisp is best used as a "mostly functional" language. |
| </p> |
| <p> |
| Avoid modifying local variables, try rebinding instead. |
| </p> |
| <p> |
| Avoid creating objects and the SETFing their slots. |
| It's better to set the slots during initialization. |
| </p> |
| <p> |
| Make classes as immutable as possible, that is, avoid giving slots |
| setter functions if at all possible. |
| </p> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Recursion"> |
| <SUMMARY> |
| You should favor iteration over recursion. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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: |
| </p> |
| <ul> |
| <li> |
| The <code>(DECLARE (OPTIMIZE ...))</code> settings |
| must favor <code>SPEED</code> enough and |
| not favor <code>DEBUG</code> too much, |
| for some compiler-dependent meanings of "enough" and "too much". |
| (For instance, in SBCL, you should avoid <code>(SPEED 0)</code> |
| and <code>(DEBUG 3)</code> to achieve proper tail calls.) |
| </li> |
| <li> |
| 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). |
| </li> |
| </ul> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Special variables"> |
| <SUMMARY> |
| Use special variables sparingly. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Assignment"> |
| <SUMMARY> |
| Be consistent in assignment forms. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| Regarding multiple assignment in a same form, there are two schools: |
| the first style groups as many assignments as possible into a single |
| <code>SETF</code> or <code>PSETF</code> form |
| thus minimizing the number of forms with side-effects; |
| the second style splits assignments into as many individual |
| <code>SETF</code> (or <code>SETQ</code>, see below) forms as possible, |
| to maximize the chances of locating forms that modify a kind of place |
| by grepping for <code>(setf (foo ...</code>. |
| 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. |
| </p> |
| <p> |
| Regarding <code>SETF</code> and <code>SETQ</code>, |
| there are two schools: |
| this first regards <code>SETQ</code> |
| as an archaic implementation detail, |
| and avoids it entirely in favor of <code>SETF</code>; |
| the second regards <code>SETF</code> |
| as an additional layer of complexity, |
| and avoids it in favor of <code>SETQ</code> 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Assertions and Conditions"> |
| <SUMMARY> |
| You must make proper usage of assertions and conditions. |
| </SUMMARY> |
| <BODY> |
| <ul> |
| <li> |
| <code>ASSERT</code> should be used ONLY to detect internal bugs. |
| Code should <code>ASSERT</code> 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 <code>ASSERT</code> failure is a developer. |
| Do not use the data-form and argument-form in <code>ASSERT</code> |
| 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). |
| </li> |
| <li> |
| <code>CHECK-TYPE</code>, |
| <code>ETYPECASE</code> are also forms of assertion. |
| When one of these fails, that's a detected bug. |
| You should prefer to use <code>CHECK-TYPE</code> |
| over (DECLARE (TYPE ...)) |
| for the inputs of functions. |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| <code>ERROR</code> should be used |
| to detect problems with user data, requests, permissions, etc., |
| or to report "unusual outcomes" to the caller. |
| </li> |
| <li> |
| <code>ERROR</code> should always be called |
| with an explicit condition type; |
| it should never simply be called with a string. |
| This enables internationalization. |
| </li> |
| <li> |
| 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. |
| </li> |
| <li> |
| Complex bug-checks may need to use <code>ERROR</code> |
| instead of <code>ASSERT</code>. |
| |
| </li> |
| <li> |
| When writing a server, you must not call <code>WARN</code>. |
| Instead, you should use the appropriate logging framework. |
| |
| </li> |
| <li> |
| Code must not call <code>SIGNAL</code>. |
| Instead, use <code>ERROR</code> or <code>ASSERT</code>. |
| </li> |
| <li> |
| Code should not use <code>THROW</code> and <code>CATCH</code>; |
| instead use the <code>restart</code> facility. |
| </li> |
| <li> |
| Code should not generically handle all conditions, |
| e.g. type <code>T</code>, or use <code>IGNORE-ERRORS</code>. |
| Instead, let unknown conditions propagate to |
| the standard ultimate handler for processing. |
| |
| </li> |
| <li> |
| 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 <em>do</em> need to handle "all conditions", |
| you MUST handle only <code>ERROR</code>, <em>not</em> <code>T</code> |
| and not <code>SERIOUS-CONDITION</code>. |
| (This is notably because CCL's process shutdown |
| depends on being able to signal <code>process-reset</code> |
| and have it handled by CCL's handler, |
| so we must not interpose our own handler.) |
| </li> |
| <li> |
| <code>(error (make-condition 'foo-error ...))</code> |
| is equivalent to <code>(error 'foo-error ...)</code> — |
| code must use the shorter form. |
| </li> |
| <li> |
| Code should not signal conditions from inside the cleanup form of |
| <code>UNWIND-PROTECT</code> |
| (unless they are always handled inside the cleanup form), |
| or otherwise do non-local exits from cleanup handlers |
| outside of the handler e.g. <code>INVOKE-RESTART</code>. |
| </li> |
| <li> |
| 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_CODE_SNIPPET> |
| ;; Bad |
| (handler-case |
| (catch 'ticket-at |
| (etd-process-blocks)) |
| (error (c) |
| (reset-parser-values) |
| (error c))) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (unwind-protect |
| (catch 'ticket-at |
| (etd-process-blocks)) |
| (reset-parser-values)) |
| </CODE_SNIPPET> |
| </li> |
| </ul> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Type Checking"> |
| <SUMMARY> |
| If you know the type of something, you should make it explicit |
| in order to enable compile-time and run-time sanity-checking. |
| </SUMMARY> |
| <BODY> |
| |
| <p> |
| If your function is using a special variable as an implicit argument, |
| it's good to put in a <code>CHECK-TYPE</code> 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. |
| </p> |
| |
| <p> |
| Using <code>(declare (type ...))</code> |
| is the least-desirable mechanism to use |
| because, as Scott McKay puts it: |
| </p> |
| <blockquote> |
| <p> |
| The fact is, <code>(declare (type ...))</code> does different things |
| depending on the compiler settings of speed, safety, etc. |
| In some compilers, when speed is greater than safety, |
| <code>(declare (type ...))</code> will tell the compiler |
| "please assume that these variables have these types" |
| <em>without</em> generating any type-checks. |
| That is, if some variable has the value <code>1432</code> in it, |
| and you declare it to be of type <code>string</code>, |
| the compiler might just go ahead and use it as though it's a string. |
| </p> |
| <p> |
| Moral: don't use <code>(declare (type ...))</code> |
| to declare the contract of any API functions, |
| it's not the right thing. |
| Sure, use it for "helper" functions, but not API functions. |
| </p> |
| </blockquote> |
| <p> |
| 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 |
| <a href="#Unsafe_Operations">Unsafe Operations</a>. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="CLOS"> |
| <SUMMARY> |
| Use CLOS appropriately. |
| </SUMMARY> |
| <BODY> |
| <p> |
| When a generic function is intended to be called from other |
| modules (other parts of the code), there should be an |
| explicit <code>DEFGENERIC</code> form, |
| with a <code>:DOCUMENTATION</code> string |
| explaining the generic contract of the function |
| (as opposed to its behavior for some specific class). |
| It's generally good to do explicit <code>DEFGENERIC</code> forms, |
| but for module entry points it is mandatory. |
| </p> |
| <p> |
| When the argument list of a generic function includes |
| <code>&KEY</code>, |
| the <code>DEFGENERIC</code> 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.) |
| </p> |
| <p> |
| You should avoid <code>SLOT-VALUE</code> and <code>WITH-SLOTS</code>, |
| unless you absolutely intend to circumvent |
| any sort of method combination that might be in effect for the slot. |
| Rare exceptions include <code>INITIALIZE-INSTANCE</code> |
| and <code>PRINT-OBJECT</code> methods and |
| accessing normally hidden slots in the low-level implementation of |
| methods that provide user-visible abstractions. |
| Otherwise, you should use accessors, |
| <code>WITH-ACCESSORS</code> |
| </p> |
| |
| <p> |
| Accessor names generally follow a convention of |
| <code><protocol-name>-<slot-name></code>, |
| where a "protocol" in this case loosely indicates |
| a set of functions with well-defined behavior. |
| </p> |
| <p> |
| No implication of a formal "protocol" concept is necessarily intended, |
| much less first-class "protocol" objects. |
| However, there may indeed be an abstract CLOS class |
| or an |
| <a href="http://common-lisp.net/~frideau/lil-ilc2012/lil-ilc2012.html">Interface-Passing Style</a> interface |
| that embodies the protocol. |
| Further (sub)classes or (sub)interfaces may then implement |
| all or part of a protocol by defining |
| some methods for (generic) functions in the protocol, |
| including readers and writers. |
| </p> |
| <p> |
| For example, if there were a notional protocol called |
| is <code>pnr</code> with accessors <code>pnr-segments</code> |
| and <code>pnr-passengers</code>, then |
| the classes <code>air-pnr</code>, <code>hotel-pnr</code> and |
| <code>car-pnr</code> could each reasonably implement |
| methods for <code>pnr-segments</code> and <code>pnr-passengers</code> |
| as accessors. |
| </p> |
| <p> |
| By default, an abstract base class name is used |
| as the notional protocol name, so accessor names default |
| to <code><class-name>-<slot-name></code>; |
| 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. |
| </p> |
| <p> |
| Accessors named <code><slot-name>-of</code> should not be used. |
| </p> |
| <p> |
| Explicit <code>DEFGENERIC</code> forms should be used when there are |
| (or it is anticipated that there will be) |
| more than one <code>DEFMETHOD</code> 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). |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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 <code>DEFGENERIC</code> for each method. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| If a class definition creates a method |
| as a <code>:READER</code>, <code>:WRITER</code>, |
| or <code>:ACCESSOR</code>, |
| do not redefine that method. |
| It's OK to add <code>:BEFORE</code>, <code>:AFTER</code>, |
| and <code>:AROUND</code> methods, |
| but don't override the primary method. |
| </p> |
| <p> |
| In methods with keyword arguments, |
| you must always use <code>&KEY</code>, |
| even if the method does not care about the values of any keys, |
| and you should never use <code>&ALLOW-OTHER-KEYS</code>. |
| 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 <code>INITIALIZE-INSTANCE</code> methods, |
| since if you did use <code>&ALLOW-OTHER-KEYS</code>, |
| it would disable error checking for misspelled or wrong keywords |
| in <code>MAKE-INSTANCE</code> calls! |
| </p> |
| |
| <p> |
| A typical <code>PRINT-OBJECT</code> method might look like this: |
| </p> |
| <CODE_SNIPPET> |
| (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)))) |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="Meta-language guidelines"> |
| <STYLEPOINT title="Macros"> |
| <SUMMARY> |
| Use macros when appropriate, which is often. |
| Define macros when appropriate, which is seldom. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| The general conclusion is that there shouldn't be |
| any recognizable <em>design pattern</em> |
| in a good Common Lisp program. |
| The one and only pattern is: <em>use the language</em>, |
| which includes defining and using syntactic abstractions. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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 <code>FOO</code>, |
| document the need and profiling-results appropriately, |
| and |
| <code>(declaim (inline foo))</code>. |
| </p> |
| |
| <p> |
| 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. |
| </p> |
| <p> |
| When you write a macro-defining macro |
| (a macro that generates macros), |
| document and comment it particularly clearly, |
| since these are harder to understand. |
| </p> |
| <p> |
| 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 |
| <code>cl-syntax</code> or <code>named-readtables</code> |
| 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. |
| </p> |
| <p> |
| 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 <code>-form</code>. |
| 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 <code>body</code> and <code>end</code> are |
| exceptions to this rule. |
| </p> |
| <p> |
| You should follow the so-called <code>CALL-WITH</code> style when it applies. |
| This style is explained at length in |
| <a href="http://random-state.net/log/3390120648.html">http://random-state.net/log/3390120648.html</a>. |
| 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 <code>WITH-<em>FOO</em></code> is often limited to |
| generating a call to an auxiliary function |
| <code>CALL-WITH-<em>FOO</em></code> |
| with arguments deduced from the macro arguments. |
| Macro <code>&body</code> 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. |
| </p> |
| <p> |
| The separation of syntactic and semantic concerns |
| is a general principle of style that applies |
| beyond the case of <code>WITH-</code> 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. |
| </p> |
| <p> |
| Any functions (closures) created by the macro should be named, |
| which can be done using <code>FLET</code>. |
| |
| This also allows you to declare the function to be of dynamic extent |
| (if it is — and often it is; yet see below regarding |
| <a href="#DYNAMIC-EXTENT">DYNAMIC-EXTENT</a>). |
| </p> |
| <p> |
| 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 <code>ALEXANDRIA:ONCE-ONLY</code> |
| that generates code to do this. |
| See also <code>ALEXANDRIA:WITH-GENSYMS</code>, |
| to make some temporary variables in the generated code. |
| Note that if you follow our <code>CALL-WITH</code> 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. |
| </p> |
| <p> |
| When you write a macro with a body, |
| such as a <code>WITH-xxx</code> macro, |
| even if there aren't any parameters, |
| you should leave space for them anyway. |
| For example, if you invent <code>WITH-LIGHTS-ON</code>, |
| do not make the call to it look like |
| <code>(defmacro with-lights-on (&body b) ...)</code>. |
| Instead, do <code>(defmacro with-lights-on (() &body b) ...)</code>. |
| That way, if parameters are needed in the future, |
| you can add them without necessarily having to change |
| all the uses of the macro. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="EVAL-WHEN"> |
| <SUMMARY> |
| When using <code>EVAL-WHEN</code>, you should almost always use all of |
| <code>(:compile-toplevel :load-toplevel :execute)</code>. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Lisp evaluation happens at several times, |
| some of them interleaved. |
| Be aware of them when writing macros. |
| <a href="http://fare.livejournal.com/146698.html">EVAL-WHEN considered harmful to your mental health</a>. |
| </p> |
| <p> |
| In summary of the article linked above, |
| unless you're doing truly advanced macrology, |
| the only valid combination in an <code>EVAL-WHEN</code> |
| is to include all of |
| <code>(eval-when (:compile-toplevel :load-toplevel :execute) ...)</code> |
| </p> |
| <p> |
| You must use |
| <code>(eval-when (:compile-toplevel :load-toplevel :execute) ...)</code> |
| whenever you define functions, types, classes, constants, variables, etc., |
| that are going to be used in macros. |
| </p> |
| <p> |
| It is usually an error to omit the <code>:execute</code>, |
| because it prevents <code>LOAD</code>ing the source rather than the fasl. |
| It is usually an error to omit the <code>:load-toplevel</code> |
| (except to modify e.g. readtables and compile-time settings), |
| because it prevents <code>LOAD</code>ing future files |
| or interactively compiling code |
| that depends on the effects that happen at compile-time, |
| unless the current file was <code>COMPILE-FILE</code>d |
| within the same Lisp session. |
| </p> |
| <p> |
| 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: |
| </p> |
| <ul> |
| <li> |
| 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 <code>LOAD-TIME-VALUE</code> for good effect. |
| In extreme cases, you may have to use |
| <code>ASDF-FINALIZERS:EVAL-AT-TOPLEVEL</code>. |
| </li> |
| <li> |
| 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 <code>*readtable*</code> |
| or compiler-internal variables holding |
| the current optimization settings. |
| You can often manage existing and new such variables using |
| the <code>:AROUND-COMPILE</code> hooks of <code>ASDF</code>. |
| </li> |
| </ul> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Read-time evaluation"> |
| <SUMMARY> |
| You should use <code>#.</code> sparingly, |
| and you must avoid read-time side-effects. |
| </SUMMARY> |
| <BODY> |
| <p> |
| The <code>#.</code> standard read-macro |
| will read one object, evaluate the object, and |
| have the reader return the resulting value. |
| </p> |
| <p> |
| You must not use it where other idioms will do, such as |
| using <code>EVAL-WHEN</code> to evaluate side-effects at compile-time, |
| using a regular macro to return an expression computed at compile-time, |
| using <code>LOAD-TIME-VALUE</code> to compute it at load-time. |
| </p> |
| <p> |
| 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 <code>#.</code> 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. |
| </p> |
| <p> |
| Another use of <code>#.</code> 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. |
| </p> |
| <p> |
| Whenever you are going to use <code>#.</code>, |
| you should consider using <code>DEFCONSTANT</code> and its variants, |
| possibly in an <code>EVAL-WHEN</code>, |
| to give the value a name explaining what it means. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="EVAL"> |
| <SUMMARY> |
| You must not use <code>EVAL</code> at runtime. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Places where it is actually appropriate to use <code>EVAL</code> |
| are so few and far between that you must consult with your reviewers; |
| it's easily misused. |
| </p> |
| <p> |
| If your code manipulates symbols at runtime |
| and needs to get the value of a symbol, |
| use <code>SYMBOL-VALUE</code>, not <code>EVAL</code>. |
| </p> |
| <p> |
| Often, what you really need is to write a macro, |
| not to use <code>EVAL</code>. |
| </p> |
| <p> |
| You may be tempted to use <code>EVAL</code> 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 <code>EVAL</code> |
| than to build a special-purpose evaluator. |
| You must not use <code>EVAL</code> in this way at runtime. |
| </p> |
| <p> |
| Places where it is OK to use <code>EVAL</code> are: |
| </p> |
| <ul> |
| <li> |
| The implementation of an interactive development tool. |
| </li> |
| <li> |
| The build infrastructure. |
| </li> |
| <li> |
| Backdoors that are part of testing frameworks. |
| (You MUST NOT have such backdoors in production code.) |
| </li> |
| <li> |
| Macros that fold constants at compile-time. |
| </li> |
| <li> |
| 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. |
| </li> |
| </ul> |
| <p> |
| 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 <code>DEFTYPE</code> expansion, |
| or in helper functions used by macros. |
| In these cases, you may actually have to use |
| <code>ASDF-FINALIZERS:EVAL-AT-TOPLEVEL</code> in your macro. |
| It will not only <code>EVAL</code> your definitions |
| at macro-expansion time for immediate availability, |
| it will also save the form aside, for inclusion in a |
| <code>(ASDF-FINALIZERS:FINAL-FORMS)</code> |
| 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. |
| <code>ASDF-FINALIZERS</code> ensures that the form is present, |
| by throwing an error if you omit it. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="INTERN and UNINTERN"> |
| <SUMMARY> |
| You must not use <code>INTERN</code> or <code>UNINTERN</code> at runtime. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You must not use <code>INTERN</code> 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. |
| </p> |
| <p> |
| You must not <code>INTERN</code> a string |
| just to compare it to a keyword; |
| use <code>STRING=</code> or <code>STRING-EQUAL</code>. |
| </p> |
| <BAD_CODE_SNIPPET> |
| (member (intern str :keyword) $keys) ; Bad |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| (member str $keys :test #'string-equal) ; Better |
| </CODE_SNIPPET> |
| <p> |
| You must not use <code>UNINTERN</code> 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. |
| </p> |
| <p> |
| You may of course use <code>INTERN</code> 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 |
| <code>ALEXANDRIA:SYMBOLICATE</code> or |
| <code>ALEXANDRIA:FORMAT-SYMBOL</code> |
| to create the symbols you need. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="Data Representation"> |
| <STYLEPOINT title="NIL: empty-list, false and I Don't Know"> |
| <SUMMARY> |
| Appropriately use or avoid using <code>NIL</code>. |
| </SUMMARY> |
| <BODY> |
| <p> |
| <code>NIL</code> can have several different interpretations: |
| </p> |
| <ul> |
| <li> |
| "False." |
| In this case, use <code>NIL</code>. |
| You should test for false <code>NIL</code> |
| using the operator <code>NOT</code> or |
| using the predicate function <code>NULL</code>. |
| </li> |
| <li> |
| "Empty-list." |
| In this case, use <code>'()</code>. |
| (Be careful about quoting the empty-list when calling macros.) |
| You should use <code>ENDP</code> to test for the empty list |
| when the argument is known to be a proper list, |
| or with <code>NULL</code> otherwise. |
| </li> |
| <li> |
| A statement about some value being unspecified. |
| In this case, you may use <code>NIL</code> |
| if there is no risk of ambiguity anywhere in your code; |
| otherwise you should use an explicit, descriptive symbol. |
| </li> |
| <li> |
| A statement about some value being known not to exist. |
| In this case, you should use an explicit, descriptive symbol |
| instead of <code>NIL</code>. |
| </li> |
| </ul> |
| <p> |
| 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 <code>NIL</code> for either. |
| If you do use <code>NIL</code>, |
| you must make sure that the distinction is well documented. |
| </p> |
| <p> |
| 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. |
| </p> |
| |
| <p> |
| When working with database classes, keep in mind that |
| <code>NIL</code> need not always map to <code>'NULL'</code> |
| (and vice-versa)! |
| The needs of the database may differ from the needs of the Lisp. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Do not abuse lists"> |
| <SUMMARY> |
| You must select proper data representation. |
| You must not abuse the <code>LIST</code> data structure. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| You must not abuse the builtin (single-linked) <code>LIST</code> |
| data structure where it is not appropriate, |
| even though Common Lisp makes it especially easy to use it. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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). |
| </p> |
| <p> |
| 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.) |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| In the many cases when lists are not the appropriate data structure, |
| various libraries such as |
| <a href="http://cliki.net/cl-containers">cl-containers</a> or |
| <a href="http://cliki.net/lisp-interface-library">lisp-interface-library</a> |
| 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 |
| <a href="#Using_Libraries">Using Libraries</a> and |
| <a href="#Open-Sourcing_Code">Open-Sourcing Code</a>. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Lists vs. structures vs. multiple values"> |
| <SUMMARY> |
| You should use the appropriate representation for product types. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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 <code>APPLY</code> a function. |
| </p> |
| <p> |
| The proper way to pass around an object |
| comprising several values of heterogeneous types |
| is to use a structure as defined by <code>DEFSTRUCT</code> |
| or <code>DEFCLASS</code>. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| You should signal a condition to denote an unusual outcome, |
| rather than relying on a special return type. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Lists vs. Pairs"> |
| <SUMMARY> |
| Use the appropriate functions when manipulating lists. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Use <code>FIRST</code> to access the first element of a list, |
| <code>SECOND</code> to access the second element, etc. |
| Use <code>REST</code> to access the tail of a list. |
| Use <code>ENDP</code> to test for the end of the list. |
| </p> |
| <p> |
| Use <code>CAR</code> and <code>CDR</code> |
| 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 <code>NULL</code> to test for <code>NIL</code> in this context. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| Exceptionally, you may use <code>CDADR</code> and other variants |
| on lists when manually destructuring them, |
| instead of using a combination of several list accessor functions. |
| In this context, using <code>CAR</code> and <code>CDR</code> |
| instead of <code>FIRST</code> and <code>REST</code> also makes sense. |
| However, keep in mind that it might be more appropriate in such cases |
| to use higher-level constructs such as |
| <code>DESTRUCTURING-BIND</code> or <code>OPTIMA:MATCH</code>. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Lists vs. Arrays"> |
| <SUMMARY> |
| You should use arrays rather than lists where random access matters. |
| </SUMMARY> |
| <BODY> |
| <p> |
| <code>ELT</code> has <i>O(n)</i> behavior when used on lists. |
| If you are to use random element access on an object, |
| use arrays and <code>AREF</code> instead. |
| </p> |
| <p> |
| The exception is for code outside the critical path |
| where the list is known to be small anyway. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Lists vs. Sets"> |
| <SUMMARY> |
| You should only use lists as sets for very small lists. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Using lists as representations of sets is a bad idea |
| unless you know the lists will be small, |
| for accessors are <i>O(n)</i> instead of <i>O(log n)</i>. |
| For arbitrary big sets, use balanced binary trees, |
| for instance using <code>lisp-interface-library</code>. |
| </p> |
| <p> |
| If you still use lists as sets, |
| you should not <code>UNION</code> lists just to search them. |
| </p> |
| <BAD_CODE_SNIPPET> |
| (member foo (union list-1 list-2)) ; Bad |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| (or (member foo list-1) (member foo list-2)) ; Better |
| </CODE_SNIPPET> |
| <p> |
| Indeed, <code>UNION</code> not only conses unnecessarily, |
| but it can be <i>O(n^2)</i> on some implementations, |
| and is rather slow even when it's <i>O(n)</i>. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="Proper Forms"> |
| <p> |
| You must follow the proper usage regarding |
| well-known functions, macros and special forms. |
| </p> |
| <STYLEPOINT title="Defining Constants"> |
| <SUMMARY> |
| You must use proper defining forms for constant values. |
| </SUMMARY> |
| <BODY> |
| <p> |
| The Lisp system we primarily use, SBCL, is very picky and |
| signals a condition whenever a constant is redefined to a value not |
| <code>EQL</code> to its previous setting. |
| You must not use <code>DEFCONSTANT</code> |
| when defining variables that are not |
| numbers, characters, or symbols (including booleans and keywords). |
| Instead, consistently use whichever alternative |
| is recommended for your project. |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Bad |
| (defconstant +google-url+ "http://www.google.com/") |
| (defconstant +valid-colors+ '(red green blue)) |
| </BAD_CODE_SNIPPET> |
| |
| |
| |
| |
| <p> |
| Open-Source libraries may use |
| <code>ALEXANDRIA:DEFINE-CONSTANT</code> |
| for constants other than numbers, characters and symbols |
| (including booleans and keywords). |
| You may use the <code>:TEST</code> keyword argument |
| to specify an equality predicate. |
| </p> |
| <CODE_SNIPPET> |
| ;; Better, for Open-Source code: |
| (define-constant +google-url+ "http://www.google.com/" :test #'string=) |
| (define-constant +valid-colors+ '(red green blue)) |
| </CODE_SNIPPET> |
| <p> |
| Note that with optimizing implementations, such as SBCL or CMUCL, |
| defining constants this way precludes any later redefinition |
| short of <code>UNINTERN</code>ing the symbol |
| and recompiling all its clients. |
| This may make it "interesting" to debug things at the REPL |
| or to deploy live code upgrades. |
| If there is a chance that your "constants" are not going to be constant |
| over the lifetime of your server processes |
| after taking into consideration scheduled and unscheduled code patches, |
| you should consider using |
| <code>DEFPARAMETER</code> or <code>DEFVAR</code> instead, |
| or possibly a variant of <code>DEFINE-CONSTANT</code> |
| that builds upon some future library implementing global lexicals |
| rather than <code>DEFCONSTANT</code>. |
| You may keep the <code>+plus+</code> convention in these cases |
| to document the intent of the parameter as a constant. |
| </p> |
| <p> |
| Also note that <code>LOAD-TIME-VALUE</code> may help you |
| avoid the need for defined constants. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Defining Functions"> |
| <SUMMARY> |
| You should make proper use of |
| <code>&OPTIONAL</code> and |
| <code>&KEY</code> arguments. |
| You should not use <code>&AUX</code> arguments. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You should avoid using <code>&ALLOW-OTHER-KEYS</code>, |
| 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 <code>(DECLARE (IGNORE ...))</code> |
| all the arguments that you are not using. |
| You must not use <code>&ALLOW-OTHER-KEYS</code> |
| 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 <code>DEFGENERIC</code>, not in the <code>DEFMETHOD</code> |
| which is basically an "implementation detail" of the generic function |
| as far as the caller of the generic is concerned. |
| </p> |
| <p> |
| A case where <code>&ALLOW-OTHER-KEYS</code> 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 <code>&REST</code> argument. |
| </p> |
| <p> |
| You should avoid using <code>&AUX</code> arguments. |
| </p> |
| <p> |
| You should avoid having both <code>&OPTIONAL</code> |
| and <code>&KEY</code> arguments, |
| unless it never makes sense to specify keyword arguments |
| when the optional arguments are not all specified. |
| You must not have non-<code>NIL</code> defaults |
| to your <code>&OPTIONAL</code> arguments |
| when your function has both <code>&OPTIONAL</code> |
| and <code>&KEY</code> arguments. |
| </p> |
| <p> |
| For maximum portability of a library, it is good form |
| that <code>DEFMETHOD</code> definitions should |
| <code>(DECLARE (IGNORABLE ...))</code> |
| all the required arguments that they are not using. |
| Indeed, some implementations will issue a warning |
| if you <code>(DECLARE (IGNORE ...))</code> those arguments, |
| whereas other implementations will issue a warning |
| if you fail to <code>(DECLARE (IGNORE ...))</code> them. |
| <code>(DECLARE (IGNORABLE ...))</code> works on all implementations. |
| </p> |
| <p> |
| 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 <code>FARE-UTILS:NEST</code> |
| to at least reduce the amount of indentation required. |
| It is bad form to use <code>NEST</code> 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. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Conditional Expressions"> |
| <SUMMARY> |
| Use the appropriate conditional form. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Use <code>WHEN</code> and <code>UNLESS</code> |
| when there is only one alternative. |
| Use <code>IF</code> when there are two alternatives |
| and <code>COND</code> when there are several. |
| </p> |
| <p> |
| However, don't use <code>PROGN</code> for an <code>IF</code> clause |
| — use <code>COND</code>, <code>WHEN</code>, or <code>UNLESS</code>. |
| </p> |
| <p> |
| Note that in Common Lisp, |
| <code>WHEN</code> and <code>UNLESS</code> return <code>NIL</code> |
| when the condition is not met. |
| You may take advantage of it. |
| Nevertheless, you may use an <code>IF</code> |
| to explicitly return <code>NIL</code> |
| if you have a specific reason to insist on the return value. |
| You may similarly include a fall-through clause <code>(t nil)</code> |
| as the last in your <cond>COND</cond>, |
| or <code>(otherwise nil)</code> as the last in your <cond>CASE</cond>, |
| 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. |
| </p> |
| <p> |
| You should prefer <code>AND</code> and <code>OR</code> |
| when it leads to more concise code than using |
| <code>IF</code>, <code>COND</code>, |
| <code>WHEN</code> or <code>UNLESS</code>, |
| and there are no side-effects involved. |
| You may also use an <code>ERROR</code> |
| as a side-effect in the final clause of an <code>OR</code>. |
| </p> |
| <p> |
| You should only use <code>CASE</code> and <code>ECASE</code> |
| to compare numbers, characters or symbols |
| (including booleans and keywords). |
| Indeed, <code>CASE</code> uses <code>EQL</code> for comparisons, |
| so strings, pathnames and structures may not compare the way you expect, |
| and <code>1</code> will differ from <code>1.0</code>. |
| </p> |
| <p> |
| You should use <code>ECASE</code> and <code>ETYPECASE</code> |
| in preference to <code>CASE</code> and <code>TYPECASE</code>. |
| It is better to catch erroneous values early. |
| </p> |
| <p> |
| You should not use <code>CCASE</code> or <code>CTYPECASE</code> 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. |
| </p> |
| <p> |
| You must not use gratuitous single quotes in <code>CASE</code> forms. |
| This is a common error: |
| </p> |
| <BAD_CODE_SNIPPET> |
| (case x ; Bad: silently returns NIL on mismatch |
| ('bar :bar) ; Bad: catches QUOTE |
| ('baz :baz)) ; Bad: also would catch QUOTE |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| (ecase x ; Better: will error on mismatch |
| ((bar) :bar) ; Better: won't match QUOTE |
| ((baz) :baz)) ; Better: same reason |
| </CODE_SNIPPET> |
| <p> |
| <code>'BAR</code> there is <code>(QUOTE BAR)</code>, |
| meaning this leg of the case will be executed |
| if <code>X</code> is <code>QUOTE</code>... |
| and ditto for the second leg |
| (though <code>QUOTE</code> will be caught by the first clause). |
| This is unlikely to be what you really want. |
| </p> |
| <p> |
| In <code>CASE</code> forms, |
| you must use <code>otherwise</code> instead of <code>t</code> |
| when you mean "execute this clause if the others fail". |
| You must use <code>((t) ...)</code> |
| when you mean "match the symbol T" rather than "match anything". |
| You must also use <code>((nil) ...)</code> |
| when you mean "match the symbol NIL" rather than "match nothing". |
| </p> |
| <p> |
| Therefore, if you want to map booleans <code>NIL</code> and <code>T</code> |
| to respective symbols <code>:BAR</code> and <code>:QUUX</code>, |
| you should avoid the former way and do it the latter way: |
| </p> |
| <BAD_CODE_SNIPPET> |
| (ecase x ; Bad: has no actual error case! |
| (nil :bar)) ; Bad: matches nothing |
| (t :quux)) ; Bad: matches anything |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| (ecase x ; Better: will actually catch non-booleans |
| ((nil) :bar)) ; Better: matches NIL |
| ((t) :quux)) ; Better: matches T |
| </CODE_SNIPPET> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Identity, Equality and Comparisons"> |
| <SUMMARY> |
| You should the appropriate predicates when comparing objects. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Lisp provides four general equality predicates: |
| <code>EQ</code>, <code>EQL</code>, <code>EQUAL</code>, |
| and <code>EQUALP</code>, |
| which subtly vary in semantics. |
| Additionally, Lisp provides the type-specific predicates |
| <code>=</code>, <code>CHAR=</code>, <code>CHAR-EQUAL</code>, |
| <code>STRING=</code>, and <code>STRING-EQUAL</code>. |
| Know the distinction! |
| </p> |
| <p> |
| You should use <code>EQL</code> to compare objects and symbols |
| for <em>identity</em>. |
| </p> |
| <p> |
| You must not use <code>EQ</code> to compare numbers or characters. |
| Two numbers or characters that are <code>EQL</code> |
| are not required by Common Lisp to be <code>EQ</code>. |
| </p> |
| <p> |
| When choosing between <code>EQ</code> and <code>EQL</code>, |
| you should use <code>EQL</code> unless you are writing |
| performance-critical low-level code. |
| <code>EQL</code> 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 <code>EQ</code>, |
| although under SBCL, it often compiles away entirely. |
| <code>EQ</code> is equivalent to <code>EQL</code> and type declarations, |
| and use of it for optimization should be treated just like |
| any such <a href="#Unsafe_Operations">unsafe operations</a>. |
| </p> |
| <p> |
| You should use <code>CHAR=</code> |
| for case-dependent character comparisons, |
| and <code>CHAR-EQUAL</code> for case-ignoring character comparisons. |
| </p> |
| <p> |
| You should use <code>STRING=</code> |
| for case-dependent string comparisons, |
| and <code>STRING-EQUAL</code> for case-ignoring string comparisons. |
| </p> |
| <p> |
| A common mistake when using <code>SEARCH</code> on strings |
| is to provide <code>STRING=</code> or <code>STRING-EQUAL</code> |
| as the <code>:TEST</code> function. |
| The <code>:TEST</code> function |
| is given two sequence elements to compare. |
| If the sequences are strings, |
| the <code>:TEST</code> function is called on two characters, |
| so the correct tests are <code>CHAR=</code> or <code>CHAR-EQUAL</code>. |
| If you use <code>STRING=</code> or <code>STRING-EQUAL</code>, |
| 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. |
| </p> |
| <p> |
| Also, you should use <code>:START</code> and <code>:END</code> arguments |
| to <code>STRING=</code> or <code>STRING-EQUAL</code> |
| instead of using <code>SUBSEQ</code>; |
| e.g. <code>(string-equal (subseq s1 2 6) s2)</code> should instead be |
| <code>(string-equal s1 s2 :start1 2 :end1 6)</code> |
| This is preferable because it does not cons. |
| </p> |
| <p> |
| You should use <code>ZEROP</code>, |
| <code>PLUSP</code>, or <code>MINUSP</code>, |
| instead of comparing a value to <code>0</code> or <code>0.0</code>. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| You must use <code>=</code> to compare numbers, |
| unless you really mean for <code>0</code>, |
| <code>0.0</code> and <code>-0.0</code> to compare unequal, |
| in which case you should use <code>EQL</code>. |
| Then again, you must not usually use exact comparison |
| on floating point numbers. |
| </p> |
| <p> |
| Monetary amounts should be using decimal (rational) numbers |
| to avoid the complexities and rounding errors |
| of floating-point arithmetic. |
| Libraries such as |
| <a href="http://wukix.com/lisp-decimals">wu-decimal</a> |
| may help you; |
| once again, if this library is not satisfactory, see above about |
| <a href="#Using_Libraries">Using Libraries</a> and |
| <a href="#Open-Sourcing_Code">Open-Sourcing Code</a>. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Iteration"> |
| <SUMMARY> |
| Use the appropriate form for iteration. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You should simpler forms such as |
| <code>DOLIST</code> or <code>DOTIMES</code> |
| instead of <code>LOOP</code> |
| in simple cases when you're not going to use any |
| of the <code>LOOP</code> facilities such as |
| bindings, collection or block return. |
| </p> |
| <p> |
| Use the <code>WITH</code> clause of <code>LOOP</code> |
| when it will avoid a level of nesting with <code>LET</code>. |
| You may use <code>LET</code> if it makes it clearer |
| to return one of bound variables after the <code>LOOP</code>, |
| rather than use a clumsy <code>FINALLY (RETURN ...)</code> form. |
| </p> |
| <p> |
| In the body of a <code>DOTIMES</code>, |
| do not set the iteration variable. |
| (CCL will issue a compiler warning if you do.) |
| </p> |
| <p> |
| Most systems use unadorned symbols in the current package |
| as <code>LOOP</code> keywords. |
| Other systems use actual <code>:keywords</code> |
| from the <code>KEYWORD</code> package |
| as <code>LOOP</code> keywords. |
| You must be consistent with the convention used in your system. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="I/O"> |
| <SUMMARY> |
| Use the appropriate I/O functions. |
| </SUMMARY> |
| <BODY> |
| <p> |
| When writing a server, |
| code must not send output to the standard streams such as |
| <code>*STANDARD-OUTPUT*</code> or <code>*ERROR-OUTPUT*</code>. |
| Instead, code must use the proper logging framework |
| to output messages for debugging. |
| We are running as a server, so there is no console! |
| </p> |
| <p> |
| Code must not use <code>PRINT-OBJECT</code> |
| to communicate with a user — |
| <code>PRINT-OBJECT</code> is for debugging purposes only. |
| Modifying any <code>PRINT-OBJECT</code> method |
| must not break any public interfaces. |
| </p> |
| <p> |
| You should not use a sequence of <code>WRITE-XXX</code> |
| where a single <code>FORMAT</code> string could be used. |
| Using format allows you |
| to parameterize the format control string in the future |
| if the need arises. |
| </p> |
| <p> |
| You should use <code>WRITE-CHAR</code> to emit a character |
| rather than <code>WRITE-STRING</code> |
| to emit a single-character string. |
| </p> |
| <p> |
| You should not use <code>(format nil "~A" value)</code>; |
| you should use <code>PRINC-TO-STRING</code> instead. |
| </p> |
| <p> |
| You should use <code>~<Newline></code> |
| or <code>~@<Newline></code> in format strings |
| to keep them from wrapping in 100-column editor windows, |
| or to indent sections or clauses to make them more readable. |
| </p> |
| <p> |
| You should not use <code>STRING-UPCASE</code> |
| or <code>STRING-DOWNCASE</code> |
| on format control parameters; |
| instead, it should use <code>"~:@(~A~)"</code> or <code>"~(~A~)"</code>. |
| </p> |
| <p> |
| Be careful when using the <code>FORMAT</code> conditional directive. |
| The parameters are easy to forget. |
| </p> |
| <dl> |
| <dt>No parameters, e.g. <code>"~[Siamese~;Manx~;Persian~] Cat"</code></dt> |
| <dd> |
| 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 <code>":"</code> in front of the last <code>";"</code>. |
| E.g. in <code>"~[Siamese~;Manx~;Persian~:;Alley~] Cat"</code>, |
| an out-of-range arg prints <code>"Alley"</code>. |
| </dd> |
| <dt><code>:</code> parameter, e.g. <code>"~:[Siamese~;Manx~]"</code></dt> |
| <dd> |
| Take one format argument. If it's <code>NIL</code>, |
| use the first clause, otherwise use the second clause. |
| </dd> |
| <dt><code>@</code> parameter, e.g. <code>"~@[Siamese ~a~]"</code></dt> |
| <dd> |
| 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.) |
| </dd> |
| <dt><code>#</code> parameter, e.g. <code>"~#[ none~; ~s~; ~s and ~s~]"</code></dt> |
| <dd> |
| 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: |
| <code>"Items:~#[ none~; ~S~; ~S and ~S~:;~@{~#[~; and~] ~S~^ ,~}~]."</code> |
| </dd> |
| </dl> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="Optimization"> |
| <STYLEPOINT title="Avoid Allocation"> |
| <SUMMARY> |
| You should avoid unnecessary allocation of memory. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| <p> |
| You should be careful that when you create objects, |
| you don't leave them reachable after they are no longer needed! |
| </p> |
| <p> |
| 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). |
| </p> |
| <p> |
| Don't cons (i.e., allocate) unnecessarily. |
| Garbage collection is not magic. |
| Excessive allocation is usually a performance problem. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Unsafe Operations"> |
| <SUMMARY> |
| You must only use faster unsafe operations |
| when there is a clear performance need |
| and you can document why it's correct. |
| </SUMMARY> |
| <BODY> |
| <p> |
| 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. |
| </p> |
| |
| <p> |
| 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. |
| </p> |
| <p> |
| 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 <code>check-type</code> in functions exported from a package |
| to sanitize input arguments, |
| so that internal functions are never passed illegal values. |
| </p> |
| <p> |
| On some compilers, |
| new unsafe operations |
| can usually be defined by combining |
| type declarations with an <code>OPTIMIZE</code> declaration |
| that has sufficiently high <code>SPEED</code> and low <code>SAFETY</code>. |
| In addition to providing more speed for production code, |
| such declarations may more helpful |
| than <code>check-type</code> 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. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="DYNAMIC-EXTENT"> |
| <SUMMARY> |
| You should only use <code>DYNAMIC-EXTENT</code> |
| where it matters for performance, |
| and you can document why it is correct. |
| </SUMMARY> |
| <BODY> |
| <p> |
| <code>DYNAMIC-EXTENT</code> declarations are |
| a particular case of |
| <a href="#Unsafe_Operations">unsafe operations</a>. |
| </p> |
| <p> |
| The purpose of a <code>DYNAMIC-EXTENT</code> 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. |
| </p> |
| <p> |
| By declaring a variable or a local function <code>DYNAMIC-EXTENT</code>, |
| the programmer <em>asserts</em> 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. |
| </p> |
| <p> |
| 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: |
| </p> |
| <ul> |
| <li> |
| The lists created to store <code>&REST</code> parameters. |
| </li> |
| <li> |
| Lists, vectors and structures allocated within a function. |
| </li> |
| <li> |
| Closures. |
| </li> |
| </ul> |
| <p> |
| If the assertion is wrong, i.e. if the programmer's claim is not true, |
| the results can be <em>catastrophic</em>: |
| 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! |
| </p> |
| <p> |
| Even if the assertion is correct, |
| future changes to the function might introduce |
| a violation of the assertion. |
| This increases the danger. |
| </p> |
| <p> |
| In most cases, such objects are ephemeral. |
| Modern Lisp implementations use generational garbage collectors, |
| which are quite efficient under these circumstances. |
| </p> |
| <p> |
| Therefore, <code>DYNAMIC-EXTENT</code> declarations |
| should be used sparingly. You must only use them if: |
| </p> |
| <ol> |
| <li> |
| There is some good reason to think that the overall effect |
| on performance is noticeable, and |
| </li> |
| <li> |
| It is absolutely clear that the assertion is true. |
| </li> |
| <li> |
| It is quite unlikely that the code will be changed |
| in ways that cause the declaration to become false. |
| </li> |
| </ol> |
| <p> |
| 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". |
| </p> |
| <p> |
| 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 |
| <code>DYNAMIC-EXTENT</code>, 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 <code>DYNAMIC-EXTENT</code>. |
| </p> |
| <p> |
| 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.) |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="REDUCE vs APPLY"> |
| <SUMMARY> |
| You should use <code>REDUCE</code> |
| instead of <code>APPLY</code> where appropriate. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You should use <code>REDUCE</code> |
| instead of <code>APPLY</code> and a consed-up list, |
| where the semantics of the first operator argument |
| otherwise guarantees the same semantics. |
| Of course, you must use <code>APPLY</code> |
| if it does what you want and <code>REDUCE</code> doesn't. |
| For instance: |
| </p> |
| <BAD_CODE_SNIPPET> |
| ;; Bad |
| (apply #'+ (mapcar #'acc frobs)) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| ;; Better |
| (reduce #'+ frobs :key #'acc :initial-value 0) |
| </CODE_SNIPPET> |
| <p> |
| This is preferable because it does not do extra consing, |
| and does not risk going beyond <code>CALL-ARGUMENTS-LIMIT</code> |
| 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). |
| </p> |
| <p> |
| However, you must be careful not to use <code>REDUCE</code> |
| in ways that needlessly increase |
| the complexity class of the computation. |
| For instance, <code>(REDUCE 'STRCAT ...)</code> is <i>O(n^2)</i> |
| when an appropriate implementation is only <i>O(n)</i>. |
| Moreover, <code>(REDUCE 'APPEND ...)</code> |
| is also <i>O(n^2)</i> unless you specify <code>:FROM-END T</code>. |
| In such cases, you MUST NOT use <code>REDUCE</code>, |
| and you MUST NOT use <code>(APPLY 'STRCAT ...)</code> |
| or <code>(APPLY 'APPEND ...)</code> 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 <code>UIOP:REDUCE/STRCAT</code>. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Avoid NCONC"> |
| <SUMMARY> |
| You should not use <code>NCONC</code>; |
| you should use <code>APPEND</code> instead, |
| or better, better data structures. |
| </SUMMARY> |
| <BODY> |
| <p> |
| You should almost never use <code>NCONC</code>. |
| You should use <code>APPEND</code> |
| when you don't depend on any side-effect. |
| You should use <code>ALEXANDRIA:APPENDF</code> |
| when you need to update a variable. |
| You should probably not depend on games |
| being played with the <code>CDR</code> |
| 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 <code>NCONC</code>; |
| and you should probably reconsider your data representation strategy. |
| </p> |
| <p> |
| By extension, you should avoid <code>MAPCAN</code> |
| or the <code>NCONC</code> feature of <code>LOOP</code>. |
| You should instead respectively use |
| <code>ALEXANDRIA:MAPPEND</code> |
| and the <code>APPEND</code> feature of <code>LOOP</code>. |
| </p> |
| <p> |
| <code>NCONC</code> is very seldom a good idea, |
| since its time complexity class is no better than <code>APPEND</code>, |
| its space complexity class also is no better than <code>APPEND</code> |
| in the common case where no one else is sharing the side-effected list, |
| and its bug complexity class is way higher than <code>APPEND</code>. |
| </p> |
| <p> |
| If the small performance hit due |
| to <code>APPEND</code> vs. <code>NCONC</code> |
| 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. |
| </p> |
| <p> |
| You may only use <code>NCONC</code>, <code>MAPCAN</code> |
| or the <code>NCONC</code> feature of <code>LOOP</code> |
| 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. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <CATEGORY title="Pitfalls"> |
| <STYLEPOINT title="#'FUN vs. 'FUN"> |
| <SUMMARY> |
| You should usually refer to a function as <code>#'FUN</code> rather than <code>'FUN</code>. |
| </SUMMARY> |
| <BODY> |
| <p> |
| The former, which reads as <code>(FUNCTION FUN)</code>, |
| refers to the function object, and is lexically scoped. |
| The latter, which reads as <code>(QUOTE FUN)</code>, |
| refers to the symbol, which when called |
| uses the global <code>FDEFINITION</code> of the symbol. |
| </p> |
| <p> |
| When using functions that take a functional argument |
| (e.g., <code>MAPCAR</code>, <code>APPLY</code>, |
| <code>:TEST</code> and <code>:KEY</code> arguments), |
| you should use the <code>#'</code> to refer to the function, |
| not just single quote. |
| </p> |
| <p> |
| An exception is when you explicitly want dynamic linking, |
| because you anticipate that |
| the global function binding will be updated. |
| </p> |
| <p> |
| 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. |
| </p> |
| <p> |
| You must consistently use either <code>#'(lambda ...)</code> |
| or <code>(lambda ...)</code> without <code>#'</code> everywhere. |
| Unlike the case of <code>#'symbol</code> vs <code>'symbol</code>, |
| 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. |
| <code>#'</code> may be seen as a hint |
| that you're introducing a function in expression context; |
| but the <code>lambda</code> 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. |
| </p> |
| <p> |
| Note that if you start writing a new system |
| in a heavily functional style, |
| you may consider using |
| <a href="http://cliki.net/lambda-reader">lambda-reader</a>, |
| a system that lets you use the unicode character <code>λ</code> |
| instead of <code>LAMBDA</code>. |
| But you must not start using such a syntactic extension |
| in an existing system without getting permission from other developers. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="Pathnames"> |
| <SUMMARY> |
| Common Lisp pathnames are tricky. Be aware of pitfalls. Use <code>UIOP</code>. |
| </SUMMARY> |
| <BODY> |
| <p> |
| It is surprisingly hard to properly deal with pathnames in Common Lisp. |
| </p> |
| <p> |
| <code>ASDF 3</code> comes with a portability library <code>UIOP</code> |
| that makes it <em>much</em> easier to deal with pathnames |
| portably — and correctly — in Common Lisp. |
| You should use it when appropriate. |
| </p> |
| <p> |
| 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 <code>#\.</code> and <code>#\*</code>, etc., |
| in addition to the quoting of |
| <code>#\\</code> and <code>#\"</code> 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. |
| </p> |
| <p> |
| Second, when using <code>MERGE-PATHNAMES</code>, |
| be wary of the treatment of the <code>HOST</code> component, |
| which matters a lot on non-Unix platforms |
| (and even on some Unix implementations). |
| You probably should be using |
| <code>UIOP:MERGE-PATHNAMES*</code> |
| instead of <code>MERGE-PATHNAMES</code>, |
| 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 |
| <code>*DEFAULT-PATHNAME-DEFAULTS*</code> |
| at the time the relative pathname was created. |
| </p> |
| <p> |
| Third, be aware that <code>DIRECTORY</code> |
| is not portable across implementations |
| in how it handles wildcards, sub-directories, symlinks, etc. |
| There again, <code>UIOP</code> provides several |
| common abstractions to deal with pathnames. |
| </p> |
| <p> |
| <code>LOGICAL-PATHNAME</code>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 <code>ASDF:SYSTEM-RELATIVE-PATHNAME</code> or |
| the underlying <code>UIOP:SUBPATHNAME</code> and |
| <code>UIOP:PARSE-UNIX-NAMESTRING</code>. |
| </p> |
| |
| <p> |
| 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. |
| <code>ASDF</code> for instance requires you to reset its paths |
| with <code>ASDF:CLEAR-CONFIGURATION</code>. |
| <code>UIOP</code> provides hooks |
| to call functions before an image is dumped, |
| from which to reset or <code>makunbound</code> relevant variables. |
| </p> |
| |
| </BODY> |
| </STYLEPOINT> |
| <STYLEPOINT title="SATISFIES"> |
| <SUMMARY> |
| You must be careful when using a <code>SATISFIES</code> clause in a type specifier. |
| </SUMMARY> |
| <BODY> |
| <p> |
| Most Common Lisp implementations can't optimize |
| based on a <code>SATISFIES</code> type, |
| but many of them offer simple optimizations |
| based on a type of the form |
| <code>(AND FOO (SATISFIES BAR-P))</code> |
| where the first term of the <code>AND</code> clause |
| describes the structure of the object |
| without any <code>SATISFIES</code> |
| and the second term is the <code>SATISFIES</code>. |
| </p> |
| <BAD_CODE_SNIPPET> |
| (deftype prime-number () (satisfies prime-number-p)) ; Bad |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| (deftype prime-number () (and integer (satisfies prime-number-p)) ; Better |
| </CODE_SNIPPET> |
| <p> |
| However, <code>AND</code> in the <code>DEFTYPE</code> 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 <code>INTEGER</code>ness |
| to protect the function <code>PRIME-NUMBER-P</code> |
| from being supplied non-integer arguments |
| to test for being of instances of the type. |
| Implementations may, and some <em>will</em>, |
| invoke <code>SATISFIES</code>-specified function |
| at compile-time to test various relevant objects. |
| </p> |
| <p> |
| That is why any function specified in a <code>SATISFIES</code> clause |
| MUST accept objects of any type as argument to the function, |
| and MUST be defined within an <code>EVAL-WHEN</code> |
| (as well as any variable it uses or function it calls): |
| </p> |
| <BAD_CODE_SNIPPET> |
| (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)))) |
| </BAD_CODE_SNIPPET> |
| <CODE_SNIPPET> |
| (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)))))) |
| </CODE_SNIPPET> |
| <p> |
| In particular, the above means that the |
| <a href="http://www.lispworks.com/documentation/HyperSpec/Body/t_satisf.htm">example</a> |
| used in the Common Lisp Standard is erroneous: |
| <code>(and integer (satisfies evenp))</code> |
| is <em>not</em> a safe, conformant type specifier to use, |
| because <code>EVENP</code> will throw an error |
| rather than return <code>NIL</code> |
| when passed a non-integer as an argument. |
| </p> |
| <p> |
| Finally, there is a catch when your <code>DEFTYPE</code> code expands |
| to a <code>SATISFIES</code> with a dynamically generated function: |
| </p> |
| <ul> |
| <li> |
| You cannot control when implementations will or will not |
| expand a <code>DEFTYPE</code>. |
| </li> |
| <li> |
| The expansion itself cannot contain a function definition |
| or any code in the expression language. |
| </li> |
| <li> |
| You cannot control when the expansion is used, |
| it may happen in a different process |
| that didn't expand the definition. |
| </li> |
| </ul> |
| <p> |
| Therefore, you cannot merely create the function |
| as a side-effect of expansion |
| using <code>EVAL</code> at type-expansion time. |
| The solution is to use |
| <code>ASDF-FINALIZERS:EVAL-AT-TOPLEVEL</code> instead. |
| See the very last point |
| in the discussion about <a href="#EVAL">EVAL</a>. |
| </p> |
| <p> |
| Common Lisp is hard to satisfy. |
| </p> |
| </BODY> |
| </STYLEPOINT> |
| </CATEGORY> |
| |
| <HR/> |
| |
| <small>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. |
| </small> |
| |
| <p align="right"> |
| Revision 1.23 |
| </p> |
| |
| |
| <address> |
| Robert Brown |
| </address> |
| |
| <address> |
| <a HREF="mailto:tunes@google.com">François-René Rideau</a> |
| </address> |
| |
| |
| |
| </GUIDE> |