common-lisp

Topics related to common-lisp:

Getting started with common-lisp

This is a simple hello world function in Common Lisp. Examples will print the text Hello, World! (without quotation marks; followed by a newline) to the standard output.

Common Lisp is a programming language that is largely used interactively using an interface known as a REPL. The REPL (Read Eval Print Loop) allows one to type code, have it evaluated (run) and see the results immediately. The prompt for the REPL (at which point one types the code to be run) is indicated by CL-USER>. Sometimes something other than CL-USER will appear before the > but this is still a REPL.

After the prompt comes some code, usually either a single word (i.e. a variable name) or a form (a list of words/forms enclosed between ( and )) (i.e. a function call or declaration, etc). On the next line will be any output that the program prints (or nothing if the program prints nothing) and then the values returned by evaluating the expression. Normally an expression returns one value but if it returns multiple values they appear once per line.

ASDF - Another System Definition Facility

ASDF - Another System Definition Facility

ASDF is a tool for specifying how systems of Common Lisp software are made up of components (sub-systems and files), and how to operate on these components in the right order so that they can be compiled, loaded, tested, etc.

CLOS - the Common Lisp Object System

format

The CLHS documentation for FORMAT directives can be found in Section 22.3. With SLIME, you can type C-c C-d ~ to look up the CLHS documentation for a specific format directive.

macros

The Purpose of Macros

Macros are intended for generating code, transforming code and providing new notations. These new notations can be more suited to better express the program, for example by providing domain-level constructs or entire new embedded languages.

Macros can make source code more self-explanatory, but debugging can be made more difficult. As a rule of thumb, one should not use macros when a regular function will do. When you do use them, avoid the usual pitfalls, try to stick to the commonly used patterns and naming conventions.

Macroexpansion Order

Compared to functions, macros are expanded in a reverse order; outmost first, inmost last. This means that by default one cannot use an inner macro to generate syntax required for an outer macro.

Evaluation Order

Sometimes macros need to move user-supplied forms around. One must make sure not to change the order in which they are evaluated. The user may be relying on side effects happening in order.

Evaluate Once Only

The expansion of a macro often needs to use the value of the same user-supplied form more than once. It is possible that the form happens to have side-effects, or it might be calling an expensive function. Thus the macro must make sure to only evaluate such forms once. Usually this will be done by assigning the value to a local variable (whose name is GENSYMed).

Functions used by Macros, using EVAL-WHEN

Complex macros often have parts of their logic implemented in separate functions. One must remember, however, that macros are expanded before the actual code is compiled. When compiling a file, then by default, functions and variables defined in the same file will not be available during macro execution. All function and variable definitions, in the same file, used by a macro must be wrapped inside an EVAL-WHEN-form. The EVAL-WHEN should have all three times specified, when the enclosed code also should be evaluated during load and runtime.

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun foobar () ...))

This does not apply to functions called from the expansion of the macro, only the ones called by the macro itself.

Functions as first class values

When talking about Lisp-like languages there is a common distinction between what is known as a Lisp-1 and a Lisp-2. In a Lisp-1, symbols only have a value and if a symbol refers to a function then the value of that symbol will be that function. In a Lisp-2, symbols can have separate associated values and functions and so a special form is required to refer to the function stored in a symbol instead of the value.

Common Lisp is basically a Lisp-2 however there are in fact more than 2 namespaces (things that symbols can refer to) -- symbols can refer to values, functions, types and tags, for example.

Quote

There are some objects (for example keyword symbols) that don't need to be quoted since they evaluate to themselves.

LOOP, a Common Lisp macro for iteration

sequence - how to split a sequence

Basic loops

Functions

Anonymous functions can be created using LAMBDA. Local functions can be defined using LABELS or FLET. Their parameters are defined the same was as in global named functions.

Unit testing

Cons cells and lists

Regular Expressions

ANSI Common Lisp, the language standard and its documentation

CLOS Meta-Object Protocol

Pattern matching

Streams

Recursion

Lisp is often used in educational contexts, where students learn to understand and implement recursive algorithms.

Production code written in Common Lisp or portable code has several issues with recursion: They do not make use of implementation-specific features like tail call optimization, often making it necessary to avoid recursion altogether. In these cases, implementations:

  • Usually have a recursion depth limit due to limits in stack sizes. Thus recursive algorithms will only work for data of limited size.
  • Do not always provide optimization of tail calls, especially in combination with dynamically scoped operations.
  • Only provide optimization of tail calls at certain optimization levels.
  • Do not usually provide tail call optimization.
  • Usually do not provide tail call optimization on certain platforms. For example, implementations on JVM may not do so, since the JVM itself does not support tail call optimization.

Replacing tail calls with jumps usually makes debugging more difficult; Adding jumps will cause stack frames to become unavailable in a debugger. As alternatives Common Lisp provides:

  • Iteration constructs, like DO, DOTIMES, LOOP, and others
  • Higher-order functions, like MAP, REDUCE, and others
  • Various control structures, including low-level go to

Control Structures

Booleans and Generalized Booleans

Lexical vs special variables

Types of Lists

Working with SLIME

Hash tables

Working with databases

Grouping Forms

Creating Binaries

Customization

Mapping functions over lists

Equality and other comparison predicates