1Beginner

1.1Community

1.2SBCL

  • Enable debugging to get stack traces?

1.3References

  • Know that the reference is CLHS (Common Lisp HyperSpec). It can also be installed with apt install hyperspec in Debian 9 or 10.

1.4Dynamic and lexical variables

  • Temporarily binding a dynamic (special) variable: (let ((*print-escape* t)) ...)
  • Temporarily binding a lexical variable: (let ((foo t)) ...)
  • (declare (special Name)): see example in CLHS

2Problems

  • read can execute arbitrary code. Theoretically, Lisp is unparseable. Practically, people keep their sanity by not touching readtables.
  • Cannot shadow built-in symbols.
(flet ((replace ...)) ...)

3Types

  • (declare (type Type Var*)).
  • See the list of type specifiers.
  • But the interpreter is not required to check the types?

4Guides

5Setup

Some people have written getting-started guides: common-lisp.net.

<2020-01-16> common-lisp.net's library recommendation list seems to be taken from CodyReichert/awesome-cl. There is also Borretti 2015 consolidation. lisp-lang.org's list seems shorter.

quickdocs.org: centralized Common Lisp libraries documentation and popularity.

There are no GitHub trends1 for Common Lisp!? Is CL that unpopular!?

https://stackoverflow.com/questions/33848241/most-recent-standard-of-common-lisp

https://common-lisp.net/project/cdr/final.html

https://www.cliki.net/Scribble

"Screamer provides a nondeterministic choice-point operator, a backtracking mechanism, and a forward propagation facility. "

No legalese? Why do all those important projects like ASDF and Quicklisp don't have any LICENSE information in their source code repository!?

6SLIME

