đŸ’Ÿ Archived View for nytpu.com â€ș gemlog â€ș 2023-04-08.gmi captured on 2023-04-19 at 22:30:38. Gemini links have been rewritten to link to archived content

View Raw

More Information

âžĄïž Next capture (2024-06-20)

-=-=-=-=-=-=-

↩ go back to index

Releasing Some New Common Lisp Macros

April 8, 2023

Last week or so I finally sat down and wrote my pretty ideal binding macro for Common Lisp—basically a rite of passage for any Lisper given all the other ones I've stumbled across. I just fully rewrote it yesterday after using it in some real code and cleaning it up a bit; so I guess I should actually tell people about it in case anyone ends up interested in it since I really like it so far. Although like almost all of my projects it's written for me and I don't expect anyone else to end up using it (not necessarily a bad thing).

The `BIND` macro itself can be found at:

https://git.sr.ht/~nytpu/lisp-utils/tree/master/bind.lisp

I decided to bundle it up with a little Design by Contract[1] library that I wrote last year and ended up heavily using in Lasso[2]. It's in an uncreatively named “lisp-utils” ASDF system:

https://git.sr.ht/~nytpu/lisp-utils

I don't have any specific plans to expand it out further, but I forsee adding more stuff if/when I write some cool general-purpose macro in the course of other programming. At any rate, I'm very firm on making every file/component in it entirely self-contained (including the DEFPACKAGEs) and with zero external dependencies, so you can just copy the file of interest into your project, install the system to your Quicklisp local projects[3] if you use that for dependency management, or otherwise install the system where ASDF can find lisp-utils.asd[4].

I heavily took inspiration from a few older binding macros, namely Scott L. Burson's new let[5] that was apparently originally written all the way back in 1980 (before Common Lisp existed!), and Ron Garret's BINDING-BLOCK[6], Ron Garrent being the author of the nice Lisping at JPL article[7]. I figured taking ideas from some very experienced and intelligent Lisp programmers, and then just morphing them into a syntax I like would be a good strategy. I think I succesfully captured the “flattening” of deeply-nested bindings of BINDING-BLOCK (especially with my heavy use of multiple return values which otherwise gets super nested), while still keeping it less procedural and more LET-style like new let.

After using it in some real code that I'm working on, it confirmed my thought that most of the time I'd be using it as a drop-in replacement for LET/LET*, so I wanted to make sure that “runs” of sequential bindings of the same type (currently LET-style bindinds and lambdas) are condensed into one single invocation of LET* or LABELS. This means that using BIND in place of LET* should have zero impact even without a decent optimizing implementation, since it expands into an identical single LET*. Even with more complex statements using the more fancy features, the number of forms is minimised wherever possible to where it *should* be no worse than writing the equivalent expression by hand. The worst is perhaps some superfluous use of LET* where LET could've been used instead, but a big part of yesterday's rewrite was making the bindings always sequential instead of trying to have a special separate sequential operator that made it annoying and verbose to use.

Overall I'm pretty happy with it so far, and I am still quite fond of that Design by Contract library so I'm glad I extracted it from Lasso into a standalone thing. Maybe check them out if you're interested?

[1]: Design by Contract

[2]: Lasso

[3]: install the system to your Quicklisp local projects

[4]: install the system where ASDF can find lisp-utils.asd

[5]: new let

[6]: BINDING-BLOCK

[7]: Lisping at JPL article

⁂

↩ go back to index

add a comment!

view likes and comments

contact: alex [at] nytpu.com

backlinks

-- Copyright © 2023 nytpu - CC BY-SA 4.0

Lisp-Utils is Copyright © 2022–2023 nytpu - MPL 2.0