rco*_*rre 5 lisp parameters function common-lisp
我假设传递给lisp函数的值被分配给与参数名称匹配的引号.但是,我对此感到惊讶:
(defun test (x) (print (eval 'x)))
(test 5)
Run Code Online (Sandbox Code Playgroud)
不起作用(变量x未绑定).因此,如果参数未作为符号存储在函数中,那么本例中究竟是什么IS?有没有办法从符合参数名称的符号中访问参数?
更多背景:我想做的是这样的:
defun slice (r1 c1 r2 c2 board)
(dolist (param '(r1 c1 r2 c2)) ;adjust for negative indices
(if (< (eval param) 0)
(set param (+ (length board) (eval param)))))
;Body of function
Run Code Online (Sandbox Code Playgroud)
基本上,我想迭代前四个参数并调整它们的任何值,如果它们<0.当然,我可以做一个let并为每个参数设置一条单独的行,但考虑到我正在做对于这四个参数中的每个参数,这看起来更清晰.但是,我得到变量R1未绑定的错误.
这基本上是词法绑定的工作方式:变量名在词法范围内被替换,直接引用变量值的存储位置.绑定变量名称symbol-value仅适用于您可以声明的动态变量special.
避免重复自己的一种方法是宏:
(defmacro with-adjusting ((&rest vars) adjust-value &body body)
`(let ,(loop for var in vars
collect `(,var (if (minusp ,var)
(+ ,var ,adjust-value)
,var)))
,@body))
(defun slice (r1 c1 r2 c2 board)
(with-adjusting (r1 c1 r2 c2) (length board)
;; function body
Run Code Online (Sandbox Code Playgroud)
有没有办法从与参数名称匹配的符号访问参数?
不适用于词汇绑定。Common Lisp 无法从类似的命名符号访问词法变量。您需要将变量声明为special。
因此,如果参数在函数中不存储为符号,那么本例中的 x 到底是什么?
处理器寄存器?堆栈框架的一部分?
使用动态绑定:
CL-USER 40 > (defun foo (a b)
(declare (special a b))
(dolist (v '(a b))
(if (zerop (symbol-value v))
(set v 10)))
(values a b))
FOO
CL-USER 41 > (foo 1 0)
1
10
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
383 次 |
| 最近记录: |