在将变量添加到列表之前如何求值?


30

下面显然不起作用,因此这个问题。

如何更正下面的代码,以使值somelist变为'(("abc" . 123))

(setq x "abc")
(setq y 123)
(setq somelist nil)
(add-to-list 'somelist '(x . y))

5
您是否尝试过准报价?尝试`(,x . ,y)

啊,那是我想念的。我不知道该用什么Google :)。我尝试过(add-to-list 'somelist '(,x . ,y))但忘了反引号。
Kaushal Modi 2015年

被认为是与此重复的问题经常出现。有人可以提出一种方法来使初学者更清楚地知道这个问题/答案是他们想要的吗?我怀疑问题的部分原因是,如果您已经知道问题的根本原因(即,您有点知道答案),那么该问题的标题才有意义。我试图将自己想象成一个用户,他不知道需要对变量进行求值,甚至更不知道“ quote”是什么意思,而是虚无。@Drew?
Stefan

@stefan:与出现错误消息(可以在社区Q + A的问题标题中使用)不同,该错误(如果有的话)是由于引用了需要评估的内容而引起的(这是特定的的情况)可以在报价网站的远处。更常见的是,没有(Emacs)错误-只是与用户想要的行为不符的行为。
提请

@Stefan:对此没有什么好问的标题。但是我们至少可以提出一个直接解决该问题的问题,其中可能包括一个要求删除引号的“正常”案例和一个要求准引用的案例。一个好的Q,涵盖了这些情况,一个好的答案,将对您有所帮助。但是对于查找重复的Q:在Q标题中没有错误消息,则需要阅读整个问题并知道如何找到要指向的重复。
提请

Answers:


30

一般的问题是,你需要xy他们得到插入前进行评估somelist。带引号的列表(使用'阅读器语法)的问题在于,这quote是一种特殊形式,不评估其参数。根据文档字符串:

(quote ARG)

返回参数,不对其求值。 (quote x)产量x。警告:quote不构造其返回值,而只是返回由Lisp阅读器预先构造的值...

因此,您需要反引号或使用一个计算参数的函数。

通过使用反引号,您可以使用以下,语法有选择地评估被引号列表的元素:

(setq x "x-val" y "y-val" z "z-val" somelist nil)
'(x  y z)                            ; => (x y z)
`(x ,y z)                            ; => (x "y-val" z)
(add-to-list 'somelist `(x y ,z))    ; => ((x y "z-val"))

或者,您可以使用cons(如@tarsius在其答案中建议的那样),或者对于任意数量的元素,使用list

(add-to-list 'somelist (cons x y))   ; => (("x-val" . "y-val"))
(setq somelist nil)                  ; reset
(add-to-list 'somelist (list x y z)) ; => (("x-val" "y-val" "z-val"))

使用哪种取决于您需要对元素执行的操作。


19

不要引用cons单元格,因为不对引用的表达式进行求值。这就是为什么要引用-防止评估。但这不是您想要的,所以不要。

而是使用从两个评估值(其参数)创建一个cons单元格的形式。

(cons x y)

当然,您也可以准报价,但这在这里实际上没有意义,而且看起来更糟。仅当`,这样做会提高可读性时,即使用比构造cons单元格或在某些现有列表的开头添加原子或列表更复杂的方法时。

使用准引用看起来像这样:

`(,x . ,y)

更糟糕的是,因为它使用了在这种情况下根本不需要的其他语法,并且混淆了cons正在使用的语法。


3
很好cons。准引用令我印象深刻的是,它更多地是对列表内容进行细粒度的控制,而不是可读性,但我同意用例对有意义cons

谢谢您的回答。对我来说,那是一个很棒的TIL时刻。我盲目地将引号放在列表和缺点之间。
Kaushal Modi 2015年

@Dan,是的-是的。Quasiquoting不能做任何事情,你不能只做conslistnconc。除了漂亮。它是语法糖,当您需要“对列表内容进行细粒度控制”时(如“比开始时添加原子或列表更复杂的事情”),它很有用。使用该语法糖的附加好处是:可读性。准引用并不能为您提供更多的细粒度控制,它只是允许您在最初的尝试中用更少的错误来做同样的事情。:-)
tarsius
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.