Basic tips

Setting variables

There are multiple ways to set a variable:

All of the above methods also return the new value of the variable (except psetf); multiple assignments return the last assigned value.

Printing

format

The format function is an extremely terse and powerful tool for golfing, able to perform lengthy logic and iteration over its arguments. The Wikipedia page for format contains (nearly) every available directive, with many annotated examples and a handy table; a complete syntax guide is available in the Hyper-Spec Section on Formatted Output.

It is difficult to teach all of what format has to offer (golfing or otherwise), but here are some highlights:

Quite disappointingly, Common Lisp does not have a function to print a value with a trailing newline, hence the necessity of format t"~a~%" in most holes. However, if you need no additional formatting, you may be able to combine print and princ to achieve the same effect: print prints its argument with a leading newline, while princ adds no whitespace or newlines at all.

Thus, a distinguished first value of e.g. a sequence hole could invite print and princ to the forefront. Furthermore, print and princ return their arguments, allowing them to appear in the middle of a calculation or other form. Be wary with non-integers, though: lists will be printed as literals, and strings are wrapped in double quotes by print.

Looping

loop

One of Lisp's most powerful (and arguably least Lisp-y) features is the loop macro. The Hyper-Spec Section describes its capabilities in full, while the Common Lisp Cookbook has a more user-oriented review and collection of examples. Here's a selection of the most common use cases.

; Infinite loop
(loop)

; Loop over a range
(loop as i from a to b do (...))        ; includes b
(loop as i from b downto a do (...))    ; includes a
(loop as i from a below b do (...))     ; excludes b
(loop as i from b above a do (...))     ; excludes a

; Collect a range into a list
; This is often (unfortunately) the shortest way to do this
(loop as i from a to b collect i)

; Reduce values in a loop
(loop as i from a to b sum (...))
(loop as i from a to b thereis (...))
(loop as i from a to b always (...))
(loop as i from a to b never (...))

; Loop over a sequence
(loop as e in my-list do (...))
(loop as c across my-string do (...))

; Return early
(loop as i from a to b if (cond) return (val))

With all this and more, loop is by far the most powerful and flexible looping facility Lisp has to offer. In general, though, loop is only shortest when you have a "complicated" looping procedure which returns something.

do

The do macro is the more Lisp-y cousin to loop. It is capable of the same complex looping and collection/reduction operations, but varies from its relative in how terse each operation is. All do loops have the following form:

(do (
    ; Update forms
    (var-1 init-1 (update-1))    ; var-1 is set to init-1, then updated each iteration by evaluating update-1
    (var-2 init-2 (update-2))    ; the (optional) update form is a rebinding of the var, rather than an in-place update
    ...                          ; updates occur in parallel; use do* if you want sequential updates
  )(
    ; End forms
    (end-condition)              ; end-condition is checked after the update forms are run, including after initialization
    (return-form-1)              ; all return forms are run within the scope of the do loop
    (return-form-2)
    ...                          ; only the last form's value is actually returned
  )
  ; Body forms
  (body-form-1)
  (body-form-2)
  ...
)

Overall, consider do anywhere you might consider loop, particularly if you don't need to collect any values; do is also likely the best option for loop variables which depend on each other.

doseq

doseq is the shortest way to loop over any sequence without collecting or returning some value (e.g. running some procedure on each arg in *args*). If you do need to return something, though, doseq may still be the way to go: (doseq(x y z)) iterates as x over y and returns the evaluation of z. You can also return early using return.

dotimes

If you find yourself looping from 0 to n-1, use dotimes. It is far and away shorter than loop or do for the same task, and can return a value using the third parameter like doseq. If you need to start from 1 or another small value, dotimes may yet save the day, either by incorporating an offset into your code, or starting from 0 anyway and using a short conditional.

Note that dotimes simply calls incf on its loop variable on each iteration, rather than setting the variable to the "next" value. That is, the following is an infinite loop:

; 0 0 0 0 0 0 ...
(dotimes(x 10)(format t "~a " x)(decf x))

Macros

Use numbered sharpsign macros to compress lengthy, repeated forms. These macros expand to their values at compile time, and can also aid in reducing whitespace in some situations.

(let(
  (a (parse-integer x))
  (b (parse-integer y))
))

(let(
  (a (#0=parse-integer x))
  (b (#0# y))
))

Special variables & syntaxes

' & `

Common Lisp has certain syntactic characters which expand to a form at compile time. The most common is ': 'foo is shorthand for (quote foo), where the quote function is what actually produces symbols. Since Common Lisp is a Lisp-2, having distinct scopes for functions and user variables, quote can be used as a variable.

This would be useless in golf if not for dotted pair notation, where .' is replaced with quote. This notation is parsed like a list literal, so it must be followed by exactly one literal, identifier, or form.

; Example:
(dotimes(i 10)(format t"~d ~a~%"i"potato"))         ; this
(dotimes(quote 10)(format t"~d ~a~%"quote"potato")) ; is equivalent to this,
(dotimes'10(format t"~d ~a~%".'"potato"))           ; is equivalent to this,
(dotimes'10(format t"~d ~a~%".'"potato"()))         ; but this will fail to compile

The above also holds for backquote, using .`. Backquote's intended use is also quite powerful for golfing, used for constructing and splatting/unrolling lists:

(list(+ x 10)1 2 3'(foo bar))
`(,(+ x 10)1 2 3(foo bar))
(append a b)
`(,@a,@b)

+, -, *, & /

The variables +, ++, and +++ (and their counterparts for / and *) store certain prior values of forms during the Lisp read-eval-print loop. Since submissions on code.golf are not run via interactive REPL, these values are never updated, but are set to specific values at the start of execution. Of particular use are * and /, which are both nil.

Reference