我总结了一些自己在写elisp的时候在quote和macro上的挣扎,希望能帮到其他新手。
大佬能不能帮我看看有没有问题,写错了就尴尬了。
https://casouri.github.io/post/some-notes-on-emacs-lisp-eval-quote-and-macro/
我总结了一些自己在写elisp的时候在quote和macro上的挣扎,希望能帮到其他新手。
大佬能不能帮我看看有没有问题,写错了就尴尬了。
https://casouri.github.io/post/some-notes-on-emacs-lisp-eval-quote-and-macro/
先撤下来吧……问题太大了。
(defmacro m-m (var) `(message ,var))
卧槽,没想到问题这么大。等我回去撤下来
能说一下哪些地方有问题吗🙏🏼
这个quote加和不加的区别在哪?
传统 Lisp 的 defmacro 主体是一个返回列表的函数,返回的列表作为代码。(Scheme 的宏是另一回事)
(defmacro m2 (var) (message var))
(m2 "hello") ;; 这里展开的结果其实是 "hello",因为 (message "hello") 的返回值是 "hello"
;; 至于为啥你觉得生效了,是因为宏主体用 message 的副作用
;; 但副作用更加证明了你的错误,因为正常的宏展开不应该有副作用
;; 不信,你可以试试这个
(macroexpand '(m-m "hello")) ;; 我们用 macroexpand 来查看宏展开结果。
;; (message "hello")
(macroexpand '(m2 "v"))
;; "v"
;; 同时 minibuffer 会显示 v
喔喔喔,那么返回的list会被再一次eval对吗?因为平时用的macro都是会“执行”的。但是你说不应该有副作用,我就有点糊涂了……
会有 eval 是因为你在 eval 这个表达式,macro 做的只是展开,这个概念一定要明白
展开的过程可以有副作用,但不鼓励有。
所以说是展开后被当作普通的sexp eval,是这个意思吗。
是的。但相对于 sexp,我更倾向用 列表 这个词,因为在 Lisp 内部,代码只是用列表表示的数据,macro 就是用列表操作来操作代码
撤下来了。
有时间改改再po