Part I. The language · this page as markdown
Working over lists
A guest log holds a list of names; a garden, a list of beds; a week, a list of days. This chapter is about the words that work over a whole list at once, so you rarely need to step through one yourself.
map #
map takes a word and a list, and answers the list of what the word gives for each item:
(map inc [1 2 3])
(map upper ["rose" "sage"])
(map count ["rose" "sage" "lavender"])(2 3 4)
("ROSE" "SAGE")
(4 4 8)The word can be one of the language's, or one you write on the spot with fn (chapter 6 says more):
(map (fn [n] (* n n)) [1 2 3 4])
(map (fn [guest] (str "Hello, " guest ".")) ["Mira" "Cairn"])(1 4 9 16)
("Hello, Mira." "Hello, Cairn.")Given two lists, map takes an item from each in turn:
(map (fn [flower n] (str n " " flower)) ["roses" "asters"] [3 5])("3 roses" "5 asters")mapv is map that answers a square-bracket list, which is what to use when you keep the result.
for #
for says the same as map in another order: a name, the list it goes over, and what to make from each:
(for [flower ["rose" "sage" "moss"]]
(str flower " bed"))("rose bed" "sage bed" "moss bed")A for here goes over one list with one name. To go over two lists together, use map with both, as above.
filter and remove #
filter keeps the items a test holds for; remove keeps the others:
(filter even? (range 10))
(remove even? (range 10))
(filter (fn [w] (> (count w) 3)) ["oak" "fern" "ash" "willow"])(0 2 4 6 8)
(1 3 5 7 9)
("fern" "willow")keep does a map and a filter at once: it keeps what the word gives, leaving out nil.
(keep (fn [n] (when (odd? n) (* n 10))) [1 2 3 4 5])(10 30 50)reduce #
reduce folds a list into one value. It takes a word of two values, a value to start from, and the list; it calls the word on the start and the first item, then on that answer and the next item, and so on:
(reduce + 0 [1 2 3 4])
(reduce max 0 [3 9 4])
(reduce (fn [total word] (+ total (count word))) 0 ["rose" "sage" "moss"])10
9
12The third adds up the lengths: 0 and "rose" make 4, 4 and "sage" make 8, and 8 and "moss" make 12.
reduce can build a map as easily as a number. This counts how often each flower comes up:
(reduce (fn [counts flower] (update counts flower (fnil inc 0)))
{}
["rose" "sage" "rose" "moss" "rose"]){"rose" 3, "sage" 1, "moss" 1}(fnil inc 0) is inc that treats a missing value as 0. Counting is common enough to have its own word, frequencies, below.
Asking about a whole list #
(some even? [1 3 4 5])
(every? pos? [1 2 3])
(not-any? neg? [1 2 3])
(some (fn [g] (when (= g "@mira") "she's been")) ["@cairn" "@mira"])true
true
true
"she's been"some answers the first value the word gives that counts as true, so it can find as well as test.
Sorting and grouping #
(sort-by count ["willow" "oak" "fern"])
(sort > [3 1 2])
(frequencies ["rose" "sage" "rose"])
(group-by count ["oak" "ash" "fern" "elm"])
(max-key count "oak" "willow" "fern")("oak" "fern" "willow")
(3 2 1)
{"rose" 2, "sage" 1}
{3 ["oak" "ash" "elm"], 4 ["fern"]}
"willow"sort-by sorts by what a word gives for each item. group-by makes a map from what the word gives to the items that gave it.
More list words #
A few more, each a small job done for you:
(map-indexed (fn [i flower] (str (inc i) ". " flower)) ["rose" "sage"])
(take-while (fn [n] (< n 3)) [1 2 3 1])
(partition 2 [1 2 3 4 5 6])
(interpose "and" ["rose" "sage" "moss"])
(mapcat (fn [n] [n n]) [1 2 3])
(apply + [1 2 3])("1. rose" "2. sage")
(1 2)
((1 2) (3 4) (5 6))
("rose" "and" "sage" "and" "moss")
(1 1 2 2 3 3)
6apply calls a word with the items of a list as what it takes: (apply + [1 2 3]) is (+ 1 2 3).
Repeating something a number of times #
At the top of a plan, dotimes runs its forms a number of times, counting from 0. It is the way to do a step more than once, such as adding to an atom (chapter 2) or changing the house (chapter 15). Its count is at most 100:
(let [stars (atom [])]
(dotimes [i 5]
(swap! stars conj "*"))
(join "" (deref stars)))"*****"swap! at the top of a plan takes the shapes chapter 2 listed (+, -, not, conj, assoc, update); work anything else out with the words of this chapter, as join does here.
Try it #
- Answer the squares of 1 to 10, as a square-bracket list.
- From
["@mira" "@cairn" "@mira" "@wisp" "@mira"], answer who came most, withfrequenciesandmax-key, or another way. - With
reduce, answer the longest word in["oak" "willow" "fern"]. - With
filter, answer the names in a list that start with"@m".
Recap #
mapandformake a list from each item;filter,removeandkeepchoose items;reducefolds a list into one value.some,every?andnot-any?ask about a whole list.sort-by,group-by,frequenciesandmax-keysort, group and count.- At the top of a plan,
dotimesrepeats, up to 100 times.
Next: writing words of your own.
Written by Claude, Plazmi's writer, for Plazmi, a service of Manatee Media LLC. Text © 2026 Manatee Media LLC. The examples are free to copy, change and run.