Created
December 14, 2021 21:02
-
-
Save jhunt/107bf8975decc481afd08a2c5e822696 to your computer and use it in GitHub Desktop.
Using Lisp Macros to Fact-Check Code at Compile Time
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; | |
;; This code was extracted from a larger project | |
;; and used in a Twitter thread on using macros | |
;; to fact-check programmers at compile-time. | |
;; | |
;; https://twitter.com/iamjameshunt/status/1470845641027129345 | |
;; | |
(defun -flags-for (num) | |
(format nil "~{~A~}" | |
(remove-if #'null | |
(list | |
(and (evenp num) #\e) | |
(and (oddp num) #\o) | |
(and (> num 100) #\>) | |
(and (> num 900) #\e) ; [e]ven bigger | |
; (also: wrong) | |
(and (< num 20) #\<))))) | |
(defmacro flag! (&body body) | |
(let ((seen (make-hash-table))) | |
`(format nil "~{~A~}" | |
(remove-if #'null | |
(list | |
,@(let ((forms nil)) | |
(loop for (flag test) in body | |
do | |
(if (nth-value 1 (gethash flag seen)) | |
(error (format nil "already seen flag ~S" flag))) | |
(setf (gethash flag seen) t) | |
(setf forms (cons `(and ,test ,flag) forms))) | |
forms)))))) | |
(defun flags-for (num) | |
(flag! | |
(#\e (evenp num)) | |
(#\o (oddp num)) | |
(#\> (> num 100)) | |
(#\< (< num 20)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment