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

如何在Clojure中实现Racket的define-values宏?

Clojure实现类似Racket define-values的全局多变量绑定

你的宏之所以会绑定到自动生成的符号,是因为用了b#这种带#的自动生成符号(gensym),def b#相当于定义了一个系统自动命名的全局变量,而非你传入的目标符号。

先修复单个变量的定义宏

如果只是想实现单个全局变量的自定义绑定,正确的宏应该直接引用传入的符号:

(defmacro defvar [sym val]
  `(def ~sym ~val))

;; 调用测试
(defvar 'a 2)
(println a) ; => 2

实现多变量全局绑定(类似Racket的define-values)

要一次性将多个全局变量绑定到对应的值,我们可以写一个def-values宏,通过解构表达式返回的序列,逐个定义全局变量:

(defmacro def-values [syms expr]
  `(let [~syms ~expr]
     ~@(map (fn [sym] `(def ~sym ~sym)) syms)))

;; 基础调用示例
(def-values [a b c] [1 2 3])
(println a) ; => 1
(println b) ; => 2
(println c) ; => 3

;; 支持返回序列的表达式
(def-values [x y] ((fn [] [(+ 5 3) (* 4 2)])))
(println x) ; => 8
(println y) ; => 8

这个宏的逻辑很直接:

  1. 先用let把表达式返回的序列解构到目标符号列表中;
  2. 再逐个将这些符号定义为全局变量,值就是let里已经绑定好的对应值。

Clojure没有Racket的values函数直接返回多值,但可以用向量、列表等序列类型传递多值,宏会自动完成解构。

内容的提问来源于stack exchange,提问作者user324885

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 14:35:22