Skip to content

Instantly share code, notes, and snippets.

@robinp
Created July 8, 2025 15:34
Show Gist options
  • Save robinp/4223339075747642214423151436eadc to your computer and use it in GitHub Desktop.
Save robinp/4223339075747642214423151436eadc to your computer and use it in GitHub Desktop.
Random Lisp macros historic notes
PG book macro notes:
- 10.x - incf. Why would one want to write it as a macro, why not a function? Probably performance? Would advanced inlining/optimization in compiler make it efficient as function?
Reading https://stackoverflow.com/questions/43772510/creating-equivalent-to-incf-as-macro-function-in-lisp, it helps in some ways:
Performance-wise, it analyses compile-time if/what is the argument to increase with (though with optional parameter, the function could do the same probably).
Then incf has the deep places-support (kind of a lens-like thing). But for plain usecases that is not needed.
- 10.7 "nil!, ntimes and while all have to be written as macros, becaule all have to control the way in which their arguments are evaluated"
Why need to control? Because they can side-effects (the bodies especially). If we wanted to write them as a function, would need to thunk them or such.
How to thunk (defer evalution)? Either wrap in lambda, which is not very nice user experience. Or quote it, but then the function needs eval, which is costy in runtime.
So macros help fix indeed the consequences of side-effects and strict evaluation.
- "The only reason to write something as a macro because you can't write it as a function" + exceptions (perf? + compile-timize..)
- vs C - macro preprocessor is hideous.
vs Perl (which version) - allegedly lang parsing is somewhat hideous.
- https://softwareengineering.stackexchange.com/questions/124930/how-useful-are-lisp-macros
Points to http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg01539.html
1. DSLs, data tables..
2. New way of bindings? Not clear example. Something to do with control structures?
3. Control (not needed when you have lazyness... well, hm, how would monadic things fare?... well, there's explicit control on execution of the monadic action still, so should be ok)
- From the Graham book, chapter 10 (or 11)?
-- begin snip
(with-open-file (s "dump" :direction :output)
(princ 99 s))
After evaluation of this expression the file "dump" will automatically be closed,
and its contents will be the two characters "99".
This operator clearly has to be defined as a macro, because it binds s. However,
operators which cause forms to be evaluated in a new context must be defined as
macros anyway
-- end snip
Hm, these guys are lambda-averse quite some?
In 11.6 Need for Macros:
-- snip
Macros aren’t the only way to protect arguments against evaluation. Another is to
wrap them in closures. Conditional and repeated evaluation are similar because
neither problem inherently requires macros. For example, we could write a version ...
-- end snip
-- snip
If all we want is conditional evaluation, macros aren’t absolutely necessary. They
just make programs cleaner. However, macros are necessary when we want to
take apart argument forms, or bind variables passed as arguments.
The same applies to macros for iteration. Although macros offer the only way
to define an iteration construct which can be followed by a body of expressions,
it is possible to do iteration with functions, so long as the body of the loop is
packaged up in a function itself
-- end snip
Chap 12: the whole business with setf sounds like lens... with similar benefits and complications. Probably some smooth-lens that doesn't need much manual boilerplate would trump setf, which is allegedly hard to get right.
Anaphoric / syntax rewrite: with laziness, again no probs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment