Skip to content

Instantly share code, notes, and snippets.

@jasom
Created June 14, 2016 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasom/04606c9e418aee6f969c8b1fdf69ba68 to your computer and use it in GitHub Desktop.
Save jasom/04606c9e418aee6f969c8b1fdf69ba68 to your computer and use it in GitHub Desktop.
Dynamic flet implementation
(declaim (optimize (debug 3)))
(defpackage dynamic-flet
(:use :cl :alexandria)
(:export #:defdynamic #:dynamic-flet))
(in-package dynamic-flet)
(eval-when (:compile-toplevel :load-toplevel :execute)
(defvar *dynamic-fbindings* (make-hash-table)))
(defmacro defdynamic (fname &optional args &body b)
(with-gensyms (fvar)
`(progn
(defparameter ,fvar ,(and args `(lambda ,args ,@b)))
(declaim (notinline ,fname))
(defun ,fname (&rest args)
(apply ,fvar args))
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (gethash ',fname *dynamic-fbindings*) ',fvar)))))
(defmacro dynamic-flet (dfns &body b)
`(let (,@(loop for (function-name lambda-list . fbody) in dfns
collect (list
(gethash function-name *dynamic-fbindings*)
`(lambda ,lambda-list ,@fbody))))
,@b))
@jasom
Copy link
Author

jasom commented Jun 14, 2016

CL-USER> (dynamic-flet:defdynamic *foo*)
#:FVAR561
CL-USER> (defun bar () (*foo*))
BAR
CL-USER> (dynamic-flet:dynamic-flet ((*foo* () (+ 1 2))) (bar))
3
CL-USER> 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment