···11+---
22+title: "JSX is quasi-quoting"
33+date: 2023-01-23
44+tags:
55+ - JSX
66+ - JavaScript
77+ - Lisp
88+---
99+1010+I've been writing a fair bit of JSX/TSX code lately and something has felt oddly
1111+familiar about that programming model. It was something that I couldn't really
1212+place until I had a breakthrough after hacking at my Emacs config again. When
1313+you are using JSX to write HTML in your JavaScript functions, you are using
1414+quasi-quoting.
1515+1616+<xeblog-conv standalone name="Aoi" mood="wut">Quasi-quoting? What's
1717+that?</xeblog-conv>
1818+1919+<xeblog-hero ai="Waifu Diffusion" file="sky-sigils" prompt="glowing sigils, sigils, zen, yin yang, taoism, landscape, world trade center, peaceful, arknights, scifi, runic energy, spellcraft"></xeblog-hero>
2020+2121+I think one of the easiest ways to explain this is to use Emacs Lisp. Emacs Lisp
2222+is the extension language for [GNU Emacs](https://www.gnu.org/software/emacs/),
2323+the text editor that I ~~am horribly addicted to using~~ have used for the last
2424+ten years.
2525+2626+One of the major concepts in Lisp is that code is data, and data is code. When
2727+you are writing in Lisp, you are writing linked lists that the computer
2828+interprets as code. For example, consider this small bit of Lisp:
2929+3030+```lisp
3131+(quote (+ 3 4))
3232+```
3333+3434+You can evaluate this with `ielm` in Emacs by using `M-x ielm`:
3535+3636+<xeblog-conv standalone name="Mara" mood="hacker">`M-x` is Emacs-speak for
3737+"alt-x".</xeblog-conv>
3838+3939+```
4040+*** Welcome to IELM *** Type (describe-mode) for help.
4141+ELISP> (quote (+ 3 4))
4242+(+ 3 4)
4343+```
4444+4545+Quoting code into data is something you do very often in Lisp, so there's a
4646+shortcut for doing this using the single quote character `'`:
4747+4848+```
4949+ELISP> '(+ 3 4)
5050+(+ 3 4)
5151+```
5252+5353+This works great, but sometimes you need to put the value of a variable into a
5454+bit of data. Let's say you have this snippet of Lisp code:
5555+5656+```lisp
5757+(let ((filename "foobar.txt"))
5858+ '(filename))
5959+```
6060+6161+<xeblog-conv standalone name="Mara" mood="hacker">`(let ((var1 value) (var2
6262+value)) code)` is how you declare temporary variables in Lisp. Here the variable
6363+name `filename` is set to `"foobar.txt"`. Each variable declaration is a list of
6464+two elements: the variable name and its value. Values can be data or code that
6565+is evaluated down to data.</xeblog-conv>
6666+6767+If you put this into the Emacs Lisp interpreter, you won't get back what you
6868+think:
6969+7070+```lisp
7171+ELISP> (let ((filename "foobar.txt"))
7272+ '(filename))
7373+(filename)
7474+```
7575+7676+You need to have some way to quote code you want to be data, and then some way
7777+to unquote data back into code. Luckily, Emacs Lisp lets you do this with a
7878+construct they call
7979+[Backquoting](https://www.gnu.org/software/emacs/manual/html_node/elisp/Backquote.html):
8080+8181+```lisp
8282+ELISP> (let ((filename "foobar.txt"))
8383+ `(,filename))
8484+("foobar.txt")
8585+```
8686+8787+The backtick <code>`</code> lets you quote everything like the single quote
8888+<code>'</code>, but you can also _unquote_ data using the comma <code>,</code>
8989+to turn your data back into code. This lets you construct complicated data
9090+structures like an attribute list to convert into HTTP form data:
9191+9292+```lisp
9393+ELISP> (let ((fname (buffer-name))
9494+ (content "Hi there"))
9595+ `((fname . ,fname)
9696+ (content . ,content)))
9797+((fname . "*ielm*")
9898+ (content . "Hi there"))
9999+```
100100+101101+<xeblog-conv name="Aoi" mood="cheer">So quasi-quoting lets you mix data and
102102+code, but how does this relate to JSX?</xeblog-conv>
103103+<xeblog-conv name="Mara" mood="aha">JSX is the same thing with slightly
104104+different syntax.</xeblog-conv>
105105+106106+[JSX](https://reactjs.org/docs/introducing-jsx.html) is a syntax extension for
107107+JavaScript that lets you mix HTML data with JavaScript code. It's a lot like
108108+quasi-quoting in Lisp. Consider this small block of JSX code:
109109+110110+```typescript
111111+const name = "Aoi";
112112+const header = (
113113+ <div>
114114+ <h2>{name}</h2>
115115+ <p>Hi there, {name}! How are you doing today?</p>
116116+ </div>
117117+);
118118+document.write(header);
119119+```
120120+121121+This writes the equivalent of this HTML to the current page:
122122+123123+```html
124124+<div>
125125+ <h2>Aoi</h2>
126126+ <p>Hi there, Aoi! How are you doing today?</p>
127127+</div>
128128+```
129129+130130+You quote HTML data inside parentheses `()` and use curly braces `{}` to unquote
131131+JavaScript code into HTML data.
132132+133133+<xeblog-conv name="Aoi" mood="grin">So JSX does the same thing for
134134+HTML in JavaScript that quasi-quoting does for lists in Lisp! It lets you mix
135135+code and data so that you can assemble whatever you want easily.</xeblog-conv>
136136+<xeblog-conv name="Mara" mood="happy">Yep! You end up finding a lot of these
137137+things across different programming tools. A lot of tools steal ideas from
138138+eachother and there are many more similar patterns across the industry. What
139139+other ones can you find?</xeblog-conv>