You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 13:15:08