Macroexpand 2025 Noj: Clay Workshop
ns scicloj.clay.workshop.macroexpand2025) (
Welcome to the Macroexpand Clay Workshop!
The main goal of this workshop is to get you up and running with Clay. I’ll present an overview of Clay, and then we’ll spend time together getting setup and trying it. Please ask for help if you are stuck or have any questions.
What is Clay?
Clay is a tool that turns a Clojure namespace into a Document.
Clay renders code, results, comments, markdown and visualizations.
Useful for documentation, data exploration, visualization, and blogging.
Bundled with Noj; the SciCloj collection of data science libraries.
What does Clay produce?
HTML or Markdown of comments, code, and values. This HTML document was made from src/scicloj/clay/workshop/macroexpand2025.clj
.
Code and results
Expressions are evaluated and the result shown in the document.
reduce * [2 3 4 5]) (
120
Visualizations
Values may be annotated as visualizations. Clay can make tables, charts, and more.
:kind/table
^:types ["Table" "Chart" "Image" "JavaScript"]
{:purpose ["Summarize data"
"Enable comparison"
"Enhance appeal"
"Add interactivity"]}
types | purpose |
---|---|
Table | Summarize data |
Chart | Enable comparison |
Image | Enhance appeal |
JavaScript | Add interactivity |
:kind/echarts
^:title {:text "Charts"}
{:tooltip {}
:legend {:data ["sales"]}
:xAxis {:data ["Shirts", "Cardigans", "Chiffons",
"Pants", "Heels", "Socks"]}
:yAxis {}
:series [{:name "sales"
:type "bar"
:data [5 20 36
10 10 20]}]}
:kind/graphviz
^"digraph D {
[ A [shape=diamond]
B [shape=box]
C [shape=circle]
A -> B [style=dashed, color=grey]
A -> C [color=\"black:invis:black\"]
A -> D [penwidth=5, arrowhead=none]
}"]
Many more (33) visualizations are supported, see Clay Examples.
Hiccup as the “swiss army knife” enables anything HTML can do:
:kind/hiccup
^:svg {:width "100%"}
[:circle {:r 40 :cx 50 :cy 50 :fill "lightblue"}]
[:circle {:r 20 :cx 50 :cy 50 :fill "lightgreen"}]] [
Anything you can do in a web page can be expressed as hiccup, such as including JavaScript in the page.
:kind/hiccup
^:script {:src "https://cdn.jsdelivr.net/npm/scittle-kitchen/dist/scittle.js"}] [
^:kind/hiccup
is Clojure syntax for attaching metadata. Kindly is a standard for annotation, and helpers for attaching metadata annotations.
(kind/hiccup:svg {:width "100%"}
[:circle {:r 40 :cx 50 :cy 50 :fill "lightblue"}]
[:circle {:r 20 :cx 50 :cy 50 :fill "lightgreen"}]]) [
Metadata on values for visualization tools like Clay to know what to do with the value.
So - Notebooks?
Yes, Clay interleaves code, results, narrative and visualizations.
Similar to Jupyter, Clerk, etc.
But, there is no execution model or environment.
You write plain Clojure code, you can run it without Clay.
Clay is not a dependency of your code.
Write with your normal workflow, sometimes using Clay to visualize as you go.
Clay takes code as input and makes a document.
Produces HTML or Markdown which may be further processed into PDF, slides, or websites.
Why make documents from code?
We value reproducible artifacts
Premise | Reason |
---|---|
Sharing ideas is important | Foundation of human progress. Fuels technology, communities, and civilization. |
Code crystallizes thinking | Concrete, logical, reproducible, explorable, and extensible. |
Edit code not documents | Thinking and coding is the hard part. |
Publishing matters | Share your idea in a widely accessible formats. |
Why use Clay?
Clay is a simple approach that keeps out of your way.
Notebooks | Clay | |
---|---|---|
Visualizing | React application | HTML+JavaScript |
Coding | Custom execution model | REPL |
Publishing | Notebook | Markdown |
People really enjoy the workflow and results.
“Best notebook experience I’ve had”
How to Clay
To use Clay is to send it some code. Usually we also want to view the document. Clay has a built-in server to show HTML.
REPL
Clay needs to be on the classpath to invoke it.
comment
(require 'scicloj.clay.v2.make)
(:source-path "src/scicloj/clay/workshop/macroexpand2025.clj"})) (scicloj.clay.v2.make/make! {
Editor integrations
The recommended way to call Clay is via REPL commands. Common operations are making the current namespace, or showing a single visualization. These operations can be found in scicloj.clay.v2.snippets
. The important ones are make-ns-html!
and make-form-html!
.
There are plugins for Calva, Cider, Conjure, and Cursive. See Clay Setup.
When active, you should be able to find the commands in the command palette by searching for “Clay”. I highly recommend creating a custom keybinding that works with your configuration.
A browser window will be shown when you call Clay.
Anyone stuck?
If you are having difficulty getting started, you might find it easier to clone an existing project:
These projects have some extra configuration in .vscode
and .idea
.
Live reload
Clay can watch for file changes and re-render the document. Use the “Clay watch” REPL command to toggle live reload mode.
Create or edit a source file and it will be shown in the browser.
Alternatively you can launch Clay in live reload mode with
clojure -M -m scicloj.clay.v2.main
Or call watch!
from the REPL:
comment
(require 'scicloj.clay.v2.snippets)
( (scicloj.clay.v2.snippets/watch! {}))
Ideas for explorations
Take some time to create your own namespace and use Clay to render it. Here are some tiny ideas you might write about.
What is macroexpand?
Macros expand code at compile time. An example of a macro is and
. The expression (and true false)
expands into an if
expression.
macroexpand '(and true false)) (
(let*true]
[and__5600__auto__ if and__5600__auto__ (clojure.core/and false) and__5600__auto__)) (
Frequencies
Clojure has a very nifty inbuilt frequencies
function.
def freq
(frequencies "frequencies takes a sequence like this string,
( and returns a map"))
freq
\space 23,
{\a 5,
\c 2,
\d 1,
\e 9,
\f 1,
\g 1,
\h 1,
\i 4,
\newline 1,
\k 2,
\, 1,
\l 1,
\m 1,
\n 5,
\p 1,
\q 2,
\r 4,
\s 6,
\t 4,
\u 3}
Charts
Try TablePlot
def scatter-ds
(:x [1 2 3 4 5]
(tc/dataset {:y [10 20 15 25 18]
:z [1 2 1 2 1]}))
-> scatter-ds
("Sample Scatter Plot"})
(tp/base {:=title :x
(tp/layer-point {:=x :y})) :=y
Question time
Please speak up! Stuck? Need help? Want to see a feature demonstrated? Questions about configuration, Quarto, Markdown, formats, narrowing? Feature suggestions? Share your experiences?
Remaining questions can be asked in the #clay-dev channel.
Footnotes
Quarto is a well established, widely used publishing solution↩︎
Comments
The narrative of the document is written as comments.
Comments may contain Markdown.
This is a markdown comment.
CommonMark (Quarto). Quarto has features like footnotes1. See Markdown reference for the full feature set.