如何在Elisp中向函数传递绑定符号并实现回调赋值?
问题:分离输入获取与输入使用函数的实现困境
我想要把获取用户输入的函数和使用输入的函数分离开。最初写了一段可行的概念验证代码:
(defun initialiser (bindings) (cl-loop for (var) in bindings do (set var (read-from-minibuffer "Input value: "))))
测试代码如下:
(let ((name)) (initialiser '((name))) (message "name is %S" name))
我的目标是传递形如((name "Name") (address "Post address") (code "County code"))的绑定给输入处理函数并完成赋值。之后我编写了如下宏:
(defmacro initialise-and-execute (bindings initialiser &rest callback-actions) (let ((unwrapped-bindings (map 'list (lambda (binding) (car binding)) bindings))) `(let ,unwrapped-bindings (,initialiser (quote ,bindings) (lambda () ,@callback-actions)))))
但实际场景中,赋值需要通过回调完成,我写的这段代码无法正常工作:
(defun initialiser(bindings) (cl-loop for (var) in bindings collect (lambda () (set var (read-from-minibuffer "Input value: "))) into callbacks return callbacks))
测试代码:
(defvar callbacks nil) (let ((name)) (setq callbacks (initialiser '((name))))) (funcall (car callbacks))
之后我修改了宏,期望生成共享同一词法环境的lambda(一个用于捕获变量,其余用于修改变量):
(defmacro initialise-and-execute (bindings initialiser &rest callback-actions) (let ((unwrapped-bindings (map 'list (lambda (binding) (car binding)) bindings))) `(lexical-let ,unwrapped-bindings (,initialiser (quote ,(map 'list (lambda (binding) (list (cadr binding) `(lambda (val) (setq ,(car binding) val)))) bindings)) (lambda () ,@callback-actions)))))
但实际运行时,callback-actions中使用的符号无法解析为已设置的值。测试代码如下:
(defun init-values (bindings callback) (loop for (desc setter) in bindings for idx = 0 then (incf idx) do (print (format "Setting %s" desc)) (funcall setter idx)) (funcall callback)) (initialise-and-execute ((name "Name") (surname "Surname")) init-values (message "name is %S" name))
这里的lambda并非在loop中生成,而是在词法绑定上下文通过setq赋值,目前问题还没解决。
内容的提问来源于stack exchange,提问作者Srv19
相关产品推荐
相关产品推荐

