
What makes Lisp macros so special? - neokantian
This question, about Lisp&#x27;s macros, has been asked over and over again:<p>-- https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;267862&#x2F;what-makes-lisp-macros-so-special<p>-- https:&#x2F;&#x2F;www.quora.com&#x2F;What-is-so-special-about-Lisps-macros<p>-- https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9508108<p>-- https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=2839742<p>-- http:&#x2F;&#x2F;kresimirbojcic.com&#x2F;2011&#x2F;08&#x2F;02&#x2F;whats-so-special-about-lisp.html<p>The value of switching to lisp (or a variant of lisp) must come from the availability of macros. By looking at examples of lisp macros, I find their usefulness certainly not obvious nor necessarily compelling. It is examples of how to benefit from using a language&#x27;s facility, that make programmers switch.<p>Paul Graham can keep touting Lisp macros for as long as he wants, without obvious examples, programmers will keep dismissing the switch as being not worth the switching cost.
======
pepper_sauce
One example that I feel most devs can appreciate is the elimination of
"boilerplate" code. How often in your non-macro language do you find yourself
repeating the same lines of code with minute differences?

Think about JavaScript before and after destructuring was implemented. How
many lines of code and mental effort are saved!

In Common Lisp this is just a macro, DESTRUCTURING-BIND
([http://www.lispworks.com/documentation/HyperSpec/Body/m_dest...](http://www.lispworks.com/documentation/HyperSpec/Body/m_destru.htm)).
Not a fan of the syntax? Just write a macro to modify how you use it.

Macros allow you the programmer to do similar things, but with anything you
want. You don't have to wait for a language committee to agree on something,
and then a third party to write a convoluted pre-processing system to
'transpile' the code to work. It's built into the language.

~~~
pepper_sauce
Really though, I felt similarly to OP until I read On Lisp[0] and Let Over
Lambda[1]. They are chock full of explicit examples. You can only learn so
much from StackOverflow questions and Quora answers.

I also hear good things about Paradigms of AI Programming, but I haven't read
it yet. From Peter Norvig's retro on the book[2], here are the lessons in it
which involve macros:

Design patterns can be used informally, or can be abstracted into a formal
function, macro, or data type (often involving higher-order functions). [p.
177]

We can write a compiler as a set of macros. [p. 277]

If you can understand how to write and when to use once-only, then you truly
understand macros [p. 853]

A word to the wise: don't get carried away with macros [p. 855]

[0]
[http://www.paulgraham.com/onlisp.html](http://www.paulgraham.com/onlisp.html)
[1]
[https://letoverlambda.com/index.cl/toc](https://letoverlambda.com/index.cl/toc)
[2] [https://norvig.com/Lisp-retro.html](https://norvig.com/Lisp-retro.html)

------
kazinator
18-19 years ago, I didn't switch to Lisp because of macros.

I was hooked by the list representation: how cons cells can be treated as
immutable to implement list operations by always allocating new cells that are
garbage collected.

I was hooked by the uniform syntax: good-bye ambiguities requiring
associativity and precedence rules.

I was charmed by the empty list being _nil_ which is also Boolean false, and
the convenience of _(car nil)_ just returning nil: the resulting code looked
slick and elegant to me.

I thought it was great how you can just _quote_ any part of the syntax and you
get an expression which gives you that syntax as a piece of literal data.

Eventually I learned about _defmacro_ , too, by which time I was productively
using Lisp.

I learned about backquote before macros: wow, how great, I thought: like "foo
$bar" string interpolation in the shell but with actual data structure.

I got into Lisp not because of some online hype about macros, but because I
happened on a copy of Stuart Shapiro's _Common Lisp: An Interactive Approach_
and worked through that. Now that book can be downloaded in electronic form.

One thing that charmed me was the Common Lisp read-table driven dispatch.
Knuth's TeX does something very similar. I imitated Knuth's idea in a macro
preprocessor that I wrote in 1999 called mpp; the preprocessor was able to
redefine its read syntax by re-assigning the categories of characters. When I
discovered that Lisp has a character-categorizing dispatch table as the basis
of its scanning, I was really bowled over: it was something I had already
liked to the point of having implemented it. (Today, I'm not so hot on read
tables any more; my TXR Lisp doesn't have the feature.)

------
komon
pepper_sauce's example is a good one, the ability to mold the language to what
features you need today is a big point.

But even beyond that I think the big purpose of macros is the ability to mold
the language the application you're applying it to. This is the Domain
Specific Language (DSL) idea.

For instance, take Protocol Buffers. The .proto format is a language that lets
you define your messages and denote which fields are required, optional, etc.
You run a compiler against these .proto files that spits out a generated
library for the platform you're on.

This sort of workflow isn't as onerous as it used to be with all the CI/CD
push to have tools that build your application in one step. But it is still a
separate language with its own compiler that must be maintained entirely
outside of your project or language ecosystem.

If, in a hypothetical universe where Lisp dominated Google, protocol buffers
had been written in Lisp you wouldn't need a separate compiler and language. A
library of macros like defpackage and defmessage could be written that would
generate the code for sending and receiving each message type you define
inline with the rest of your application. It would all be Lisp code and would
benefit from all of your Lisp tools, like linting, debugging, and testing.

And if it was written in a Lisp-y tradition, such a DSL would likely be
riddled with hooks for your application code to be able to attach to
dynamically, say if you would like every receipt of a message to be logged or
if a message fails validation you would want to page the on-call to figure out
who's sending bad messages and why.

So, in short, macros allow you to extend the language for reasons even beyond
syntactical conveniences like DESTRUCTURING-BIND. It allows you to really
shape your tools to the application at hand, and allows others to shape the
tools you share to their applications.

------
Jtsummers
What programming languages are you familiar with already?

