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)
)
)