<commit_before>For a very long time, Carp didn’t have a mechanism for [quasiquotation](https://courses.cs.washington.edu/courses/cse341/04wi/lectures/14-scheme-quote.html).
As a macro writer, this frustrated me to no end, until, finally, I broke down
and wrote an implementation of quasiquotation, in macros. It received a lot of
helpful feedback from the community, and everyone was very excited when it got
merged!

In this blog post I want to both explain what quasiquotation is and how it is
useful, and build a mechanism for quasiquotation with you. While I was
initially afraid it might be a lot of work to build this feature, I actually
was able to get to a working prototype within a few hours. If we work together,
it will hopefully take us even less time!

Let’s get this party started!

## Why quasi? And what is quoting?

If you’ve ever talked to anyone who likes Lisp, you’ve probably heard that its
killer feature is that “code is data”. If your eyes—or ears—start to glaze over
when someone tries to explain the concept, you’re not alone. Still, let me try
and make up a short introduction:

```
(defn adder [x y] (+ x y))
```
<div class="figure-label">Fig. 1: An addition function.</div>

In Figure 1, we build a function `adder` that takes two arguments, `x` and `y`,
and adds them together using `+`. But this is also a list! Its first two
elements are the symbols `defn` and `adder`, its third the argument array, and
the last element is the body, which is in itself a list. If we wanted to treat
this list as a data structure rather than as code, all we’d have to do is
prefix it with a quote (`'`).

```
'(defn adder [x y] (+ x y))
```
<div class="figure-label">Fig. 2: Not a function anymore.</div>

We can traverse that list, take elements, rearrange it, all the things we
usually do with our data! This is exciting, because it means that writing a
macro in Lisp is just building a list like that and telling the environment to
evaluate it. We can programmatically generate code!

To do that, however, we often need to make some sections of the structrue
fixed, and others flexible. Let’s think of a macro that creates an alias for
a function without arguments, and you will see what I mean:

```
(defmacro alias [new-name original]
  ; we want to emit (defn new-name [] (original))
  (list 'defn new-name [] (list original)))

(defn x [] 1)
(alias y x)
(y) ; => 1
```
<div class="figure-label">Fig. 3: Aliasing functions.</div>

While the code in Figure 3 isn’t terrible, all the calls to `list` get in the
way of understanding the final structure of the code we emit. It doesn’t at all
look like what we want to produce, and it’s ver verbose. Still, this is as good
as it gets if we use `quote`, because it’s an all-or-nothing situation: either
this is code, or it’s data.

This is where quasiquotation comes in. Rather than explaining what it does, let<commit_msg>Update Lets_Build_a_Quasiquoter.md (#146)<commit_after>For a very long time, Carp didn’t have a mechanism for [quasiquotation](https://courses.cs.washington.edu/courses/cse341/04wi/lectures/14-scheme-quote.html).
As a macro writer, this frustrated me to no end, until, finally, I broke down
and wrote an implementation of quasiquotation, in macros. It received a lot of
helpful feedback from the community, and everyone was very excited when it got
merged!

In this blog post I want to both explain what quasiquotation is and how it is
useful, and build a mechanism for quasiquotation with you. While I was
initially afraid it might be a lot of work to build this feature, I actually
was able to get to a working prototype within a few hours. If we work together,
it will hopefully take us even less time!

Let’s get this party started!

## Why quasi? And what is quoting?

If you’ve ever talked to anyone who likes Lisp, you’ve probably heard that its
killer feature is that “code is data”. If your eyes—or ears—start to glaze over
when someone tries to explain the concept, you’re not alone. Still, let me try
and make a short introduction:

```
(defn adder [x y] (+ x y))
```
<div class="figure-label">Fig. 1: An addition function.</div>

In Figure 1, we build a function `adder` that takes two arguments, `x` and `y`,
and adds them together using `+`. But this is also a list! Its first two
elements are the symbols `defn` and `adder`, its third the argument array, and
the last element is the body, which is in itself a list. If we wanted to treat
this list as a data structure rather than as code, all we’d have to do is
prefix it with a quote (`'`).

```
'(defn adder [x y] (+ x y))
```
<div class="figure-label">Fig. 2: Not a function anymore.</div>

We can traverse that list, take elements, rearrange it, all the things we
usually do with our data! This is exciting, because it means that writing a
macro in Lisp is just building a list like that and telling the environment to
evaluate it. We can programmatically generate code!

To do that, however, we often need to make some sections of the structrue
fixed and others flexible. Let’s think of a macro that creates an alias for
a function without arguments, and you will see what I mean:

```
(defmacro alias [new-name original]
  ; we want to emit (defn new-name [] (original))
  (list 'defn new-name [] (list original)))

(defn x [] 1)
(alias y x)
(y) ; => 1
```
<div class="figure-label">Fig. 3: Aliasing functions.</div>

While the code in Figure 3 isn’t terrible, all the calls to `list` get in the
way of understanding the final structure of the code we emit. It doesn’t at all
look like what we want to produce, and it’s ver verbose. Still, this is as good
as it gets if we use `quote`, because it’s an all-or-nothing situation: either
this is code, or it’s data.

This is where quasiquotation comes in. Rather than explaining what it does, let
{'fraction_non_alphanumeric': 0.07770503101309442, 'fraction_numerical': 0.005341144038594073, 'mean_word_length': 4.178412132024977, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7566286', 'n_tokens_mistral': 1726, 'n_tokens_neox': 1643, 'n_words': 962}