elisp macro的应用场景问题


#1

我有两个函数有一段重复代码,我想把这段代码抽象出来。

这段代码的作用是解析变量package,得到两个函数变量package-symboreciepe

一般来说都是写一个函数,package进去,package-symboreciepe出来。

不过我还想到一个用macro的方法,大概是这样:

(defmacro with-recipe (&rest body)
  `(let ((package-symbol (something using package))
         (recipe (something using package)))
       ,@body))

这个方法看起来就很违规很危险,但是我不太明白具体为什么。我能想到的是用到的变量没有显式的表现出来(当然我在文档里都写清楚了)。是这样吗?


#2

这样用没啥问题啊, macro 的作用就是去掉重复代码和嵌套函数


#3

吹毛求疵一点就是没用 gensym 其它没啥问题,不过 Emacs 也没像样的 gensym 可以用。


#4

gensym不是避免body內变量撞车用的么?(我没理解错的话)但是我的目的就是让body里的代码可以用package-symbolreciepe啊。还是说是别的地方?


#5

为什麼不用 flet

package 为什麼不在 argilst 里?


#6

抱歉我打错了……已经在问题里修正

我问的就是这个地方,把package加进arglist里在下面就要各种quote,很麻烦而且容易错,我这样的话body里面和(something using package)package就很方便。但是我不清楚这么做会不会出什么问题。


#7

内置的gensymmake-symbol不能用吗?感觉还行啊


#8

https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Symbols.html

因为 Emacs 实现的问题多出来一些限制。


#9

https://lists.gnu.org/archive/html/help-gnu-emacs/2010-05/msg00023.html

好像大部分场合都能应付了…有什么可能出问题的刁钻场合么?


#10
(make-symbol "f") ;; f
;; CL
(make-symbol "F") ;; #:F 

区别多了去了,比如如果要打印出来再读回去,Elisp 完全不会区分 interned 和 uninternd