Почему (find-if # 'consp' ('notdefinedsymbol)) =>' NOTDEFINEDSYMBOL? - PullRequest
0 голосов
/ 04 марта 2020

Этот код поступил из буфера emacs slime-repl sbcl :

CL-USER> (consp 'notdefinedsymbol)

NIL

CL-USER> (find-if # 'consp' ('notdefinedsymbol))

' NOTDEFINEDSYMBOL

Если consp возвращает nil, тогда почему find-if действует так, как будто consp возвращает истинное значение?

Ответы [ 3 ]

3 голосов
/ 04 марта 2020

С (consp 'notdefinedsymbol) consp в позиции оператора является символом для функции #'consp, и, следовательно, ее аргумент (quote notdefinedsymbol), сокращенно просто 'notdefinedsymbol, должен быть оценен перед применением. A (quote x) соответствует данным x, поэтому в нашем случае аргумент становится символом notdefinedsymbol. Это НЕ cons, а symbolp, и, следовательно, результат равен nil

Со вторым у вас есть (find-if #'consp '('notdefinedsymbol)), и, поскольку find-if является функцией, он оценивает свои аргументы. #'consp оценивает функциональный объект, а '('notdefinedsymbol), что является сокращением от (quote ((quote notdefinedsymbol))), оценивает. Как всегда, он оценил свой аргумент ((quote notdefinedsymbol)). Это список с одним элементом, который сам является списком с двумя элементами, символами quote и notdefinedsymbol. Поскольку (consp '(quote notdefinedsymbol) ; ==> t find-if оценивается как (quote notdefinedsymbol), и некоторые принтеры CL сокращают список из двух элементов, где первый элемент - quote, так же, как макрос чтения, и выдают 'notdefinedsymbol, но он по-прежнему является списком из двух элементов, так как это не код, а данные.

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

(find-if #'consp '(notdefinedsymbol)) ; ==> nil
1 голос
/ 04 марта 2020

Ваш звонок: (find-if #'consp '('not-defined-symbol)) такой же, как (т. Е. Расширяется читателем) (find-if (function consp) (quote ((quote not-defined-symbol)))). Аргумент (quote ((quote not-defined-symbol))) оценивается как список ((quote not-defined-symbol)) (т.е. список, содержащий список, содержащий два символа quote и not-defined-symbol). Find-if проходит через этот внешний список, проверяет внутренний, который является минусом, с consp, который говорит true , и возвращает его.

Больше всего вы хотели бы сделать вероятно: (find-if #'consp '(not-defined-symbol)), что совпадает с (find-if (function consp) (quote (not-defined-symbol)). Примечание: нет вложенной цитаты.

Посмотрите на документы для quote и главу CLHS об оценке для лучшего понимания.

1 голос
/ 04 марта 2020

(consp 'a) - аргументы функции оцениваются первыми. Таким образом, мы имеем: 'a оценивает до: a. И это атом, поэтому NIL.

(find-if #'consp '('a)) также вначале излагает аргументы. Но для первого аргумента списка проверяется, является ли 'a минусом. Это потому, что это (quote a) (оценивается только внешний ' списка, внутренний перед a нет, поэтому 'a.

a = notdefinedsymbol.

...