Как оценить переменные перед добавлением их в список?


30

Ниже, очевидно, не работает, и, следовательно, этот вопрос.

Как мне исправить приведенный ниже код, чтобы значение somelistстало '(("abc" . 123))?

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

5
Вы пробовали квазицитирование? Попробуй `(,x . ,y).
Дан

Ах, это то, что я пропустил. Я не знал, что гуглить для :). Я пытался, (add-to-list 'somelist '(,x . ,y))но забыл цитату.
Каушал Моди

Вопросы, считающиеся дубликатами этого, повторяются очень часто. Может кто-нибудь придумать способ, чтобы новичкам было понятнее, что этот вопрос / ответ - это то, что они ищут? Я подозреваю, что отчасти проблема заключается в том, что заголовок этого вопроса имеет смысл только в том случае, если вы уже знаете причину проблемы (т. Е. Знаете, что-то знаете). Я пытаюсь представить себя пользователем, который не имеет представления о том, что переменные нужно оценивать, и еще меньше - о том, что означает «цитата», но я становлюсь пустым. @Нарисовался?
Стефан

@stefan: в отличие от случая, когда есть сообщение об ошибке (которое можно использовать в заголовке вопроса сообщества Q + A), ошибка, если таковая имеется, возникает в результате цитирования чего-то, что необходимо оценить (и это конкретное случай этого) может быть далеко от места цитирования. Чаще всего нет ошибки (Emacs) - только поведение, которое не соответствует желанию пользователя.
Дрю

@Stefan: Для этого не приходит на ум большое название вопроса. Но мы могли бы, по крайней мере, сформулировать вопрос, который решает его непосредственно, в том числе, возможно, «нормальный» случай, который требует простого удаления знака кавычки, и случай, который требует квазиквотирования. Хороший вопрос, охватывающий такие случаи, и хороший ответ, охватывающий их, был бы полезен. Но что касается поиска Q, которые являются дубликатами: без сообщения об ошибке в заголовке Q требуется прочитать весь вопрос и знать, как найти дубликат для указания.
Дрю

Ответы:


30

Общая проблема заключается в том, что вам нужно xи yнужно оценить, прежде чем они будут вставлены в 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 x y)

Конечно, вы также можете квазицитировать, но это не имеет смысла, и выглядит хуже. Только использовать `и ,когда это улучшает читаемость, то есть , когда делает что - то более сложное , чем строительство ячейки минусы или добавление атома или списка в начале какого - то существующего списка.

При использовании квазицитирования это будет выглядеть так:

`(,x . ,y)

Что еще хуже, потому что он использует дополнительный синтаксис, который вообще не требуется в этом случае, и запутывает consиспользуемый язык.


3
Хороший вопрос по поводу cons. Квазицитирование поражает меня как более детальный контроль над содержимым списка, а не читаемостью, но я согласен, что вариант использования имеет смысл cons.
Дан

Спасибо за ваш ответ. Это был отличный момент для меня. Я слепо ставил цитаты перед списками и минусами.
Каушал Моди

@ Дэн, ну да - и нет. Quasiquoting все , что вы не могли бы сделать с просто не может сделать cons, listи nconc. За исключением того, чтобы быть красивее. Это синтаксический сахар, который полезен, когда вам нужно «детальное управление содержимым списка» (как в «выполнении чего-то более сложного, чем добавление атома или списка в начале»). И дополнительное преимущество использования этого синтаксического сахара: удобочитаемость. Квазицитирование не дает вам дополнительного более детального контроля - оно просто позволяет вам делать то же самое с меньшим количеством ошибок в первой попытке. :-)
tarsius
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.