неожиданный результат из списка - PullRequest
1 голос
/ 05 января 2020

У меня есть структура spider:

(defstruct spider omegas values k)

И экземпляр spider :

(set '*spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k '(#'omegashift #'dec #'dupval '((0 . #'dec) (1 . #'inc) (2 . #'dec)))))

Но когда я запускаю выражение: (listp (car (spider-k *spider*)) в Emacs и SBCL (и SLIME участвует, но я не уверен, что это такое.) REPL возвращает T. Это явно сбивает с толку, поскольку (car (spider-k *spider*) правильно возвращает #'OMEGASHIFT, а (listp (function OMEGASHIFT)) правильно возвращает NIL.

Почему (listp (car (spider-k *spider*)) верно? Разве это не должно быть ложным?

1 Ответ

6 голосов
/ 05 января 2020

#'omegashift - это макрос для чтения, который расширяется до списка (function omegashift).

Когда вы оцениваете (function omegashift), вы получаете функцию, но вы не оцениваете ее, потому что вы цитировали список. Итак, вы просто получаете список, до которого расширяется макрос для чтения.

Вы бы увидели то же самое, если бы сделали (listp (car '('foo))). 'foo расширяется до списка (quote foo). Это приводит к символу foo, но кавычка перед списком препятствует вычислению.

Чтобы получить функции вместо списков, вам нужно вычислить выражения функции. Вы можете сделать это, вызвав функцию list вместо цитирования списка.

(setq *spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k (list #'omegashift #'dec #'dupval (list (cons 0  #'dec) (cons 1  #'inc) (cons 2  #'dec)))))

Вы также можете использовать обратную цитату, чтобы упростить это:

(setq *spider* (make-spider
  :omegas '()
  :values (list *input*)
  :k `(,#'omegashift ,#'dec ,#'dupval '((0 . ,#'dec) (1 . ,#'inc) (2 . ,#'dec)))))

Внутри выражения в кавычках вы используйте запятую, чтобы отметить подвыражения, которые вы хотите вычислить.

Кстати, вы должны использовать setq для присваивания переменных, а не set с символом в кавычках. Они эквивалентны для глобальных переменных, но вы не можете использовать set с локальной переменной.

...