Cadey is coffee
<Cadey> Hello! Thank you for visiting my website. You seem to be using an ad-blocker. I understand why you do this, but I'd really appreciate if it you would turn it off for my website. These ads help pay for running the website and are done by Ethical Ads. I do not receive detailed analytics on the ads and from what I understand neither does Ethical Ads. If you don't want to disable your ad blocker, please consider donating on Patreon or sending some extra cash to xeiaso.eth or 0xeA223Ca8968Ca59e0Bc79Ba331c2F6f636A3fB82. It helps fund the website's hosting bills and pay for the expensive technical editor that I use for my longer articles. Thanks and be well!

JSX is quasi-quoting

Read time in minutes: 5

I've been writing a fair bit of JSX/TSX code lately and something has felt oddly familiar about that programming model. It was something that I couldn't really place until I had a breakthrough after hacking at my Emacs config again. When you are using JSX to write HTML in your JavaScript functions, you are using quasi-quoting.

Aoi is wut
<Aoi> Quasi-quoting? What's that?

hero image sky-sigils

Image generated by Waifu Diffusion -- glowing sigils, sigils, zen, yin yang, taoism, landscape, world trade center, peaceful, arknights, scifi, runic energy, spellcraft

I think one of the easiest ways to explain this is to use Emacs Lisp. Emacs Lisp is the extension language for GNU Emacs, the text editor that I am horribly addicted to using have used for the last ten years.

One of the major concepts in Lisp is that code is data, and data is code. When you are writing in Lisp, you are writing linked lists that the computer interprets as code. For example, consider this small bit of Lisp:


(quote (+ 3 4))

You can evaluate this with ielm in Emacs by using M-x ielm:

Mara is hacker
<Mara> M-x is Emacs-speak for "alt-x".


*** Welcome to IELM ***  Type (describe-mode) for help.
ELISP> (quote (+ 3 4))
(+ 3 4)

Quoting code into data is something you do very often in Lisp, so there's a shortcut for doing this using the single quote character ':


ELISP> '(+ 3 4)
(+ 3 4)

This works great, but sometimes you need to put the value of a variable into a bit of data. Let's say you have this snippet of Lisp code:


(let ((filename "foobar.txt"))
     '(filename))

Mara is hacker
<Mara> (let ((var1 value) (var2 value)) code) is how you declare temporary variables in Lisp. Here the variable name filename is set to "foobar.txt". Each variable declaration is a list of two elements: the variable name and its value. Values can be data or code that is evaluated down to data.

If you put this into the Emacs Lisp interpreter, you won't get back what you think:


ELISP> (let ((filename "foobar.txt"))
            '(filename))
(filename)

You need to have some way to quote code you want to be data, and then some way to unquote data back into code. Luckily, Emacs Lisp lets you do this with a construct they call Backquoting:


ELISP> (let ((filename "foobar.txt"))
            `(,filename))
("foobar.txt")

The backtick ` lets you quote everything like the single quote ', but you can also unquote data using the comma , to turn your data back into code. This lets you construct complicated data structures like an attribute list to convert into HTTP form data:


ELISP> (let ((fname (buffer-name))
             (content "Hi there"))
            `((fname . ,fname)
              (content . ,content)))
((fname . "*ielm*")
 (content . "Hi there"))

Aoi is cheer
<Aoi> So quasi-quoting lets you mix data and code, but how does this relate to JSX?
Mara is aha
<Mara> JSX is the same thing with slightly different syntax.

JSX is a syntax extension for JavaScript that lets you mix HTML data with JavaScript code. It's a lot like quasi-quoting in Lisp. Consider this small block of JSX code:


const name = "Aoi";
const header = (
  <div>
    <h2>{name}</h2>
    <p>Hi there, {name}! How are you doing today?</p>
  </div>
);
document.write(header);

This writes the equivalent of this HTML to the current page:


<div>
  <h2>Aoi</h2>
  <p>Hi there, Aoi! How are you doing today?</p>
</div>

You quote HTML data inside parentheses () and use curly braces {} to unquote JavaScript code into HTML data.

Aoi is grin
<Aoi> So JSX does the same thing for HTML in JavaScript that quasi-quoting does for lists in Lisp! It lets you mix code and data so that you can assemble whatever you want easily.
Mara is happy
<Mara> Yep! You end up finding a lot of these things across different programming tools. A lot of tools steal ideas from eachother and there are many more similar patterns across the industry. What other ones can you find?


This article was posted on M01 23 2023. Facts and circumstances may have changed since publication Please contact me before jumping to conclusions if something seems wrong or unclear.

Tags: JSX JavaScript Lisp

The art for Mara was drawn by Selicre.

The art for Cadey was drawn by ArtZora Studios.

Some of the art for Aoi was drawn by @Sandra_Thomas01.