Як оцінити змінні перед тим, як додати їх до списку?


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, які є дублікатами: без повідомлення про помилку в заголовку Q потрібно прочитати все запитання та знати, як знайти дублікат, на який слід вказати.
Дрю

Відповіді:


30

Загальна проблема в тому , що вам потрібно , xі yповинні бути оцінені , перш ніж вони вставлені в somelist. Проблема зі списком цитованих (з 'синтаксисом читача) полягає в тому, що quoteце спеціальна форма, яка не оцінює його аргумент. Відповідно до docstring:

(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 x y)

Звичайно, ви також можете сказати, що це цитувати, але це насправді не має сенсу, і виглядає гірше. Використовуйте лише те, `і ,коли це покращує читабельність, тобто коли ви робите щось складніше, ніж будувати клітинку мінусу або додавати атом або список на початку деякого наявного списку.

Використовуючи квасиквітування, це виглядатиме так:

`(,x . ,y)

Що гірше, тому що він використовує додатковий синтаксис, який у цьому випадку зовсім не потрібен, і обтяжує, consякий використовується.


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

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

@Dan, ну так - і ні. Quasiquoting все , що ви не могли б зробити з просто не може зробити cons, listі nconc. За винятком гарнішого. Це синтаксичний цукор, який корисний, коли вам потрібен "дрібнозернистий контроль над вмістом списку" (як у "робити щось складніше, ніж додавати атом або список на початку"). І додатковою перевагою використання синтаксичного цукру є: читабельність. Квазіквітування не дає додаткового більш дрібного контролю - воно просто дозволяє зробити те саме, що з меншою кількістю помилок у першій спробі. :-)
тарсій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.