March 2013
2 posts
Formatting integers in different radixes
format has four directives for formatting integers with different radixes:
~B formats as binary: (format nil "~B" 42) => "101010"
~O formats as octal: (format nil "~O" 42) => "52"
~X formats as hexadecimal: (format nil "~X" 666) => "29A"
~R formats with an arbitrary radix between 2 and 36: (format nil "~36R" 18321) => "E4X"
Each directive takes padding and pad-character options...
Literal syntax for integers
There are several ways to write literal integers with different radixes in Common Lisp. #b… is for binary, #o… is for octal, #x… is for hexadecimal, and #r is for an arbitrary radix from 2 to 36. Section 2.4.8.10 has this example:
#2r11010101 ;Another way of writing 213 decimal
#b11010101 ;Ditto
#b+11010101 ;Ditto ...
How do I convert an integer to a list of bits?
Novices sometimes ask how to get a convert an integer to a list of bits, often for the purpose of iterating over the bits somehow. Common Lisp has a rich set of functions for directly accessing the bits of an integer, so constructing an intermediate list of bits is rarely necessary.
Here are a few examples of accessing the bits of an integer.
With integer-length and logbitp to test the bit at a...
February 2013
5 posts
The optional arguments of deftype
deftype can be used to create user-defined types that expand into built-in types. For example:
(deftype octet-vector (length)
`(simple-array (unsigned-byte 8) (,length)))
Given this deftype, in a type context, (octet-vector 32) expands into (simple-array (unsigned-byte 8) (32)), or a one-dimensional octet array of length 32.
Lambda lists for deftype are very similar to lambda lists for...
Trying again with with-simple-restart
I have some code that reads data from a config file. If there’s a problem loading, I’d like the opportunity to fix it, outside of Lisp, and retry loading. It’s easy to do that with with-simple-restart and loop:
(loop
(with-simple-restart (try-again "Try again")
(return
(progn
(setf *config* (load-config-file))))
If any error occurs during load-config-file,...
Semicolon style
The standard explains common semicolon comment style in section 2.4.4.2. Section 2.4.4.2.5 includes this short example showing typical use of one through four semicolons:
;;;; Math Utilities
;;; FIB computes the the Fibonacci function in the traditional
;;; recursive way.
(defun fib (n)
(check-type n integer)
;; At this point we're sure we have an integer argument.
;; Now we can get down...
The tree-walkers of CL
If you need to visit a tree in some way, there are two built-in functions that, while not explicitly designed for the purpose, can walk a tree effectively.
First, subst-if takes a predicate function that is called for each cons and atom in a tree. As long as the predicate returns nil, no substitution will actually take place.
Here’s a simple way to turn it into a function:
(defun walk-tree...
December 2012
1 post
Duplicated keyword arguments
If a function call has two pairs of keyword arguments with the same keyword, the leftmost argument pair is used. This can be helpful if a list of keyword arguments is received and you want to selectively override some value in that argument list in application. There’s no need to use mutation or produce a fresh variation of the list.
For example:
(defun write-escaped (object &rest args...
October 2012
1 post
The four causes of symbol conflicts
A symbol conflict arises when a package operation would result in two distinct symbols with the same name being accessible in a single package. There are exactly four ways this can happen.
Inheriting: When you use (via use-package or the defpackage :use clause) a package that exports a distinct symbol sharing the same name with a symbol already accessible in the using package. The conflict can...
September 2012
7 posts
A little bit of file-position
When used with one argument, file-position returns an integer representing the stream’s file position:
* (defvar *s* (open "data.bin" :element-type '(unsigned-byte 8))
=> *S*
* (read-byte *s*)
=> 42
* (read-byte *s*)
=> 107
* (file-position *s*)
=> 2
When used with two arguments, file-position sets the stream position:
* (file-position *s* 1)
=> T
* (read-byte *s*)
=>...
A brief history of Lisp
For a 1500-word history of Lisp up to the point of Common Lisp standardization, see section 1.1.2 of the spec. It covers the institutions, projects, people, and influential ideas involved in the creation and evolution of Lisp over the course of several decades, from McCarthy at Dartmouth in the 1950s to the many active branches of Lisp in the 1980s.
Putting the R in REPL
Try this in your REPL:
* (let (#'42) (+ . #'5))
=> 47
If you find it perplexing, and you use SBCL, evaluating + next in the REPL might help clear things up.
Using an adjustable displaced array as a cursor on...
Scanning a string can be done using input functions withwith-input-from-string:
(with-input-from-string (stream "Hello World! How do you do? ")
(let ((c (make-string 4)))
(loop
:for pos = (read-sequence c stream)
:while (= pos (length c))
:do (print c)
:finally (terpri))))
"Hell"
"o Wo"
"rld!"
" Ho"
"w do"
" you"
" do?"
nil
This can also be done using a...
Binding keyword arguments
By default, keyword argument variable bindings match the name of the keyword used to pass the value. For example:
(defun keytest (&key foo)
(list foo))
* (keytest :foo 42)
=> (42)
However, the variable doesn’t have to match the keyword provided. The following syntax will accept a keyword of :foo in the function call but bind a variable named bar:
(defun keytest (&key ((:foo...
Multiple export clauses in defpackage
The syntax for defpackage allows multiple export clauses. I like to use this feature to visually group related symbols.
(defpackage #:myproject
(:use #:cl)
;; Web stuff
(:export #:fetch
#:parse-url
#:status)
;; File utilities
(:export #:lines
#:first-line
#:touch)
...)
Although it has no effect on the semantics, I find it helpful for...
A simple REPL
Here’s a very simple REPL that includes the *, **, and *** variables:
(defun repl ()
(princ "> ")
(loop
(shiftf *** ** * (eval (read)))
(format t "~a~&> " *)))
Provided by Stas Boukarev.
April 2012
1 post
Printing package-qualified symbols
When *print-escape* is true, symbols are normally printed with package prefixes only if the current package *package* is not the symbol’s home package. It’s easy to make sure that a symbol is always printed with a package prefix, e.g. for debugging.
When the current package is the keyword package, non-keyword symbols are printed with package prefixes, and keywords are printed with...
January 2012
2 posts
Evaluating the last expression
In the REPL, +, ++, and +++ have as values the three most recently evaluated expressions. A quick way to evaluate the previous expression, especially handy in a REPL without input history, is
#.+
It’s equivalent to (eval +).
(Thanks to Anton Kovalenko.)
Un-displacing an array
Here’s a function to get the underlying array on which a displaced array is based:
(defun undisplace-array (array)
"Return the fundamental array and the start and end positions into
it of a displaced array."
(let ((length (length array))
(start 0))
(loop
(multiple-value-bind (to offset) (array-displacement array)
(if to
(setq array to
...
December 2011
3 posts
Referring to method parameters
In defmethod lambda lists, required parameters that aren’t explicitly specialized default to specializing on the system class t. But there’s a difference between an implicit and explicit specialization on t. The hyperspec explains:
The expansion of the defmethod macro “refers to” each specialized parameter (see the description of ignore within the description of declare)....
Describing objects
Everyone writes new methods for print-object for specialized printing of their own objects. But the output of describe can be specialized as well via describe-object. For example, if you have an object that has a vector of keys and a corresponding vector of values, the standard describe output might not show them in a way that’s very readable:
* (describe record)
#<RECORD...
Forcing buffered output
Many CL implementations (SBCL in particular) perform output in a buffered manner. Sometimes this may cause a confusion, because it may reverse the order of effects. Like in the following example it may be possible to enter something before seeing ‘?’.
(defun ask () (princ '?) (read))
Also if you are writing an application, that should interact with some other program (for...
November 2011
3 posts
String functions
Common Lisp has relatively few functions that work exclusively on strings. There is no function, for example, to extract a substring from a string. However, strings are defined as specialized vectors of character objects. Since vectors are sequences, all the sequence-related functions also apply to strings. To extract a substring from a string, use subseq.
A concatenated stream trick
If you pass a stream to a library function that closes it (as with with-open-stream), but you want the stream to remain open, you can wrap the stream in a concatenated stream:
(auto-closing-function (make-concatenated-stream my-stream))
When the concatenated stream is closed, the wrapped stream my-stream remains open.
(Thanks to Rob Warnock for this tip.)
Working on multidimensional arrays
What to use if you have a multidimensional array and you want to do something to each element?
row-major-aref can access an element in a multidimensional array with a single index. array-total-size returns the total number of elements in an array. Together, you can do something like this:
(dotimes (i (array-total-size array))
(incf (row-major-aref array i) 42))
You can also displace a...
October 2011
24 posts
Initialize a vector with map-into
Novices who want an array of distinct things sometimes write something like this, where make-foo returns a fresh object of some sort:
(make-array 42 :initial-element (make-foo))
This actually creates a vector containing the same identical (eq) object at all 42 indexes. The initial-element argument is evaluated only once to produce the result, and the result is used 42 times to initialize the...
Graham Crackers
If you’re trying to learn Common Lisp from Paul Graham’s ANSI Common Lisp (which I don’t recommend), be sure to read Graham Crackers. These course notes outline some of the cases where the style of ANSI Common Lisp differs from good Common Lisp style.
Division shortcuts
floor, truncate, and related functions can take an optional second argument to use as the divisor. The default value is the integer 1. Instead of (floor (/ x 42)) you can use (floor x 42).
:initform and :default-initargs
There are two means of automatic initialization of CLOS slot values, :initform and :default-initargs. Chris Riesbeck makes a strong case for preferring :default-initargs.
Here’s a simplified example of the syntactic difference, taken from some Quicklisp code. Consider modeling version control commands with CLOS. Here’s a possible design:
(defclass vc-command ()
((command
...
Multiple value division
floor, truncate, and related functions return multiple values for division-related operations: the quotient, and the remainder. There are several situations where both values are useful.
For example, if you have a vector of octet values and you want to find the value of a particular bit, you can use something like this:
(defun bit-ref (octet-vector index)
(multiple-value-bind (octet-index...
The Common Lisp and Unix epochs
The Common Lisp epoch begins at 00:00 on January 1, 1900, GMT. get-universal-time returns a universal time, defined as the number of seconds elapsed since then.
The Unix epoch begins at 00:00 on January 1, 1970, GMT. time() returns the number of seconds elapsed since then.
It’s easy to get the difference between a Common Lisp universal time and a Unix epoch timestamp:
*...
"How do I apply AND?"
I sometimes see a question like this: “I have a list of things and I want to see if they’re all true, so how can I apply ‘and’ to it?” Since and is a macro, it can’t be applied, but there are standard functions that can answer the question instead.
(every #’identity list) will return nil as soon as it encounters any nil entries in list, and true if no...
Controlling loop flow with simple restarts
Sometimes you know in advance how you want to change control flow in a loop. Other times you might want to defer that decision by offering a restart. For example, here’s a loop with a pair of with-simple-restarts:
(with-simple-restart (stop-processing "Stop processing users")
(dolist (user (pending-user-list))
(with-simple-restart (skip "Skip user ~A" user)
(process-user...
Slow pretty-printing
Producing “pretty” output can be time consuming. Some implementations do a lot of work to determine whether to e.g. break lines when printing with functions like print and format.
If printing is a bottleneck and aesthetic output isn’t required, binding or setting *print-pretty* to NIL can significantly improve output speed for some implementations.
(setf values)
To assign the multiple return values of a function to multiple variables, you could use this:
(multiple-value-setq (whole partial) (truncate x 1024))
(setf values) is more general, and works on places:
(setf (values whole partial) (truncate x 1024))
(setf (values (aref v 0) (aref v 1)) (truncate x 1024))
Fine-grained control flow
The “do” macros (do, do*, dolist, and dotimes) have bodies that act like tagbody. You can put go tags anywhere in the body and use go to jump to them from arbitrary places. This can be useful for skipping, retrying, or otherwise changing the flow of iteration.
For example:
(dolist (users (get-user-list))
:retry
...
(when some-condition
(go :retry)
...)
Comparing many objects
The numeric comparison functions =, /=, <, <=, >, and >= can take more than two arguments. This is handy to e.g. check if several variables have monotonically increasing numeric value:
(< a b c d)
For numbers in a sufficiently short list, apply does the trick:
(apply #'< list)
Non-numeric comparison functions generally take exactly two objects to compare, so e.g. (string= x y...
:start and :end with parse-integer
parse-integer takes :start and :end arguments, so you don’t have to extract integer subsequences from strings to pass them to parse-integer. For example, to parse date strings that look like “2011-10-01” into year, month, and date integers, you can do this:
(defun parse-date (string)
"Parse a date string in the form YYYY-MM-DD and return the
year, month, and day as multiple...
Converting characters to integers
If you have the character #\7 and you want the integer 7, you might be tempted to use (parse-integer (string char)) or even this ASCII-oriented technique:
(- (char-int char) (char-int #\0))
While the former is specified to give the right answer, the latter will only work by coincidence. The spec does discuss character ordering, but it makes no guarantees about the values returned by char-int or...
Multi-line format control strings
You can break up long format control strings with ~ at the end of a line. For example:
* (format t "It was the best of times, ~
it was the worst of times.")
It was the best of times, it was the worst of times.
The ~, newline, and all whitespace following the newline are removed from the output, so you can align the continued control string with the previous line.
The : and @...
PAIP lessons
Paradigms of AI Programming is a great book for learning Common Lisp. Peter Norvig wrote a retrospective on the book and included this list of 52 important lessons:
Use anonymous functions. [p. 20]
Create new functions (closures) at run time. [p. 22]
Use the most natural notation available to solve a problem. [p. 42]
Use the same data for several programs. [p. 43]
Be specific. Use...
Stylish Common Lisp
The Tutorial on Good Lisp Programming Style by Peter Norvig and Kent Pitman is full of useful tips for Common Lisp programmers.
Touching a file
To create an empty file, like the Unix touch command does, you might try something like this:
;; BOGUS
(close (open "foo.txt" :direction :output
:if-does-not-exist :create
:if-exists :append))
open has a :direction option specifically for this purpose, though:
(open "foo.txt" :direction :probe :if-does-not-exist :create)
If “foo.txt” does not exist, it...
Reading floats
When the reader sees a number like “3.0” with no exponent marker, the reader will convert it into a single-float by default. You can change what float type is used for conversion by changing *read-default-float-format* to another float type.
For example:
* (/ 22.0 7.0)
3.142857
* (setf *read-default-float-format* 'double-float)
DOUBLE-FLOAT
* (/ 22.0 7.0)
3.142857142857143
The...
Redirecting output
Got a function that writes to *standard-output* but you really want to redirect it somewhere else? You can bind the *standard-output* special variable in all the macros that create temporary streams.
For example, to return the output as a string:
* (with-output-to-string (*standard-output*)
(print-marketing-report))
"Source,Hits
twitter,243
google,805
direct,47
"
To write it out to a...
Swapping places
The naive way to swap the values of two places, a and b, is something like this:
;; BOGUS
(setf temp a)
(setf a b)
(setf b temp)
psetf (parallel setf) can do it in one form:
(psetf a b b a)
But rotatef is best:
(rotatef a b)
Pluralization
The ~P format directive can do simple pluralization.
* (format nil "You have ~D goat~:P." 42)
"You have 42 goats."
* (format nil "You have ~D goat~:P." 1)
"You have 1 goat."
* (format nil "You have ~D fl~@:P." 42)
"You have 42 flies."
* (format nil "You have ~D fl~@:P." 1)
"You have 1 fly."
Irregular plurals are more complicated:
(format nil "You have ~D ~:*~[mice~;mouse~:;mice~]." n)
...
string output streams
get-output-stream-string doesn’t just return the string accumulated so far in a string-stream. It also resets the accumulation, so you can use the same stream multiple times for separate results. Here’s a simple string splitter:
(defun split (string &optional (split-character #\Space))
(let ((result '())
(stream (make-string-output-stream)))
(loop for char across...
Discarding output
Unix shell nerds discard unwanted output by redirecting it to /dev/null. The equivalent in Common Lisp is the empty broadcast stream returned by a call to make-broadcast-stream with no arguments.
For example, if you have some code that normally prints to *standard-output*, but you want that output discarded, you can do something like this:
(let ((*standard-output* (make-broadcast-stream)))
...
September 2011
3 posts
http://slime-tips.tumblr.com/ →