7Strings

  • Concatenate several strings: (concatenate 'string "foo" "bar" "baz").

8Compilation

  • The compiler must at least do the minimal compilation.
  • Programs must conform to some constraints in order to make compilation semantics = interpretation semantics.
  • Understand the compilation of top-level forms and the compilation of defining macros.
  • Compile time is before run time.
  • Run time spans from load time to execution time.
  • "At compile time, only the compilation environment and the evaluation environment are available."
  • "At run time, only the run-time environment is available."
  • "The compilation environment inherits from the evaluation environment, […]."
  • "The evaluation environment inherits from the startup environment, […]."
  • The not-compile-time mode means that the form is evaluated at load time.
  • The compile-time-too mode means that the form is evaluated at both compile time and load time.
  • "eval-when forms cause compile-time evaluation only at top level."

9Timing, coarse profiling

10Naming conventions

  • (defconstant +Name+ Value Docstring)
  • (defvar *Name* Value Docstring)

11Gensyms

Gensyms are theoretically disgusting but practically amazing.

Gensyms require that programmers don't name their variables like gensyms (G<number>).

Do not call gensym too much. Assume that they are not garbage collected.

It is unknown whether gensym is thread-safe. ANSI CL does not specify concurrency.

12Conditions, exceptions, restarts

13Projects

13.1Writing ASDF systems

13.2Packages

  • defpackage
  • Use uninterned symbols for names in defpackage.
  • in-package

Tricky stuff:

(defpackage my-package) ;; wrong
(defpackage :my-package) ;; less OK
(defpackage #:my-package) ;; OK

The first causes an unintended interning in the *package* (usually common-lisp-user) when the defpackage form is being read.

The second adds noise to SLIME autocompletion? SLIME does not auto-complete uninterned symbols?2

https://stackoverflow.com/questions/7894548/why-are-uninterned-symbols-used-for-package-names-and-exports-in-common-lisp

:export + use-package + uninterned symbols = conflict.

(defpackage temp (:export a))
(use-package 'temp) ;; conflicts because A is already interned in *PACKAGE* when the above DEFPACKAGE was read.

This uses keywords http://www.gigamonkeys.com/book/programming-in-the-large-packages-and-symbols.html

Should we use :keywords or #:uninterned-symbols?

https://stackoverflow.com/questions/46981477/variations-in-invocation-of-defpackage-and-in-package

Is an interned symbol never garbage-collected?

Tricky stuff: If read interns symbols, and symbols are never garbage-collected, then we can make the interpreter run out of memory by making it read too many distinct symbols?

13.3Show dependency graph as tree

  • asdf-viz? But we want text output.
  • (ql-dist:dependency-tree SYSTEM) does not work for non-quicklisp libraries:

Quicklisp has an idea about the dependencies of Quicklisp-provided systems, but not of any other systems available through ASDF.

14DEFSTRUCT vs DEFCLASS

15CLOS (Common Lisp Object System)

  • defclass
  • defgeneric
  • defmethod
  • make-instance

16FORMAT language

  • Format to standard output with (format t Format Arg...).
  • Format to string with (format nil Format Arg...).
  • ~a
  • ~s
  • ~% newline.

http://www.lispworks.com/documentation/lw50/CLHS/Body/22_c.htm

17LOOP language

http://www.lispworks.com/documentation/HyperSpec/Body/06_aac.htm

(loop for i from 0 to 9
      if Cond
        if Cond
          do Form ...
        end
      end)

From http://www.lispworks.com/documentation/HyperSpec/Body/06_aha.htm

(loop for i from 0 to 9
      if (evenp i)
        collect i into evens
      else
        collect i into odds
      end
      finally (return (list evens odds)))
=> ((0 2 4 6 8) (1 3 5 7 9))

(loop for i from 0
      for j in '(a b c)
      collect (list i j))
=> ((0 A) (1 B) (2 C))

Syntax.

repeat X translates to for Gensym in 0 to (- X 1)

18MATCH languages

  • Know some trivia MATCH patterns.
  • Use EMATCH instead of MATCH, because, if no patterns match, the former raises an error and the latter returns NIL.

19Web application development

HTTP is too low-level for web application development.

"UnCommon Web provides developers with the illusion that web pages are nothing more than function calls."

20Parsing

Meta, parsing on Lisp https://www.cliki.net/Meta

21Tricky stuff

21.1eval vs load

21.2Keyword vs symbol

https://stackoverflow.com/questions/23969203/what-is-the-difference-between-a-keyword-symbol-and-a-quoted-symbol

In the toplevel:

  • 'a evaluates to a symbol in the package common-lisp-user.
  • :a evaluates to a symbol in the package keyword; this package is special.

See also: symbol-package.

21.3Equality comparison

In mathematics, X and Y are equal iff every X can be replaced with Y without changing the truth value of the containing statement.

Two things are identical iff …

In Common Lisp:

  • eq is identity comparison.
  • eql is eq or something? eql is the default for make-hash-table.
  • equal is about structural similarity / isomorphism?
  • equalp is equal or something?
  • =
  • string=
  • char=

In Scheme:

  • eq? is identity comparison.
  • eqv? is ???
  • equal? is deep/recursive comparison?
  • = is numeric comparison?

21.4Nil vs false

https://www.google.com/amp/s/lispchronicles.wordpress.com/2017/03/16/the-truth-about-nothing/amp/

21.5Printing

  • prin1 for machines (read).
  • princ for humans.
  • pprint for pretty-printing.
  • Avoid write and print?

21.6macro-function, symbol-function, fdefinition, apply, funcall

  • (setf (macro-function 'foo) ...)
  • Understand FUNCTION vs CLOSURE.
    • Closure = Function + Lexical environment.
  • #' (function) can access lexical environment; symbol-function can only access global environment (what about dynamic environment?)
  • Expand macro form with MACROEXPAND.
  • Evaluate macro form with EVAL.

21.7map

  • Common Lisp map takes 3 arguments and works with lists and vectors.
  • Scheme map takes 2 arguments and works with lists only.

22Writing libraries

23Some project ideas

23.1Clash-free file-local packages

Key idea: a file-local package generates its name from the file's truename (canonical path).

23.2Common Lisp Plus

  • Create a language Lisp1 on top of Common Lisp (CL), that translates to CL, and fully interoperates with CL.

23.3Scheme on Common Lisp

23.4Emacs Lisp on Common Lisp

  • Emacs Lisp (EL) to Common Lisp (CL) embedding: translator or perhaps interpreter?

23.5Lisp "format" but more user-friendly?

format should use proper forms instead of format strings.

(format Fragment ...)

A string fragment is printed literally.

(display X) is Racket ~a.

(write X) is Racket ~s.

(print X) is Racket ~v.

newline is Racket ~n.

(max-width L F) is F but its width is truncated to L characters

(fixed-width L F).

See also: Racket fprintf

(format "Foo" (write 1) (print 2) newline)

23.6Racket syntax objects in Common Lisp and Scheme?

Racket's syntax object represents abstract syntax and not concrete syntax. If it had concrete syntax object, it would enable refactoring tools.

A Lisp should come with its own parser (about concrete syntax, not only about abstract syntax).

24Advanced?

25Other Lisps

26Namespaces?

https://www.emacswiki.org/emacs/Namespaces

"Debuggable" https://endlessparentheses.com/introducing-names-practical-namespaces-for-emacs-lisp.html


  1. <2020-01-16> https://github.com/trending/common-lisp

  2. https://www.reddit.com/r/learnlisp/comments/7a48i7/foo/dp7gr7i?utm_source=share&utm_medium=web2x

  3. <2020-01-15> "Why I haven't jumped ship from Common Lisp to Racket (just yet)?" https://fare.livejournal.com/188429.html