Skip to content

Instantly share code, notes, and snippets.

@euhmeuh
Created October 19, 2017 11:18
Show Gist options
  • Save euhmeuh/0d2788a28ddf3682f6a28e30911c70ef to your computer and use it in GitHub Desktop.
Save euhmeuh/0d2788a28ddf3682f6a28e30911c70ef to your computer and use it in GitHub Desktop.
Anaphoric macros
;; Scheme hygienic aif is too long :(
;;
;; (define-syntax aif
;; (lambda (x)
;; (syntax-case x ()
;; ((_ test then else)
;; (with-syntax ((it (datum->syntax x 'it)))
;; (syntax
;; (let ((it test))
;; (if it then else))))))))
;;
;; Common Lisp equivalent:
;;
;; (defmacro aif (test then else)
;; `(let ((it ,test))
;; (if it ,then ,else)))
;; let's write a macro that returns a macro \o/
(define-syntax anaphoric-macro
(syntax-rules ()
((_ name (anaphora ...) (pattern template) ...)
(define-syntax name
(lambda (x)
(syntax-case x ()
(pattern
(with-syntax ((anaphora (datum->syntax x 'anaphora)) ...)
(syntax template))) ...))))))
;; better :D
(anaphoric-macro aif (it)
((_ test then else)
(let ((it test)) (if it then else))))
;; it works!
(aif (+ 2 20 16 4) (display it) (display "Nope"))
; alambda works too!
(anaphoric-macro alambda (self)
((_ params body)
(letrec ((self (lambda params body)))
self)))
;; a lambda that calls itself using 'self' \o/
(alambda (n)
(if (> n 0)
(cons
n
(self (- n 1)))
'()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment