如何解决在 Common Lisp 中不带括号和引号的函数中使用符号参数
(defun all-longer-than-1-char? (&rest elements)
(every (lambda (x) (> (length
(cond ( (typep x 'integer) (write-to-string x) )
( (typep x 'string) x )
( (typep x 'symbol) (symbol-name x) )
))
1))
elements))
(all-longer-than-1-char? "OK" "NO" 1)
我希望此函数可以处理符号参数(即无需双引号或输入数字),但它不起作用。要使其与符号参数一起使用:
(defun all-longer-than-1-char? (lst)
(every (lambda (x) (> (length
(cond ( (typep x 'integer) (write-to-string x) )
( (typep x 'string) x )
( (typep x 'symbol) (symbol-name x) )
))
1))
lst))
(all-longer-than-1-char? '(OK NO 1))
NIL
但是这次我必须将参数括在括号内并引用它。我想让它同时使用符号参数,而不必将参数放在括号内并引用它们,例如:
(all-longer-than-1-char? OK NO 1)
怎么做?
解决方法
您可以使用 &rest
来创建曾经被称为“nospread”函数(或“lexpr”,具体取决于您的宗教信仰)的东西,除了作为用户界面之外,它通常没有什么用处,因为如果您有一个列表,则必须使用 apply
。
Common Lisp 没有不评估其参数的函数,这曾经被称为“nlambda”(如果您属于错误的邪教,则称为“fexpr”),因此您需要引用表格否则对评估者来说意味着什么。
您可以使用宏获得与 nlambda 相同的结果。但您几乎肯定不想这样做,因为这听起来像是对宏的不当使用。
给定
(defun all-longer-than-1-char-p (list)
(every (lambda (x)
(> (length
(etypecase x
(string x)
(integer (write-to-string x))
(symbol (symbol-name x))))
1))
list))
那么 nospread 可能是
(defun all-longer-than-1-char-p/nospread (&rest list)
(all-longer-than-1-char list))
nlambda 可能是
(defmacro all-longer-than-1-char-p/quoted/nospread (&rest things)
`(all-longer-than-1-char ',things))
那么现在
> (all-longer-than-1-char-p '(xx yy 12 "foo"))
t
> (all-longer-than-1-char-p/nospread 'xx 'yy 12 "foo")
t
> (all-longer-than-1-char-p/quoted/nospread xx yy 12 "foo")
t
(所有假设 *print-base*
小于 13
)。
但是
> (let ((x "xx"))
(all-longer-than-1-char-p/quoted/nospread x))
nil
所以,在语义上不是很有用,而且是如何不使用宏的典型代表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。