Jak ocenić zmienne przed dodaniem ich do listy?


30

Poniższe oczywiście nie działa i stąd to pytanie.

Jak poprawić poniższy kod, aby wartość someliststała się '(("abc" . 123))?

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

5
Próbowałeś quasi-cytowania? Spróbować `(,x . ,y).
Dan

Ach, tego mi brakowało. Nie wiedziałem, po co google :). Próbowałem, (add-to-list 'somelist '(,x . ,y))ale zapomniałem cytatu.
Kaushal Modi

Pytania uważane za duplikaty tego pytania powtarzają się bardzo często. Czy ktoś może wymyślić sposób, aby wyjaśnić początkującym, że to pytanie / odpowiedź jest tym, czego szuka? Podejrzewam, że część problemu polega na tym, że tytuł tego pytania ma sens tylko wtedy, gdy znasz już pierwotną przyczynę problemu (tzn. Znasz swoją odpowiedź). Próbuję sobie wyobrazić siebie jako użytkownika, który nie ma pojęcia, że ​​zmienne wymagają oceny, a tym bardziej nie rozumie, co oznacza „cytat”, ale jestem pusty. @Drew?
Stefan

@stefan: W przeciwieństwie do przypadku, w którym pojawia się komunikat o błędzie (którego można użyć w tytule pytania społeczności Q + A), błąd, jeśli występuje, wynikający z cytowania czegoś, co należy ocenić (i jest to szczególny taki przypadek) może znajdować się daleko poza miejscem cytowania. Częściej nie występuje błąd (Emacs) - po prostu zachowanie, które nie odpowiada oczekiwaniom użytkownika.
Drew,

@Stefan: Nie przychodzi mi do głowy żaden wielki tytuł pytania. Ale moglibyśmy przynajmniej sformułować pytanie, które bezpośrednio je rozwiązuje, w tym być może „normalną” sprawę, która wymaga jedynie usunięcia znaku cudzysłowu i sprawę, która wymaga quasi-cytowania. Pomocne byłoby dobre Q obejmujące takie przypadki i dobra odpowiedź na nie. Ale jeśli chodzi o znalezienie Q, które są duplikatami: bez komunikatu o błędzie w tytule Q trzeba przeczytać całe pytanie i wiedzieć, jak znaleźć duplikat, na który należy wskazać.
Drew,

Odpowiedzi:


30

Ogólnym problemem jest to, że trzeba xi ynależy ocenić, zanim zostaną one umieszczone w somelist. Problem z cytowaną listą (ze 'składnią as czytnika) polega na tym, że quotejest to specjalna forma, która nie ocenia swojego argumentu. Zgodnie z dokumentacją:

(quote ARG)

Zwraca argument, nie oceniając go. (quote x)daje x. Ostrzeżenie: quotenie konstruuje zwracanej wartości, a jedynie zwraca wartość, która została wcześniej skonstruowana przez czytnik Lisp ...

Dlatego musisz albo cofnąć cudzysłów, albo użyć funkcji, która ocenia argumenty.

Cofanie cudzysłowu pozwala oceniać elementy listy z cudzysłowami selektywnie za pomocą ,składni:

(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"))

Alternatywnie możesz użyć cons(jak sugeruje @tarsius w swojej odpowiedzi) lub, dla dowolnej liczby elementów 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"))

Które użyć zależy od tego, co musisz zrobić z elementami.


19

Nie cytuj komórki minus, ponieważ cytowane wyrażenia nie są oceniane. Właśnie dlatego cytuje się - aby zapobiec ocenie. Ale nie tego chcesz, więc nie rób tego.

Zamiast tego użyj formularza, który tworzy komórkę przeciw z dwóch ocenianych wartości, jej argumentów.

(cons x y)

Oczywiście możesz także quasi-cytat, ale to naprawdę nie ma sensu i wygląda gorzej. Używać tylko `i ,kiedy który poprawia czytelność, to znaczy, gdy robi coś bardziej skomplikowanego niż skonstruowania komory minusy lub dodając atom lub listy na początku jakiejś istniejącej listy.

Przy użyciu quasi-cytowania wyglądałoby to tak:

`(,x . ,y)

Co jest gorsze, ponieważ używa dodatkowej składni, która wcale nie jest wymagana w tym przypadku i zaciemnia consużywaną.


3
Dobra uwaga na consing. Quasi-cytowanie wydaje mi się bardziej precyzyjne niż kontrola czytelności zawartości listy, ale zgadzam się, że przypadek użycia ma sens cons.
Dan

Dziękuję za Twoją odpowiedź. To był dla mnie świetny moment TIL. Ślepo stawiam cytaty przed listami i wadami.
Kaushal Modi

@ Dan, cóż, tak - i nie. Quasiquoting nic, że nie można zrobić z po prostu nie może zrobić cons, listi nconc. Z wyjątkiem tego, że jest ładniejszy. Jest to cukier składniowy, który jest przydatny, gdy potrzebujesz „drobnoziarnistej kontroli zawartości listy” (jak w „robieniu czegoś bardziej złożonego niż dodawanie atomu lub listy na początku”). Dodatkową zaletą stosowania tego cukru syntaktycznego jest: czytelność. Quasiquoting nie daje ci dodatkowej, bardziej szczegółowej kontroli - pozwala tylko zrobić to samo z mniejszą liczbą błędów w początkowej próbie. :-)
tarsius
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.