|
| 1 | +^{:kindly/hide-code true |
| 2 | + :clay {:title "Macroexpand 2025 Noj: Clay Workshop" |
| 3 | + :quarto {:author :timothypratley |
| 4 | + :description "What is Clay, why use it, and how to use it." |
| 5 | + :draft true |
| 6 | + :type :post |
| 7 | + :date "2025-10-16" |
| 8 | + :category :clay |
| 9 | + :tags [:clay :workflow]}}} |
| 10 | +(ns scicloj.clay.workshop.macroexpand2025 |
| 11 | + (:require [scicloj.tableplot.v1.plotly :as tp] |
| 12 | + [tablecloth.api :as tc])) |
| 13 | + |
| 14 | +(ns scicloj.clay.workshop.macroexpand2025) |
| 15 | + |
| 16 | +;; ## What is Clay? |
| 17 | + |
| 18 | +;; Clay is a tool that turns a Clojure namespace into a Document. |
| 19 | +;; This document was made from the `scicloj.clay.workshop.macroexpand2025` namespace. |
| 20 | + |
| 21 | +;; Clay renders code, results, comments, markdown and visualizations. |
| 22 | + |
| 23 | +;;  |
| 24 | + |
| 25 | +;; ### Code and results |
| 26 | + |
| 27 | +;; Expressions are evaluated and the result shown in the document. |
| 28 | + |
| 29 | +(reduce * [2 3 4 5]) |
| 30 | + |
| 31 | +;; ### Comments |
| 32 | + |
| 33 | +;; The narrative of the document is written as comments. |
| 34 | + |
| 35 | +;; Comments may contain Markdown. |
| 36 | + |
| 37 | +;; ``` |
| 38 | +;; ;; This is a _markdown_ comment. |
| 39 | +;; ``` |
| 40 | + |
| 41 | +;; This is a _markdown_ comment. |
| 42 | + |
| 43 | +;; ``` |
| 44 | +;; ;; > Euler's identity is $e^{i\pi} + 1 = 0$ |
| 45 | +;; ``` |
| 46 | + |
| 47 | +;; > Euler's identity is $e^{i\pi} + 1 = 0$. |
| 48 | + |
| 49 | +;; ``` |
| 50 | +;; ;;  |
| 51 | +;; ``` |
| 52 | + |
| 53 | +;;  |
| 54 | + |
| 55 | +;; See [Markdown reference](https://quarto.org/docs/authoring/markdown-basics.html). |
| 56 | + |
| 57 | +;; ### Visualizations |
| 58 | + |
| 59 | +;; Values may be annotated as visualizations. |
| 60 | +;; Clay can make tables, charts, and more. |
| 61 | + |
| 62 | +^:kind/table |
| 63 | +{:types ["Table" "Chart" "Image" "JavaScript"] |
| 64 | + :purpose ["Summarize data" |
| 65 | + "Enable comparison" |
| 66 | + "Enhance appeal" |
| 67 | + "Add interactivity"]} |
| 68 | + |
| 69 | +^:kind/echarts |
| 70 | +{:title {:text "Charts"} |
| 71 | + :tooltip {} |
| 72 | + :legend {:data ["sales"]} |
| 73 | + :xAxis {:data ["Shirts", "Cardigans", "Chiffons", |
| 74 | + "Pants", "Heels", "Socks"]} |
| 75 | + :yAxis {} |
| 76 | + :series [{:name "sales" |
| 77 | + :type "bar" |
| 78 | + :data [5 20 36 |
| 79 | + 10 10 20]}]} |
| 80 | + |
| 81 | +^:kind/graphviz |
| 82 | +["digraph D { |
| 83 | + A [shape=diamond] |
| 84 | + B [shape=box] |
| 85 | + C [shape=circle] |
| 86 | +
|
| 87 | + A -> B [style=dashed, color=grey] |
| 88 | + A -> C [color=\"black:invis:black\"] |
| 89 | + A -> D [penwidth=5, arrowhead=none] |
| 90 | +}"] |
| 91 | + |
| 92 | +;; Many more (33) visualizations are supported, see [Clay Examples](https://scicloj.github.io/clay/clay_book.examples.html). |
| 93 | + |
| 94 | +;; Hiccup as the "swiss army knife" enables anything HTML can do: |
| 95 | + |
| 96 | +^:kind/hiccup |
| 97 | +[:svg {:width "100%"} |
| 98 | + [:circle {:r 40 :cx 50 :cy 50 :fill "lightblue"}] |
| 99 | + [:circle {:r 20 :cx 50 :cy 50 :fill "lightgreen"}]] |
| 100 | + |
| 101 | +;; ## So - Notebooks? |
| 102 | + |
| 103 | +;; Yes, Clay interleaves code, results, narrative and visualizations. |
| 104 | + |
| 105 | +;; > Similar to Jupyter, Clerk, etc. |
| 106 | + |
| 107 | +;; But, there is no execution model or environment. |
| 108 | + |
| 109 | +;; > It's your Clojure code, the way you usually write it. |
| 110 | + |
| 111 | +;; Clay is not _required_ by your code. |
| 112 | +;; Clay takes code as input and makes a document. |
| 113 | + |
| 114 | +;; > Produces **HTML**, PDF, presentations and Markdown. |
| 115 | + |
| 116 | +;; ## Why make documents from code? |
| 117 | + |
| 118 | +;; We value reproducible artifacts |
| 119 | + |
| 120 | +;; | Premise | Reason | |
| 121 | +;; |--|--| |
| 122 | +;; | Sharing ideas is important | Foundation of human progress. Fuels technology, communities, and civilization. | |
| 123 | +;; | Code crystallizes thinking | Concrete, logical, reproducible, explorable, and extensible. | |
| 124 | +;; | Edit code not documents | Thinking and coding is the hard part. | |
| 125 | +;; | Publishing matters | Share your idea in a widely accessible format. | |
| 126 | + |
| 127 | +;; ## Why use Clay? |
| 128 | + |
| 129 | +;; Clay is a simple approach that keeps out of your way. |
| 130 | + |
| 131 | +;; | | Notebooks | Clay | |
| 132 | +;; |--|--|--| |
| 133 | +;; | Visualizing | React application | HTML+JavaScript | |
| 134 | +;; | Coding | Custom execution model | REPL | |
| 135 | +;; | Publishing | Notebook | Markdown | |
| 136 | +;; : Clay is _simple_ |
| 137 | + |
| 138 | +;; ## How to Clay |
| 139 | + |
| 140 | +;; To use Clay is to send it some code. |
| 141 | +;; Usually we also want to view the document. |
| 142 | +;; Clay has a built-in server to show HTML. |
| 143 | + |
| 144 | +;; ### REPL |
| 145 | + |
| 146 | +;; Clay needs to be on the classpath to invoke it. |
| 147 | + |
| 148 | +;; <a href="https://clojars.org/org.scicloj/clay" data-original-href="https://clojars.org/org.scicloj/clay"><img src="https://img.shields.io/clojars/v/org.scicloj/clay.svg" class="img-fluid" alt="Clojars Project"></a> |
| 149 | + |
| 150 | +(comment |
| 151 | + (require 'scicloj.clay.v2.make) |
| 152 | + (scicloj.clay.v2.make/make! {:source-path "src/scicloj/clay/workshop/macroexpand2025.clj"})) |
| 153 | + |
| 154 | +;; ### Editor integrations |
| 155 | + |
| 156 | +;; The recommended way to call Clay is via REPL commands. |
| 157 | +;; Common operations are making the current namespace, or showing a single visualization. |
| 158 | +;; These operations can be found in [`scicloj.clay.v2.snippets`](https://github.com/scicloj/clay/blob/main/src/scicloj/clay/v2/snippets.clj). |
| 159 | +;; The important ones are `make-ns-html!` and `make-form-html!`. |
| 160 | + |
| 161 | +;; There are plugins for Calva, Cider, Conjure, and Cursive. |
| 162 | +;; [See Clay Setup](https://scicloj.github.io/clay/#setup). |
| 163 | + |
| 164 | +;; When active, you should be able to find the commands in the command palette |
| 165 | +;; by searching for "Clay". |
| 166 | +;; I highly recommend creating a custom keybinding that works with your configuration. |
| 167 | + |
| 168 | +;; If you are having difficulty getting started, |
| 169 | +;; you might find it easier to clone an existing project: |
| 170 | + |
| 171 | +;; * [noj-v2-getting-started](https://github.com/scicloj/noj-v2-getting-started) |
| 172 | +;; * [Clojure Civitas](https://github.com/ClojureCivitas/clojurecivitas.github.io) |
| 173 | + |
| 174 | +;; These projects have some extra configuration in `.vscode` and `.idea`. |
| 175 | + |
| 176 | +;; ### Live reload |
| 177 | + |
| 178 | +;; Clay can watch for file changes and re-render document. |
| 179 | +;; Use the "Clay watch" REPL command to toggle live reload mode. |
| 180 | + |
| 181 | +;; Create or edit a source file and it will be shown in the browser. |
| 182 | + |
| 183 | +;; Alternatively you can launch Clay in live reload mode with |
| 184 | + |
| 185 | +;; ```sh |
| 186 | +;; clojure -M -m scicloj.clay.v2.main |
| 187 | +;; ``` |
| 188 | + |
| 189 | +;; Or call `watch!` from the REPL: |
| 190 | + |
| 191 | +(comment |
| 192 | + (require 'scicloj.clay.v2.snippets) |
| 193 | + (scicloj.clay.v2.snippets/watch! {})) |
| 194 | + |
| 195 | +;; ## Ideas for explorations |
| 196 | + |
| 197 | +;; The purpose of this Workshop is to encourage you to create your own namespace and use clay to render it. |
| 198 | +;; Here are some tiny ideas you might write about. |
| 199 | + |
| 200 | +;; ### What is macroexpand? |
| 201 | + |
| 202 | +;; Macros expand code at compile time. |
| 203 | +;; An example of a macro is `and`. |
| 204 | +;; The expression `(and true false)` expands into an `if` expression. |
| 205 | + |
| 206 | +(macroexpand '(and true false)) |
| 207 | + |
| 208 | +;; ### Frequencies |
| 209 | + |
| 210 | +;; Clojure has a very nifty inbuilt `frequencies` function. |
| 211 | + |
| 212 | +(def freq |
| 213 | + (frequencies "frequencies takes a sequence like this string, |
| 214 | + and returns a map")) |
| 215 | + |
| 216 | +freq |
| 217 | + |
| 218 | +;; ### Charts |
| 219 | + |
| 220 | +;; Try [TablePlot](https://scicloj.github.io/tableplot/tableplot_book.plotly_reference.html) |
| 221 | + |
| 222 | +(def scatter-ds |
| 223 | + (tc/dataset {:x [1 2 3 4 5] |
| 224 | + :y [10 20 15 25 18] |
| 225 | + :z [1 2 1 2 1]})) |
| 226 | + |
| 227 | +(-> scatter-ds |
| 228 | + (tp/base {:=title "Sample Scatter Plot"}) |
| 229 | + (tp/layer-point {:=x :x |
| 230 | + :=y :y})) |
| 231 | + |
| 232 | +;; ## Question time |
| 233 | + |
| 234 | +;; Stuck? Need help? Please speak up! |
0 commit comments