Skip to main content

The Craft of Emacs

Evaluation: S-expressions and special forms

1 hour

Phew! That was decent work!

There may be less than thirty lines of code but a lot of information is packed between those braces. Lisp syntax is wonderfully concise, but that can make it a little daunting to read at first glance.

It’s worth remembering a few tips:

Finally, browse the reading guide to see the code broken down into bite-sized chunks.

Define the command xx

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Define the helper function xx--insert-line

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Define the helper function xx--num-skeins

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Prepare a temporary "*xx*" buffer

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Insert text into the buffer

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Ask for the number of strands as input

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Bind it to strands

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Ask for the number of stitches as input

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Bind it to stitches

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Insert the number of strands into the buffer

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Insert the number of stitches into the buffer

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Calculate the number of skeins

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

Insert the number of skeins into the buffer

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

xx--insert-line accepts a text argument

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

It inserts the text into the current buffer

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

It inserts a new line

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

xx--num-skeins accepts a strands argument

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

xx--num-skeins accepts a stitches argument

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

It performs a calculation

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)

(defunxx
()
(interactive)
(get-buffer-create"*xx*")
(switch-to-buffer"*xx*")
(erase-buffer)
(xx--insert-line"Skeins")
(xx--insert-line"======")
(let
(
(strands
(read-string"No. strands: ")
)
(stitches
(read-string"No. stitches: ")
)
)
(xx--insert-line
(concat"No. strands: "strands)
)
(xx--insert-line
(concat"No. stitches: "stitches)
)
(xx--insert-line
(concat"No. skeins: "
(number-to-string
(xx--num-skeins
(string-to-numberstrands)
(string-to-numberstitches)
)
)
)
)
)
)
(defunxx--insert-line
(text)
(inserttext)
(newline)
)
(defunxx--num-skeins
(strandsstitches)
(ceiling
(/
(float
(*strandsstitches)
)
4800.0)
)
)