Вопрос

Я читаю «О lisp» и столкнулся с этим кодом (немного его упростил).

CL-USER> (defun foo ()                                                          
           '(a b c))
FOO                                                                             
CL-USER> (foo)
(A B C)                                                                         
CL-USER> (nconc * '(D E))
(A B C D E)                                                                     
CL-USER> (foo)
(A B C D E) 
CL-USER> (defun foo ()                                                          
          (list 'a 'b 'c))
STYLE-WARNING: redefining FOO in DEFUN                                          
FOO                                                                             
CL-USER> (foo)
(A B C)                                                                         
CL-USER> (nconc * '(D E))
(A B C D E)                                                                     
CL-USER> (foo)
(A B C)
  • Что именно делает * иметь в виду?Это предыдущий вызов функции?Подходит ли он для использования в реальном коде?

  • Почему (nconc * '(D E)) измените возвращаемое значение первого foo функция?

  • Я всегда думал (list 'a 'b 'c) и '(a b c) одинаковы?В чем разница?

Это было полезно?

Решение

Вызов LIST создает новый список каждый раз при его оценке.Литерал списка может быть помещен в сегмент памяти только для чтения после компиляции.Деструктивное обновление списков с помощью NCONC становится проблематичным, возможно, с неопределенными последствиями (ошибка сегментации, изменение литерала для будущих ссылок или вообще ничего).

Другие советы

Переменные *, ** и *** определяются языком стандартный и они весьма полезны при тестировании.Они являются особенностью REPL и поэтому не должны и не должны быть полезны в «реальном коде».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top