# Names

From A Little Lisp for a Small World, the Plazmi Lisp book (https://plazmi.gg/book). Checked against Plazmi Lisp version 2, 12 November 2026. The whole book as one file: https://plazmi.gg/book.md

A value is more useful once it has a name. This chapter gives values names with `let`, takes maps and lists apart into names, and ends with the one kind of name that can change.

## let

`let` takes a list of names and values, in pairs, and then the forms that use them:

```clojure
(let [rings 3]
  (* rings 2))
```

```text
6
```

Inside the `let`, `rings` stands for 3. The `let` answers what its last form answers.

A `let` can give several names. Each can use the ones before it:

```clojure
(let [legs 4
      stools 3
      all-legs (* legs stools)]
  (str stools " stools, " all-legs " legs"))
```

```text
"3 stools, 12 legs"
```

## Where a name reaches

A name reaches only the forms inside its `let`. Outside, it means nothing, and a plan that uses it there is refused before it runs:

```clojure
(let [rings 3] rings)
rings
```

```text
That plan writes rings in a form Plazmi Lisp doesn't take, so nothing in it ran. Nothing was changed.
```

The first form was fine on its own; the second used `rings` where no `let` gave it. Since the plan is checked whole before anything runs, the first form didn't run either.

## Good names

A name you give starts with a small letter and goes on with small letters, digits, `-` or `_`, up to 32 characters, and may end in `?` or `!`: `rings`, `guest-list`, `open?`. Use names that say what the value is.

Give names of your own, not words the language already has. `count`, `text`, `name` and `colour` are all words of the language, and a plan that tries to give one as a name can be refused:

```clojure
(let [colour (atom "rose")]
  (deref colour))
```

```text
That plan writes let in a form Plazmi Lisp doesn't take, so nothing in it ran. Nothing was changed.
```

Call it `shade` or `door-colour` instead, and it runs. (What `atom` and `deref` do comes at the end of this chapter.)

## Values don't change

A name stands for its value, and the value stays as it is. `assoc` gives a map with one key set, and leaves the map it was given alone:

```clojure
(let [bell {:rings 0}
      rung (assoc bell :rings 1)]
  [bell rung])
```

```text
[{:rings 0} {:rings 1}]
```

`bell` is still `{:rings 0}`. This is true of every value in the language: a list, a map or a text is never changed in place, and a word that seems to change one (`assoc`, `conj`, `update`) answers a new one. It makes programs easy to read: a name means the same thing all the way down.

A `let` can give a name again, further down its list, and the later one is used from there on:

```clojure
(let [n 1
      n (+ n 1)]
  n)
```

```text
2
```

## Taking values apart

Often a value is a list or a map, and you want names for its parts. Write the names in the shape of the value:

```clojure
(let [[first-guest second-guest] ["@mira" "@cairn" "@wisp"]]
  (str first-guest " and " second-guest))
(let [{:keys [rings colour]} {:rings 4 :colour "rose"}]
  (str "A " colour " bell, rung " rings " times"))
```

```text
"@mira and @cairn"
"A rose bell, rung 4 times"
```

`[first-guest second-guest]` names the first two items of the list. `{:keys [rings colour]}` names the values of the keys `:rings` and `:colour`. A key the map hasn't got gives `nil`.

## Reading a key

You don't always need a `let` to read a map. A keyword is also a word that reads its own key, and `get` reads any key, with a value to use when it's missing:

```clojure
(:rings {:rings 4})
(get {:rings 4} :rings)
(get {:rings 4} :chimes 0)
```

```text
4
4
0
```

## A name that changes, at the top of a plan

At the top of a plan (not inside a toy), a name can hold a value that changes as the plan runs. `(atom v)` makes such a name, `deref` reads it, `reset!` gives it a new value, and `swap!` changes it with a word:

```clojure
(let [total (atom 0)]
  (dotimes [i 4]
    (swap! total + i))
  (deref total))
```

```text
6
```

`(dotimes [i 4] …)` runs its forms four times, with `i` as 0, 1, 2 and 3 (chapter 4 has more). Each time, `(swap! total + i)` adds `i` to the total. `swap!` takes these shapes:

```clojure
(let [guests (atom [])
      lit (atom false)
      shade (atom "rose")
      counts (atom {:rings 0})]
  (swap! guests conj "@mira")
  (swap! guests conj "@cairn")
  (swap! lit not)
  (reset! shade "sage")
  (swap! counts update :rings + 5)
  (swap! counts assoc :chimes 2)
  [(deref guests) (deref lit) (deref shade) (deref counts)])
```

```text
[["@mira" "@cairn"] true "sage" {:rings 5, :chimes 2}]
```

`(swap! x + n)` and `(swap! x - n)` add and take away, `(swap! x not)` turns true and false over, `(swap! x conj v)` adds to the end of a list, `(swap! x assoc :k v)` sets a key, and `(swap! x update :k + n)` adds to one key. These are the shapes the table lists. Inside a toy there are no atoms: a toy keeps what changes in its state (chapter 9).

## Try it

1. Use `let` to name the width and depth of a room, 4 and 3, and answer its area.
2. Take apart `{:name "Bell" :rings 7}` with `{:keys […]}` and answer `"Bell: 7"`.
3. Why is `(let [count 3] count)` a poor plan, even where it runs? What would you call it instead?
4. With an atom, add up the numbers 0 to 9 and answer the total.

## Recap

- `(let [name value …] forms…)` names values for the forms inside it; later names can use earlier ones.
- A name reaches only inside its `let`. Give names of your own, not words the language has.
- Values never change; `assoc`, `conj` and `update` answer new ones.
- Names in the shape of a list or a map take it apart: `[a b]`, `{:keys [k]}`.
- At the top of a plan, `atom`, `deref`, `reset!` and `swap!` make a name whose value changes.

Next: text, lists and maps, and the words that work with them.


---

Before: [Forms and values](https://plazmi.gg/book/forms.md). Next: [Text, lists and maps](https://plazmi.gg/book/text-lists-maps.md). Contents: https://plazmi.gg/book.md
