clojure待解决问题?
1,https://stackoverflow.com/questions/56030237/variable-capture-with-macro-in-clojure 【已解决】
(defmacro t2macro [all-bindings body] (reduce (fn [acc [v binding]]
`(let [~v ~binding] ~acc))
`(do ~@body) all-bindings))
plans-client.mock> (t2macro [[a 1] [b 2]] (print (+ a b)))
3
宏展开:
(macroexpand-1 '(t2macro [[a 1] [b 2]] (print (+ a b))))
=> (clojure.core/let [b 2] (clojure.core/let [a 1] (do print (+ a b))))
这段宏展开代码该怎么理解?
匿名函数总共调用了几次?为什么只有一次println?
解答:这里涉及到reduce的逻辑reduce文档,reduce如果是(reduce f val coll)
形式调用的话,
那么执行顺序如下:
f(val, coll第一个元素) =》 tmp
f(tmp, coll第二个元素) =》tmp
直至coll最后一个元素。
回到代码本身,(let [~v ~binding] ~acc))
其实是执行了let绑定,并把acc原封不动的返回了,由于是被syntax quote处理过的,所以不会求值,所以reduce的f的第一个参数一直都是acc,直到最后返回的时候被求值,acc只求值了一次,所以只会打印一次。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人