• person rss_feed

    Michał "phoe" Herda’s feed

    Blog

    • 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.