Если вы хотите изменить слот объекта, вам нужно передать сам объект в свою функцию, а не только значение слота, который вы хотите изменить.
РЕДАКТИРОВАТЬ: относительно edit2 вопроса
Я предполагаю, my-list
- это имя класса, и вы на самом деле не хотите передавать его в функцию, верно?В этом случае вы должны заменить defun
на defmethod
.Кроме того, лучше изменить экземпляр только один раз, после того как вы перевернули весь список, а не на каждом этапе.Для этого можно использовать внутреннюю функцию:
(defmethod my-reverse ((l my-list))
(labels ((inner (list acc)
(if (endp list)
acc
(inner (rest list) (cons (first list) acc)))))
(setf (my-list-ls l) (inner (my-list-ls l) ()))))
РЕДАКТИРОВАТЬ 2: подробное объяснение
defmethod
является альтернативой defun
для определения (полиморфных) методов.Хотя, если вам не нужен полиморфизм, вы можете просто использовать (defun my-reverse (l)
для первой строки.
labels
для внутренних определений функций.Здесь он определяет внутреннюю функцию с именем inner
с двумя параметрами list
и acc
.inner
- это функция, которая выполняет реверсирование, и это хвостовая рекурсивная функция, потому что реверсирование происходит естественным образом с хвостовой рекурсией.(Он может построить свой результат с cons
и поэтому имеет линейную сложность, тогда как вашему решению требуется append
и, следовательно, имеет квадратичную сложность, потому что cons
само по себе является постоянным, а append
является линейным.)
first
и rest
- это просто альтернативные имена для car
, а cdr
, endp
- это в основном просто альтернативное имя для null
, с той разницей, что endp
будет сигнализировать об ошибке, если егоАргумент на самом деле не является списком.
Наконец, последняя строка вызывает inner
с исходным и пустым списком в качестве аргументов и присваивает результат слоту (он же переменная экземпляра).