I have a macro that intends to creates a closure:
; -*- lexical-binding: t -*-
(defmacro repro ()
(let ((kmap-sym (gensym "kmap-")))
`(let ((,kmap-sym (make-sparse-keymap)))
(define-key ,kmap-sym "a"
(lambda () (interactive) (message "kmap is %s" ,kmap-sym)))
,kmap-sym)))
;; only works when lexical-binding: t in the current file
(funcall (lookup-key (repro) "a"))
Although lexical-binding
is t
in the file where the macro is defined, (funcall (lookup-key (repro) "a"))
fails with the error (void-variable kmap-30252)
whenever it is evaluated in a different file where lexical-binding
is nil
.
Since I can't control where the macro will be used, I considered going back to using lexical-let
for the inner let in the example, which does work regardless of where the macro is invoked.
(defmacro repro ()
(let ((kmap-sym (gensym "kmap-")))
`(lexical-let ((,kmap-sym (make-sparse-keymap)))
(define-key ,kmap-sym "a"
(lambda () (interactive) (message "kmap is %s" ,kmap-sym)))
,kmap-sym)))
;; this works in any file
(funcall (lookup-key (repro) "a"))
But lexical-let
requires cl
, which I would like to avoid, and unfortunately lexical-let
is not defined in cl-lib
.
What options do I have for creating a closure?
Should the macroexpansion of repro
always expand into lexical bindings given that lexical-binding
is t
where the macro is defined?