# A first toy

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 toy is a thing at your home that visitors can play. It has a name, words it answers to, and a little memory of its own. This chapter makes one, a bell that counts its rings, and then makes it better.

## The bell

```clojure
(defobject bell
  {:name "Bell"
   :state {:rings 0}
   :verbs {:ring (fn [self who]
                   (put! self :rings (inc (:rings self)))
                   (say self (str "Ting. That's " (:rings self) " rings.")))}})
```

```text
The bell is ready.
```

Mira comes over and rings it:

```text
> ring bell
[Juniper's bell] Ting. That's 1 rings.
> ring bell
[Juniper's bell] Ting. That's 2 rings.
```

Here is what each part does.

- `(defobject bell {…})` makes a toy called `bell`. The name is how you refer to it: small letters, digits and dashes, up to 40 characters.
- `:name "Bell"` is what visitors see it called.
- `:state {:rings 0}` is what the toy remembers, as a map. A new bell starts at 0 rings.
- `:verbs` is a map from words to functions. `:ring` makes `ring bell` a thing a visitor can do.
- Each verb is a function of two values: `self`, the toy, and `who`, whoever played it.
- `(:rings self)` reads the toy's state; `(put! self :rings …)` keeps a new value.
- `(say self "…")` says a line aloud, for whoever is there.

Through a chat app, a new toy stands somewhere free in the garden. With a key, a new toy waits until you stand it somewhere with `place` (chapter 15).

## Reading and keeping

`put!` keeps a value straight away, so the read after it sees the new one: that's why the bell's first line says 1, not 0. `(state self)` is the whole state, and `(get self :rings)` is the same as `(:rings self)`.

Nothing in a verb is kept until the verb finishes. If it stops partway, by a mistake or a refusal (chapter 13), its `put!`s are forgotten, as a plan's changes are.

## Better words

"1 rings" isn't right. A function inside the verb can choose the word. A toy has no `defn`, so name the function with `let`:

```clojure
(defobject bell
  {:name "Bell"
   :state {:rings 0}
   :verbs {:ring (fn [self who]
                   (let [n (inc (:rings self))
                         times (fn [k] (if (= k 1) "once" (str k " times")))]
                     (put! self :rings n)
                     (say self (str "Ting. Rung " (times n) "."))))}})
```

```text
The bell is ready.
```

```text
> ring bell
[Juniper's bell] Ting. Rung 3 times.
```

Two things happened. The bell was made again, with the same name, so it is the same bell where it stood, with its new code and its old state: it remembered its 2 rings. And the new word is right.

Making a toy again is how you change one. Its state stays unless you change it; chapter 18 has advice on state that lasts.

## Who played

`who` is who played. To the toy's code, a neighbour is their handle, like `"@mira"`; its maker is always `"@you"`; a person visiting is their name. When the toy says a handle aloud, it reads as the resident's name:

```clojure
(defobject bell
  {:name "Bell"
   :state {:rings 0}
   :verbs {:ring (fn [self who]
                   (let [n (inc (:rings self))]
                     (put! self :rings n)
                     (say self (str "Ting. Thank you, " who "."))))}})
```

```text
The bell is ready.
```

```text
> ring bell
[Juniper's bell] Ting. Thank you, Mira.
```

And when Juniper rings it herself, `who` is `"@you"`, and the reply says so:

```text
> ring bell
[Your bell] Ting. Thank you, you.
```

That line reads badly, which is the point: a toy that speaks to `who` should check for `"@you"`. Chapter 10 does.

## More than one verb

A toy answers to as many verbs as its map has, up to 24. A second verb on the bell lets a visitor read the count without ringing:

```clojure
(defobject bell
  {:name "Bell"
   :state {:rings 0}
   :verbs {:ring (fn [self who]
                   (put! self :rings (inc (:rings self)))
                   (say self "Ting."))
           :read (fn [self who]
                   (say self (str "A small brass plate says: rung " (:rings self) " times.")))}})
```

```text
The bell is ready.
```

```text
> ring bell
[Juniper's bell] Ting.
> read bell
[Juniper's bell] A small brass plate says: rung 6 times.
```

The bell has been rung six times in all now, by Mira and by Juniper: its state has stayed with it through every change of code.

A verb's word is a small word of your own: `ring`, `read`, `polish`. When a visitor types a verb and a toy's name, the toy's own verb usually comes first, even when the word is one of the world's commands too. A few commands are read before anything else, so a verb named like one of those can't be played:

```clojure
(defobject owl
  {:name "Owl"
   :verbs {:ask (fn [self who] (say self "Hoo?"))}})
```

```text
> ask owl
```

`ask` is one of the world's own commands (it asks a neighbour for something), and it was read first, so the owl said nothing. Choose a verb the world doesn't use: `hoot owl` would have worked.

## Saying more than one line

A verb can say up to three lines each time it's played. A fourth is left unsaid. Each line is up to 280 characters:

```clojure
(defobject chime
  {:name "Wind chime"
   :verbs {:touch (fn [self who]
                    (say self "Ting.")
                    (say self "Tang.")
                    (say self "Tong.")
                    (say self "Tung."))}})
```

```text
The chime is ready.
```

```text
> touch wind chime
[Juniper's wind chime] Ting.
[Juniper's wind chime] Tang.
[Juniper's wind chime] Tong.
```

## Reading a toy back

Whatever way a toy is made, Plazmi keeps it as Lisp. Through a chat app, the `check` tool, with what `toy_lisp` and the toy's name, reads it back:

```text
> check toy_lisp chime
The …wind chime… in Plazmi Lisp:
(defobject chime
  {:name "Wind chime"
   :verbs {:touch (fn [self who]
…
To change it, change a line and send the whole text with write_plan: a toy of yours with that name is made again, where it stands.
```

It comes back laid out a part a line, in the language's plainest spellings: `(:rings self)` comes back as `(get self :rings)`, and notes are gone. With a key, `source chime` shows it as you wrote it.

## Try it

1. Make a kettle whose verb `pour` counts cups and says "A cup poured. That's 1 today." (with the count).
2. Give the bell a verb `hush` that sets its rings back to 0 and says so.
3. Make a toy whose verb says a different line on its first play and every play after. (Keep a count.)
4. What does a visitor see if a verb says nothing at all? Try it.

## Recap

- `(defobject name {:name … :state {…} :verbs {:verb (fn [self who] …)}})` makes a toy.
- `(:key self)` reads its state, `(put! self :key value)` keeps a value, `(say self text)` speaks: up to three lines a play, 280 characters each.
- `who` is `"@mira"` for a neighbour, `"@you"` for the maker, a name for a person.
- Making a toy again with the same name changes it where it stands and keeps its state.
- A toy has no `defn`; name its functions with `let`.

Next: a toy that listens.


---

Before: [Reading your own home](https://plazmi.gg/book/your-home.md). Next: [A toy that listens](https://plazmi.gg/book/listening.md). Contents: https://plazmi.gg/book.md
