Próbuję przekazać listę do funkcji w Lisp i zmienić zawartość tej listy w ramach funkcji bez wpływania na oryginalną listę. Czytałem, że Lisp jest wartością typu pass-by-value i to prawda, ale jest coś, co nie jest do końca zrozumiałe. Na przykład, ten kod działa zgodnie z oczekiwaniami:W typowym selektorze, jak zmodyfikować część parametru listy z poziomu funkcji bez zmiany oryginalnej listy?
(defun test()
(setf original '(a b c))
(modify original)
(print original))
(defun modify (n)
(setf n '(x y z))
n)
Jeśli zadzwonisz (test), drukuje (a b c) chociaż (modyfikacji) zwraca (X Y Z).
Jednak nie działa w ten sposób, jeśli spróbujesz zmienić tylko część listy. Zakładam, że ma to coś wspólnego z listami, które mają taką samą zawartość wszędzie w pamięci lub coś w tym stylu? Oto przykład:
(defun test()
(setf original '(a b c))
(modify original)
(print original))
(defun modify (n)
(setf (first n) 'x)
n)
Następnie drukuje (test) (x b c). Jak więc zmienić niektóre elementy parametru listy w funkcji, tak jakby ta lista była lokalna dla tej funkcji?
Należy pamiętać, że konsekwencje modyfikacji stałych literowych są niezdefiniowane. Nie rób tego. Nigdy. "(a b c) jest literalną stałą w kodzie. Nie należy go modyfikować. Możesz modyfikować listy tworzone za pomocą funkcji LIST (lista 'a' b 'c). –
również zauważyć, że (SETF oryginał "(a b c)) nie ma sensu. SETF nie wprowadza zmiennych.zmienna "oryginał" nigdzie nie jest zdefiniowana. Możesz ustawić zmienne, które zostały wprowadzone przez LET, DEFUN, DEFVAR, DEFPARAMETER, ... –