-
chevron_right
STATIC-LET, Or How I Learned To Stop Worrying And Love LOAD-TIME-VALUE
Michał "phoe" Herda · Sunday, 30 January, 2022 - 09:42 · 1 minute
So I have been working on Common Lisp Recipes, on a recipe for using global static bindings via global-vars. I was wondering if there was anything for local bindings though, something like in C:
// Simple test in C
int test_function() {
static int counter = 0;
return counter++;
}
test_function(); // -> 0
test_function(); // -> 1
test_function(); // -> 2
And then, oh, I remembered. There was an article exploring the topic and showing a technique that had some pretty nice syntax.
;;; Simple test in Lisp
(defun test-function ()
(static-let ((counter 0))
(incf counter)))
(test-function) ; -> 1
(test-function) ; -> 2
(test-function) ; -> 3
Oh, and it should come in a LET*
flavor too!
;;; Simple sequential test in Lisp
(defun test-function-2 ()
(static-let* ((counter 0)
(big-counter (+ counter 100)))
(list (incf counter) (incf big-counter))))
(test-function-2) ; -> (1 101)
(test-function-2) ; -> (2 102)
(test-function-2) ; -> (3 103)
The only thing that was missing was a usable and somewhat tested implementation of that technique that I could link people to from the recipe. There wasn't one, though... So, d'oh, it needed to be written and uploaded somewhere.
Where? The library of Serapeum accepted the idea and I was able to come up with an implementation. It satisfied the maintainer who also provided a few fixes, all of which are implemented in the article.
But, that's the boring stuff. Come! Let us indulge in a little bit of literate programming and figure out how exactly that code works.
Read the full article on GitHub.