在循环宏中使用照应绑定
Using anaphoric bindings within a loop macro
我有这样的结构
(loop :for c :in list-of-char-codes
:if (gethash c hash-of-frequencies)
:do (incf (gethash c hash-of-frequencies) 0))
是否有合理的方法来避免冗余 (gethash c hash-of-frequencies)
,例如,使用照应宏?
您是否试图仅计算 hash-of-frequencies
中已经存在的那些字符?
(loop :for c :in list-of-char-codes
:for freq = (gethash c hash-of-frequencies)
:when freq
:do (setf (gethash c hash-of-frequencies) (1+ freq)))
或者您可能想要计算 所有 个字符?
(loop :for c :in list-of-char-codes
:do (incf (gethash c hash-of-frequencies 0)))
您通常也可以通过使用 #=
和 ##
来避免重复,就像这样:
(loop :for c :in list-of-char-codes
:for freq = #1=(gethash c hash-of-frequencies)
:when freq
:do (setf #1# (1+ freq)))
这是在读取时插入代码。
完整性w.r.t。其他好的答案,你也可以这样做:
(defun foo (list-of-char-codes hash-of-frequencies)
(macrolet ((hash (c) `(gethash ,c hash-of-frequencies)))
(loop :for c :in list-of-char-codes
:for freq = (hash c)
:when freq
:do (setf (hash c) (1+ freq)))))
请注意,如果您经常 access/modify 相同的散列 table,定义一个全局宏来隐藏实现细节可能是个好主意。
此外,您甚至可以使用 symbol-macrolet
,但我认为这种风格很糟糕,因为下面会注入 c
,使绑定隐含,并且在重命名变量 c
时会中断(虽然你问过照应宏):
;; AVOID DOING THAT, PLEASE
(defun foo (list-of-char-codes hash-of-frequencies)
(symbol-macrolet ((hash (gethash c hash-of-frequencies)))
(loop :for c :in list-of-char-codes
:for freq = hash
:when freq
:do (setf hash (1+ freq)))))
我有这样的结构
(loop :for c :in list-of-char-codes
:if (gethash c hash-of-frequencies)
:do (incf (gethash c hash-of-frequencies) 0))
是否有合理的方法来避免冗余 (gethash c hash-of-frequencies)
,例如,使用照应宏?
您是否试图仅计算 hash-of-frequencies
中已经存在的那些字符?
(loop :for c :in list-of-char-codes
:for freq = (gethash c hash-of-frequencies)
:when freq
:do (setf (gethash c hash-of-frequencies) (1+ freq)))
或者您可能想要计算 所有 个字符?
(loop :for c :in list-of-char-codes
:do (incf (gethash c hash-of-frequencies 0)))
您通常也可以通过使用 #=
和 ##
来避免重复,就像这样:
(loop :for c :in list-of-char-codes
:for freq = #1=(gethash c hash-of-frequencies)
:when freq
:do (setf #1# (1+ freq)))
这是在读取时插入代码。
完整性w.r.t。其他好的答案,你也可以这样做:
(defun foo (list-of-char-codes hash-of-frequencies)
(macrolet ((hash (c) `(gethash ,c hash-of-frequencies)))
(loop :for c :in list-of-char-codes
:for freq = (hash c)
:when freq
:do (setf (hash c) (1+ freq)))))
请注意,如果您经常 access/modify 相同的散列 table,定义一个全局宏来隐藏实现细节可能是个好主意。
此外,您甚至可以使用 symbol-macrolet
,但我认为这种风格很糟糕,因为下面会注入 c
,使绑定隐含,并且在重命名变量 c
时会中断(虽然你问过照应宏):
;; AVOID DOING THAT, PLEASE
(defun foo (list-of-char-codes hash-of-frequencies)
(symbol-macrolet ((hash (gethash c hash-of-frequencies)))
(loop :for c :in list-of-char-codes
:for freq = hash
:when freq
:do (setf hash (1+ freq)))))