Документы сделали меня не мудрее
Эта функция возвращает значение, хранящееся в ячейке значения символа. Здесь хранится текущее (динамическое) значение переменной. Если переменная не имеет локальной привязки, это просто ее глобальное значение. Если переменная void, сообщается об ошибке void-variable.
Какой смысл в значении символа? Где и когда мне нужно это использовать?
Ответы:
Это необходимо, когда в коде Elisp вы хотите получить значение символа, то есть его значение, если рассматривать его как переменную.
Имейте в виду, что символ Elisp имеет несколько характеристик / особенностей:
symbol-name
дает функция )symbol-value
дает)symbol-function
дает)symbol-plist
дает)Думайте о символе как об объекте с различными атрибутами.
источник
symbol-value
всегда возвращает динамическое связывание для символа. Вы не можете получить лексические значения таким способом.C-h i g
(elisp) Symbol Components
RET
Документацию по этим различным символьным ячейкам / компонентам.(setq lexical-binding t) (let ((v 42)) (message "lex: %S, val: %S" lexical-binding (symbol-value 'v)))
. Но да, это то, что он говорит в (elisp)Lexical Binding
: « функционирует какsymbol-value
,boundp'
иset'
только извлекает или изменяет динамическое связывание переменной (т. Е. Содержимое ячейки значения ее символа) ». Однако об этом ничего не сказаноSymbol Components
.(Doh, @Drew уже выдвинул некоторые из следующих. Во всяком случае, вот некоторые дополнительные детали.)
Как объясняется на странице руководства по компонентам символов , для каждого символа есть четыре компонента (ячейки): ячейка с именем печати, ячейка значения, определение функции и список свойств. Ячейка значения или ячейка функции может быть недействительной, а список свойств может быть нулевым.
В руководстве также указано:
Вот почему вы можете иметь, например:
источник
Вот небольшая историческая справка (я еще не родился, когда произошли описанные события, поэтому, возможно, кто-то более знающий исправит меня. Все это от чтения старых статей и некоторых книг).
Не обращая внимания на отказ от ответственности, кажется, что во времена Фортрана против Лиспа «символическое» было своего рода модным словом, как сегодня «объектно-ориентированное». Т.е. программы обычно рассматривались как просто огромные математические формулы, в которых числа в конечном итоге будут вставлены, а заполнители для чисел были несущественными. Вся символическая информация, содержащаяся в программе, исчезнет, как только эта программа будет запущена, скомпилирована или интерпретирована. Новинка Lisp заключалась в том, что он позволял символам сохраняться в программе даже после ее запуска, компиляции или интерпретации. Это вдохновило такую терминологию, как «символическая алгебра» (как при манипулировании алгебраическими формулами, как это делается на бумаге / доске, а не путем прямого вычисления). Чтобы поддержать это (и другие символические вещи), символы должны были быть снабжены именем и некоторыми свойствами. С несимволической точки зрения можно сказать, что «символы просто называются указателями», и хотя это не так, если они являются чем-то большим, чем указатели на структуры, но для практических целей символы обозначают левые сторона стороны пары переменная-значение. Это также позволяет увидеть
symbol-value
функция разыменования указателя в несимвольных языках.Современные Лиспы отличаются тем, что значения могут быть связаны с одним символом (предположим, у вас был не символический язык с несколькими стеками / кучами памяти, вы можете представить себе ситуацию, когда один и тот же указатель имеет значение при интерпретации в контексте разных стеков / отвалы). Таким образом, языки Lisp2 (Emacs Lisp является одним из таких языков) имеют отдельное хранилище для функций и переменных, поэтому существует также метод
symbol-function
, который «разыменовывает указатель, указывающий на хранилище функций». Схема не имеет этого специального хранилища, а Clojure AFAIK не имеет ни того, ни другогоsymbol-plist
.источник
Небольшая демонстрация:
источник