Common Lisp Style Guide
lisp-lang.org
lisp-lang.org
The code in Norvig's book "Paradigms of Artificial Intelligence Programming" is enjoyable to read as well. As a pdf the book itself is freely available: https://github.com/norvig/paip-lisp
And then of course there's the classic Costanza guide at http://www.p-cos.net/lisp/guide.html (not so much about style per se) that contains an important remark, "There cannot be "the one definitive guide" to Lisp. What I present here is what I would have liked to have seen in the first place. Other people probably prefer a different approach."
A quick glance at the broader open source ecosystem will show anyone that most projects don't follow this particular style guide, or this guide is silent on certain things that are probably considered good form enough to put in a company guide, like using uninterned symbols for packages, or using qlot for version pinning your dependencies and having reproducible builds in your CI system, or using UIOP for anything to do with file paths, or... One needs to get comfortable loading a system and then using the usual cross-referencing features of an editor (emacs, vim, atom (https://atom.io/packages/slima), really anything that can talk to a swank server...) since reading code will be the surest way to understand it, especially when it might not be laid out as you expect.
In my projects I often find myself wishing for some actually comprehensive and written down guide to maintain consistency and elegance. It's hard to do it entirely in your head. I mean, even a multitude of these would be fine if they'd be explicit and followed. Let's build roads through this wilderness. One day I'll get around to (also) doing it myself ;p
The OP is quite short, but the Google guide they cite and some ones linked by others here seem interesting.
One thing I'd like sorted is naming CLOS writers and accessors as opposed to readers. I feels that it should be somehow communicated what they are.
I'd love to see more apps, innovations, success stories and use cases.
That perception needs to change if you want it to gain more traction among developers.
Can you expound upon what you realized here, and why it made Common Lisp seem more appealing?
First, using libraries is great but it always comes at a cost so that I’m always performing a cost-benefit analysis before I choose a third party library. The best case is that the library is well-written, well-documented and close to authoritative, meaning it attempts to maximally cover the problem domain (and not just solve small parts of the domain, typically those parts that scratch the itches of the developer). A lot of libraries out there are far from the best case. Most Common Lisp libraries out there are very far from best case.
Second, writing libraries or as the CL Style Guide puts it: “In short: write many small libraries (and I’ll add here the implied when solving a specific problem).” This sounds nice in theory but I find that it often falls apart in practice. Most developers that set out to solve a problem are focused on the problem and it’s hard to get them to decompose that problem into libraries that are best-case. Far more typically, if they do end up decomposing the problem into libraries, they will do so in haste and will only do the minimum. Or they may not yet possess sufficient understanding of the domain that would let them write a “best-case” library. This leads to a proliferation of libraries with similar functionality, with no clear “winner”. No clear “best-case” library for others to use.
Thus we see the conflict between the two statements. I would reword them as such:
+ Use third party libraries but perform a cost-benefit analysis before doing so.
+ Only write libraries (meant for others to reuse) if you are willing to put in the best-case effort. If you are writing such a library, then do attempt to minimize third party dependencies. It makes it a lot easier for others to do a cost-benefit analysis and also more probable that your library will end up used. Choose best-case libraries to depend on.
The things we’re trying to avoid are duplication of effort, expansion of the library space with similar libraries - no standouts - that end up confusing newcomers and dependency hell where it becomes expensive to do a cost-benefit analysis.
That might be the missing distinction here. Avoid writing monolithic projects; you aren't going to turn every sub-module into a standalone library for other people to use, but the modularity will help you and your project anyway, and then you or someone else could spin off your code if they wanted to.
EDIT: to be more clear, my single git repo contains as subdirectories all libraries I write as well as all applications I write that use my libraries and other people’s libraries in Quicklisp. I almost always provide Makefile files to create standalone applications for each non-library I write so I don’t have to run code in a repl unless I am developing.
you take something like this
(defpackage my-package
(:use :cl)
(:import-from :alexandria
:with-gensyms
:curry))
and you want to add an item to the list.. so you need to change the :curry)) line to be :curry and then add a new item. anyone have a workaround?Of course if you had a lisp with no parans then you'd never have this problem to start with...
defpackage my-package
:use :cl
:import-from :alexandria
:with-gensyms
:curry
:new-thingy
"Indentation is two lines per form"Emacs seems to always do one space for Elisp and Clojure and two spaces for 'let' and 'if' forms. or did I screw something up in my init file?
So, I would think it's not a thing that can be solved with style guidelines, maybe a different diffing paradigm that handles elements addition or deletion from a list?
In any case, the obvious solution is to add your new element as the new third entry, if you care about this.
Now, moving on to this article, I agree with the parts of it that are directly influenced by the language, as that's clearly how one should write it; this isn't unique to this document nor to Common Lisp. I've had people criticize my Common Lisp just because I use parts of the language they weren't aware of or don't care for, which I find silly; people also enjoy trying to enforce usage rules where none exist and don't like seeing those broken, such as using #1= and #1# to indicate duplicated code where it's not otherwise easy to express.
I disagree with using libraries merely because they exist. What, a lack of libraries is bad, but don't write more? In any case, I make certain all of my libraries are rather comprehensive and well-documented; that's not much in the way of advice, though, since it's obvious. Common Lisp libraries aren't likely to change significantly, especially after several years, which is nice.
As for indentation, I generally use whatever Emacs gives me, except for LOOP, where I indent how I prefer it look; generally, two spaces is the indentation level, but here's an example where that isn't the case:
(list 1
2)
I agree with the line length note, as eighty is an asinine limit. I disagree with the comment conventions; I use a single semicolon for all of my comments.I use OR and AND for flow control more than WHEN or UNLESS, but this is my preference. There's nothing wrong with an IF that doesn't use both paths and claiming otherwise is silly arbitrary ruling. I further disagree with keeping conditions short; defining an entire function for a single condition is stupid.
Having a single package to a file is treating Common Lisp like other languages; it's completely unnecessary. Avoiding :USE is another asinine quality of this style guide; again, libraries are unlikely to change significantly and you can always avoid using the most recent version. Using hierarchical names is a bad idea, since they're not actually hiararchical, but this could trick others into believing they are and, again, pretends Common Lisp is some other language.
Lastly, I try to have my programs and libraries in a single file. What's nicer, looking through a single file or skulking around a large directory with many small files; I'll always prefer the former. If a file isn't even one thousand lines, why would you even consider breaking it into many files as other, poor languages are prone to do?
This recommendation of ''Continuous Integration'' has nothing whatsoever to do with Common Lisp style and Common Lisp isn't a language that needs this.
In brief, I don't care for this style guide, but it paints itself as authorative. My advice is to use Emacs and mimic the standard language where you can and, otherwise, do as you please until you derive your own rules; don't listen to others if you don't care to, although I believe my advice is good, you may disagree.
Also in this particular case you don't have to put :new-thingy after :curry. They can be in any order, it doesn't matter at all.
I do remember that convention though, and it makes sense. I just found your usages in text interesting.
Fun observation :)
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node84.html
Very much a "stylistic preference" though!
Edit: I realised that for the 6 years or so I wrote CL as part of my day job that my well thumbed copy of CLtL was by far the most referenced programming language book I have ever used (mostly falling open at either the loop or CLOS chapters). Not sure what this says about CL!