For those who don’t know and who didn’t see the banner :D I am creating a Common Lisp course on the Udemy platform (with complementary videos on Youtube). I wanted to do something different and complementary than writing on the Cookbook.
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 Common 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)
- find the course here: https://www.udemy.com/course/common-lisp-programming/?couponCode=LISPMACROSPOWER (various videos are free to watch, so you can judge, and learn a couple things) (I can send free links to students, plz PM)
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.
This is what we see on the topic of macros. For a full overview of the course, what I want to do next (if you subscribe now, you’ll get new content for the same price) and read others’ feedback, see its GitHub project page (there are six more chapters including getting started, functions, iteration, condition handling…).
Table of Contents
- 7.1 A quick intro (FREE PREVIEW)
- 7.2. A comparison with C macros (FREE PREVIEW)
- 7.3 QUOTE (FREE PREVIEW)
- 7.4 Backquote and comma
- 7.5 How to spot you are using a macro
- 7.6 Functions vs macros
- 7.7 COMMA SPLICE ,@ the third most important macro mechanism
- 7.8 &body and other macro parameters. Our second macro model.
- 7.9 Putting this together: with-echo macro. Macroexpand in use.
- 7.10 GENSYM -the simple fix to the most dangerous macros gotcha
- 7.11 CALL-WITH pattern: simplifying macros
- 7.12 Compile time computing
- 7.13 Lists VS AST
- 7.14 Two example macros for compile-time computing
- 7.15 SYMBOL-MACRO
- 7.16 Read-time evaluation with #.
- 7.17 EDITOR TOOL: macrostep (FREE PREVIEW, Lem demo)
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.
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.
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 for your support, it does make a difference (I am self employed, I don’t earn millions and I’d love to spend *even more time* on CL resources and projects). If you want to learn what I do for the Lisp community and why you should buy my course, read more on Github.
Don’t hesitate to share the link with a friend or a colleague :) Thanks, and happy lisping.
A demo about web development has been recorded and is coming.
The Udemy course by @vindarel is the best introductory material for a fast and practical intro to Common Lisp.
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 )