У меня есть ниже:
(setq some-variable "less")
Я смущен, почему я должен использовать одинарную кавычку с, boundp
но не с bound-and-true-p
.
Пример 1:
(when (boundp 'some-variable)
(message "some-variable is %s" some-variable))
Результат:
"некоторая переменная меньше"
Пример 2а:
(when (bound-and-true-p some-variable) ;; Note that using single-quote causes error
(message "some-variable is %s" some-variable))
Результат:
"некоторая переменная меньше"
Пример 2б:
(when (bound-and-true-p 'some-variable) ;; Note that using single-quote causes error
(message "some-variable is %s" some-variable))
Результат:
и: Неверный аргумент типа: symbolp, (указать некоторую переменную)
setq
означаетset quoted
, и изначально был макрос, который расширился в(set 'some-variable "less")
. В целом, Elisp не очень согласован в отношении аргументов, заключенных в кавычки, а не в кавычки, но любая функция (не макрос), которая должна взаимодействовать с переменной, а не со значением, получит свой аргумент в кавычках (setq
что является основным исключением).bound-and-true-p
это глупый макрос. Вернее, его имя глупо. 99,99% времени, когда вы хотите это сделать,(and (boundp 'FOO) FOO)
вы используете значениеFOO
. Вы делаете это не просто для того, чтобы получить истинную ценность. (1) Макрос не нужен - код, который он заменяет, тривиален и мал. (2) Имя вводит в заблуждение - оно касается значения переменной, а не просто проверяет, является ли значение переменнойnil
.Ответы:
Краткий ответ
Если вы пытаетесь использовать саму переменную, используйте
'some-variable
. Если вы пытаетесь использовать значение, хранящееся в переменной, используйтеsome-variable
.объяснение
Для определения вручную см. Руководство .
'
и(quote ...)
оба выполняют одну и ту же цель в emacs-lisp.Цель этого состоит в том, чтобы передать неоцененную форму в окружающую среду, а не оценить ее.
В вашем примере предположим, что у нас было следующее выше
Тогда оценка идет следующим образом:
Тогда как без цитаты:
Lisp оценивает формы по мере их поступления, заключая в кавычки форму, которую вы запрещаете оценивать, чтобы передать фактическую переменную (или список, или имя функции).
источник
bound-and-truep
и вопрос заключался в том, почему я должен цитировать при использовании,boundp
а не при использованииbound-and-truep
.boundp
требованием символа (без оценки) иbound-and-truep
необходимостью значения переменной в точках маркера (отредактировано после первоначального ответа)Символ, который находится в нефункциональном положении, обрабатывается как имя переменной. In
(function variable)
function
находится в функции-положении (после открывающей скобки) иvariable
не находится. Если явно не заключенные в кавычки переменные заменены их значениями.Если бы вы написали
(boundp my-variable)
, это означало бы «это символ, который хранится в значении переменной,my-variable
связанной как переменная», а не «это символ,my-variable
связанный как переменная.Так почему же
bound-and-truep
ведет себя по-другому?Это макрос, и нормальные (функциональные) правила оценки здесь не применяются, макросы могут сами решать, когда и когда их аргументы оцениваются. Что на самом деле делают макросы, так это как-то преобразовывают аргументы и возвращают результат в виде списка, который затем оценивается. Преобразование и окончательная оценка происходят в разное время, называемое временем макроразложения и временем оценки.
Вот как
bound-and-true-p
выглядит определение :При этом используются макросы чтения, которые отличаются от макросов lisp (подробнее об этом ниже). Чтобы не усложнять это далее, давайте не будем использовать какие-либо макросы чтения:
Если ты пишешь
который сначала "переводится" на
и затем это вычисляется, возвращая,
nil
еслиmy-variable
это не такboundp
или иначе значениеmy-variable
(которое, конечно, также может бытьnil
).Вы могли заметить, что расширение не было
как мы могли ожидать.
quote
это специальная форма, а не макрос или функция. Как и макросы, специальные формы могут делать что угодно со своими аргументами. Эта особая специальная форма просто возвращает свой аргумент, здесь символ, вместо значения переменной символа. Это единственная цель этой специальной формы: предотвращение оценки! Макросы не могут сделать это самостоятельно, они должны использоватьquote
это.Так в чем дело
'
? Это макрос для чтения , который, как упоминалось выше, не совпадает с макросом LISP . В то время как макросы используются для преобразования кода / данных, макросы чтения используются ранее при чтении текста, чтобы преобразовать этот текст в код / данные.это короткая форма для
`
в настоящем определенииbound-and-true-p
также используется макрос для чтения. Если он заключает в кавычки символ как в`symbol
нем, это эквивалентно'symbol
, но когда используется для цитирования списка, так как`(foo bar ,baz)
он ведет себя по-разному в тех формах, с которыми ставится префикс,
, оцениваются.эквивалентно
Это должно ответить на вопрос, почему символы без кавычек иногда оцениваются (заменяются их значениями), а иногда нет; Макросы можно использовать
quote
для предотвращения оценки символа.Но почему
bound-and-true-p
макроса покаboundp
нет? Мы должны быть в состоянии определить, связаны ли произвольные символы, которые не известны до времени выполнения, как символы. Это было бы невозможно, еслиboundp
аргумент был автоматически указан.bound-and-true-p
используется, чтобы определить, определена ли известная переменная и, если да, использовать ее значение. Это полезно, если библиотека имеет необязательную зависимость от сторонней библиотеки, как в:bound-and-true-p
может быть определена как функция и требует, чтобы аргумент был заключен в кавычки, но потому что он предназначен для случаев, когда вы заранее знаете, какая переменная, которую вы заботитесь о макросе, использовалась, чтобы избавить вас от необходимости вводить'
.источник
Из исходного кода
boundp
:boundp
ожидаетsymbol
как вход.'some-variable
является символом переменнойsome-variable
.Из исходного кода
bound-and-true-p
:bound-and-true-p
ожидаетvariable
как вход.Внутри
bound-and-true-p
макроса, он получает символ, делая(quote ,var)
. Так что, если вводsome-variable
,(quote ,var)
приведет к'some-variable
.Но когда я даю вход
'some-variable
наbound-and-true-p
, я получаю ошибку:and: Wrong type argument: symbolp, (quote some-variable)
потому что макрос не ожидает символ ('some-variable
) на входе.источник
''symbol
имеет смысл. Значит(quote (quote symbol))
. Причина, по которой вы получаете ошибку, состоит в том, что это недопустимый аргументboundp
.