DEV Community

vindarel
vindarel

Posted on • Edited on

Learn Common Lisp macros: new 17 videos tutorial

I worked on new videos this summer and I just finished editing the subtitles. I have added 17 videos (worth 1h30+ of code-driven content) about Lisp macros!

We cover a lot of content: quote, backquote and comma, ",@", comparison with C macros, comparison with functions, GENSYM and variable capture, useful patterns (call-with…), compile-time computing, read-time evaluation… (full summary below)

New: 17 videos to learn Lisp macros

I recorded the last one, about the MACROSTEP tool, inside the Lem editor. It's short, you should have a look at how this new editor looks like. (I'm very excited about it. Did I say I started develop a magit-like plugin for it?)

Who is this course for?

The whole course is for beginners in Lisp, although not total beginners in programming. This chapter is, logically, a bit more difficult than the others. If you didn't write small Common Lisp programs yet, be gentle with yourself and stop if you don't understand. (you can ask questions in the Udemy forum, of course) In your case I would advise to watch the introductory one, the comparison with C macros, the video on QUOTE, the "functions VS macros" one, and then carry on at your rhythm. Be sure to work on the previous chapters before tackling this one.

Content

This is the full content:

What we see:

7.1 A quick intro (free preview)

Macros do not evaluate their arguments and expand to new code at compile time. What does that mean? A quick intro before diving deeper.

7.2. A comparison with C macros (free preview)

Lisp macros are NOT manipulating text, unlike C. Text leads to many unnecessary problems. We have a fun tour of a trivial need yet complicated issue in C that is easily done in Common Lisp.

7.3 QUOTE (free preview)

QUOTE does not evaluate its argument.

What we see: how to use QUOTE outside macros. Data takes the shape of code. We pair it with eval and we go full circle. We introduce the need to extrapolate values inside a quote.

7.4 Backquote and comma

What we see: how we extrapolate variable values. How they can help create data structures. Real world examples.

7.5 How to spot you are using a macro

Four tips to recognize if you are using a function or a macro, and why it matters.

7.6 Functions vs macros

Macros do NOT replace functions!

What we see: they are not higher-level functions. The subtle but logic need to re-compile functions using macros.

Introducing MACROEXPAND.

Keeping compile-time computing in mind (more on that later). A look at a function's disassembly. So… you might not need a macro yet ;)

7.7 COMMA SPLICE ,@ the third most important macro mechanism

What we see: when use it, understanding the common error messages, passing body forms to our macro. Our first macro model.

7.8 &body and other macro parameters. Our second macro model.

What we see: how &body differs to &rest. Macro parameters: lots of possibilities, but some conventions carry meaning. Our own DOLIST macro. Our second macro model you can follow.

7.9 Putting this together: with-echo macro. Macroexpand in use.

We build our first macro with backquote and comma-splice, even a quote followed by a comma. We use macroexpand.

7.10 GENSYM -the simple fix to the most dangerous macros gotcha

What we see: what is variable capture and how to avoid it. Writing our own REPEAT macro. A little discussion about Common Lisp VS Scheme macros. GENSYM can be used outside macros too.

At this point you know enough to write all common macros. See the exercises for easy and not-so-easy ones.

7.11 CALL-WITH pattern: simplifying macros

We saw there can be subtle pitfalls when we write a macro. This pattern allows to offload most of the work to a function, which presents many advantages. We demo with our REPEAT macro.

7.12 Compile time computing

When writing macros, we have the full power of Common Lisp at compile time. This gives great tools to the developer: early type errors and warnings, faster runtime.

What we see: a simple example, writing a scientific macro for conversion of unit at compile time, existing libraries for that, introduction to dispatching macro characters and reader macros.

7.13 Lists VS AST

What we see: other languages don't have macros but can manipulate Abstract Syntax Trees. Code as lists of symbols is not the same, we would need a third-party library to manipulate a Lisp AST proper. This doesn't prevent us to develop crazy macros though, see this library adding Haskell-like type checking on top of Common Lisp, in pure CL macros.

7.14 Two example macros for compile-time computing

defstar allows to specify a function's arguments' types, Serapeum's ecase-of does exhaustiveness type checking. At compile time, of course.

7.15 SYMBOL-MACRO

A symbol macro is not your everyday Lisp development tool, but it expands your toolbet. Again.

7.16 Read-time evaluation with #.

Macros occur at compile-time. But Common Lisp blurs the lines between read time, compile time and run time. This allows to execute code at READ time.

7.17 EDITOR TOOL: macrostep (FREE PREVIEW, Lem demo)

Macrostep is an editor extension that helps understand our macro expansions. It is only available in Sly and Lem. We demo with the Lem editor.

Thanks

Thanks for your support, it does make a difference (I'm self employed and don't earn millions). If you want to learn what I do for the Lisp community and why you should buy my course, read more on Github.

I also published some complementary videos on Youtube.

A wonderful course for someone with cursory knowledge of lisp. I've dipped my feet many times now, but always struggled to wrap my head around everything. This course really helped give me greater confidence in how to start a project. I really enjoyed the focus on having an executable early. The Lisp-2 reveal was beautiful and made me finally understand the difference. Thanks a lot!

Simon, August of 2023. (thanks <3 )

Top comments (0)