RSS Feed

Lisp Project of the Day

constantfold

You can support this project by donating at:

Donate using PatreonDonate using Liberapay

constantfoldlanguagemacro

Documentation🤨
Docstrings😀
Tests 🥺
Examples😀
RepositoryActivity🤨
CI 😀

This is an interesting library by @guicho271828, which allows moving some calculations into the compile-time.

Constant folding is a cool thing when smart compiler simplifies expressions in compile-time if some parts of the expression are known.

For example, when you will write (* (+ 1 3) 3600), SBCL will simplify it to a 14400 constant during compilation of the lisp file.

Library constantfold allows you to define rules for constant folding for custom data structures:

POFTHEDAY> (defstruct point2d
             (x 0)
             (y 0))

POFTHEDAY> (defun point2d-add-2 (left right)
             (make-point2d
              :x (+ (point2d-x left)
                    (point2d-x right))
              :y (+ (point2d-y left)
                    (point2d-y right))))

POFTHEDAY> (defun point2d-add (&rest args)
             (reduce #'point2d-add-2 args))

;; These calls will define macro with same name
;; as functions:
POFTHEDAY> (constantfold:constantfold
            make-point2d
            :copier copy-point2d)

POFTHEDAY> (constantfold:constantfold
            point2d-add
            :copier copy-point2d
            :commutative t
            :associative t)

;; And foldable arguments will be folded into a constant:
POFTHEDAY> (macroexpand-dammit
            '(point2d-add (make-point2d :x 1 :y 2)
                          (make-point2d :x 3 :y 4)))
(COPY-POINT2D '#S(POINT2D :X 4 :Y 6))

When some values are not known at compile-time, they are left unfolded:

POFTHEDAY> (macroexpand-dammit
            '(defun add-offset (x y)
              (point2d-add (make-point2d :x 1 :y 2)
                           (make-point2d :x x :y y)
                           (make-point2d :x 3 :y 4))))
(DEFUN ADD-OFFSET (X Y)
  (POINT2D-ADD
   ;; This is the result of folding two points into one:
   (COPY-POINT2D '#S(POINT2D :X 4 :Y 6))
   ;; And this is the point with unknown X and Y:
   (MAKE-POINT2D :X X :Y Y)))

To look at how does it work in the whild, you might write NumCL's code. This library uses constantfold to mark functions which work with numbers to make constant folding work for them.


Brought to you by 40Ants under Creative Commons License