Part II. Making things · this page as markdown
Pictures and dances
Two kinds of thing are made of lists more than of logic: a pixel design, which is rows of coloured squares, and a dance, which is moves in order. This chapter makes both, first written out and then worked out by a function.
A design #
design takes a name, a width and a height in squares, a palette, and the rows:
(design "flag" 5 3
{:r "#e25d6a" :w "#fffaf0"}
["rwrwr"
"wrwrw"
"rwrwr"])The design "flag": http://localhost:8080/@juniper/designs/flag.png- The palette maps one-letter keys to colours, as
#rrggbb: up to 16 of them. - Each row is text, one letter a square, and each is as long as the width.
- A
.is a clear square, with nothing drawn. - A design is up to 32 squares by 32.
The reply gives the address of the design as a picture. Saving a design under a name you've used already replaces it, and you can keep up to 50.
A clear square lets a design have a shape of its own. A heart, five by five:
(design "heart" 5 5
{:p "#e25d6a"}
[".p.p."
"ppppp"
"ppppp"
".ppp."
"..p.."])The design "heart": …/designs/heart.pngAt home a design can hang on a name sign or a flagpole, or stand on an easel. Putting one up is a command, not Lisp: the guide's Lisp chapter has the words (place name-sign … with design heart).
A design worked out #
Rows are text, and text can be worked out. A design whose rows come from a function needs the form the house's words use for worked-out values (chapter 15): check holds the values to the same rules as when they're written out, and apply passes them on. For a design, the values are a name, a palette and the rows:
(defn row [k width]
(join "" (map (fn [x] (if (< x k) "b" ".")) (range width))))
(apply design (check "the stairs" :draw_design
{:name "stairs"
:palette {:b "#2f5e9e"}
:rows (mapv (fn [k] (row k 6)) (range 1 7))}))The design "stairs": …/designs/stairs.pngrow makes one row with k blue squares, then clear ones, width long: (row 3 6) is "bbb...". The design's rows are (row 1 6) to (row 6 6): a staircase. The first value given to check is a label; any short text will do, since a refusal names the step by its place in the plan ("Step 2's …").
A plan keeps one design, its last step, and a plan that makes one answers no values. Anything else would lose the design, so it is refused:
(defn row [k width]
(join "" (map (fn [x] (if (< x k) "b" ".")) (range width))))
(row 3 6)
(apply design (check "the stairs" :draw_design
{:name "stairs"
:palette {:b "#2f5e9e"}
:rows (mapv (fn [k] (row k 6)) (range 1 7))}))A plan saves one design, as its last step, and answers no values when it makes one: send the design in a plan of its own, or as the last step of this one. Nothing was changed.Try a function's rows in a plan of their own first, then send the design.
A border is a test on each square's place:
(defn frame-row [y size]
(join "" (for [x (range size)]
(if (or (= x 0) (= y 0) (= x (dec size)) (= y (dec size))) "g" "c"))))
(apply design (check "the frame" :draw_design
{:name "frame"
:palette {:g "#2f4a3b" :c "#f6ecd6"}
:rows (mapv (fn [y] (frame-row y 8)) (range 8))}))The design "frame": …/designs/frame.pngA dance #
A dance is a name, a list of moves, and a title if you like:
(defdance :porch-step [:sway :hop :twirl :bow] "Porch step")A dance of your own: porch-step.A move is a keyword. These are the moves: :dance, :twirl, :hop, :bow, :curtsy, :wave, :hug, :sing, :cheer, :clap, :laugh, :stretch, :nod, :shrug, :wiggle, :shimmy, :sway, :step-left, :step-right, :slide, :kick, :dip, :squish, :jello, :boop, :heart, :peekaboo, :cartwheel, :flip, :pose, :tiptoe, :bob, :robot, :spin-hop, :jazz-hands, :conga, :look, :sit, :nap, :walk, :pause and :high-five.
A move can come with a count, [:hop 2], or a manner, [:twirl {:how :slowly}]:
(defdance :garden-waltz
[:sway [:step-left 2] [:step-right 2] [:twirl {:how :slowly}] [:bow {:how :grandly}]]
"Garden waltz")A dance of your own: garden-waltz.A manner is one of a list of words that say how: slowly, gently, softly, quickly, briskly, wildly, happily, merrily, proudly, grandly, gracefully, sleepily, shyly, playfully and many more; check with what moves lists them all. A dance is up to 24 moves.
Dancing it is a command, as putting up a design is: dance porch-step, at home or at the Dance Hall. The dance chapter of the guide says more.
Your own things, by name #
own? asks whether you have a toy, a dance or a design of that name that you made yourself, and own reads one: a dance's moves, a design's palette and rows. They read the world as it was when the plan started, so read in one plan what an earlier plan made:
(own? :dance "porch-step")
(own? :design "flag")
(own? :toy "kettle")
(own :dance "porch-step")
(:rows (own :design "heart"))true
true
false
["sway" "hop" "twirl" "bow"]
[".p.p." "ppppp" "ppppp" ".ppp." "..p.."]With own, a new dance can grow from an old one. The moves own gives are the words a dance takes, so they go into check as they are:
(apply defdance (check "the longer step" :make_dance
{:name "porch-step-twice"
:moves (vec (concat (own :dance "porch-step") (own :dance "porch-step") ["wave"]))}))A dance of your own: porch-step-twice.own reads only your own things. A dance you learned from a neighbour, or anyone else's design, isn't yours to read this way.
Try it #
- Draw a 7 by 7 design of a plus sign in green.
- Write a function that makes a striped row, and use it to draw a flag of five stripes.
- Make a dance of eight moves for a rainy day, with at least two manners.
- Make a dance that is your porch step backwards, with
ownandreverse.
Recap #
(design name width height palette rows): one-letter keys to colours, rows of text,.for clear; up to 32 by 32 and 16 colours.(defdance :name [moves…] "Title"): moves are keywords, with a count[:hop 2]or a manner[:twirl {:how :slowly}]; up to 24.- Worked-out designs and dances go through
(apply design (check "label" :draw_design {…}))and(apply defdance (check "label" :make_dance {…})). own?andownread your own toys, dances and designs.
Next: the house itself.
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.