Що робить "символ-значення"?


13

Документи не зробили мене мудрішим:

Ця функція повертає значення, збережене у комірці знаку символу. Тут зберігається поточне (динамічне) значення змінної. Якщо змінна не має локальної прив'язки, це просто її глобальне значення. Якщо змінна недійсна, сигналізується про помилку змінної пустоти.

У чому полягає значення символу-значення? Де і коли мені потрібно його використовувати?


3
Дякуємо, що спробували знайти відповідь, попросивши Emacs. Це правильний підхід: спочатку запитайте Emacs, а потім запитайте тут про все, що ще не зрозуміло, повідомте нам у вашому питанні, що ви вже спробували. Кудо!
Дрю

Відповіді:


13

Вам це потрібно, коли в коді Elisp ви хочете отримати значення символу, тобто його значення, коли розглядається як змінна.

Майте на увазі, що символ Elisp має кілька характеристик / особливостей:

  • Він має назву (яка функція symbol-nameдає)
  • Це може мати значення, якщо розглядати його як змінну (що symbol-valueдає)
  • Він може назвати функцію, якщо розглядати її як функцію (яка symbol-functionдає)
  • Він має список властивостей (який symbol-plistдає)

Подумайте про символ як на предмет, з різними атрибутами.


1
Зауважте також, що (як свідчить документація) symbol-valueзавжди повертається динамічне прив'язування символу. Таким чином ви не можете отримати лексичні значення.
філс

2
Також дивіться C-h i g (elisp) Symbol Components RETдокументацію щодо цих різних комірок / компонентів символів.
філс

@phils: Гм, мені цікаво : (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.
Дрю

10

(Doh, @Drew вже поставив щось із наступного. У будь-якому випадку, ось додаткові деталі.)

Як пояснюється сторінка керівництва щодо компонентів символів , до кожного символу є чотири компоненти (комірки): його комірка імені друку, клітинка значення, визначення функції та список властивостей. Або клітинка значення, або функціональна комірка можуть бути недійсними, і список властивостей може бути нульовим.

Як зазначається в посібнику:

Оскільки кожен символ має окремі комірки значень та функцій, імена змінних та назви функцій не суперечать.

Ось чому ви можете мати, наприклад:

(setq test "kittens")
(defun test ()
  (message "puppies"))
(symbol-value 'test)    ; => "kittens"
(symbol-function 'test) ; => (lambda nil (message "puppies"))

1
Так, це значення на відміну від функції полегшило розуміння. Дякую.
The Unfun Cat

8

Ось трохи історичної довідки (я ще не народився, коли відбувалися описані події, тому, можливо, хтось більш обізнаний мене виправить. Все це - від читання старих статей та деяких книг).

Відмовившись від відмови від відповідальності, здається, що ще в часи Фортран проти Ліспа "символічний" був своєрідним модним словом, оскільки "об'єктно орієнтований" є сьогодні. Тобто програми, як правило, розглядаються як просто величезні математичні формули, де в кінцевому підсумку будуть підключені числа, а місця заповнення чисел не мають значення. Вся символічна інформація, що міститься в програмі, буде зникати, як тільки ця програма була запущена, складена або інтерпретована. Новинка Лісп полягала в тому, що вона дозволяла символам зберігатися в програмі навіть після її запуску, складання чи інтерпретації. Це надихнуло таку термінологію, як "символічна алгебра" (як при маніпулюванні алгебраїчними формулами, як це робиться на папері / дошці, а не шляхом прямого обчислення). Для підтримки цієї (та інших символічних речей) символи мали бути обладнані іменем та деякими властивостями. З несимволічної точки зору, можна сказати, що "символи називаються лише вказівниками", і хоча це неправда, якщо що-небудь, то вони більше є вказівниками на структури, але для практичних цілей символи є позначеннями зліва сторона пари змінної величини. Це також дає можливість побачитиsymbol-value функціонувати як перенаправлення покажчика в несимволічних мовах.

Сучасні Lisps відрізняються тим, скільки значень може бути пов'язано з одним символом (припустимо, у вас була несимволічна мова з кількома стеками / купими пам'яті, ви можете уявити ситуацію, коли той самий покажчик має значення, коли його інтерпретують у контексті різних стеків / купи). Отже, мови Lisp2 (одна з таких мов Emacs Lisp) мають окреме сховище для функцій та змінних, тому існує також і a symbol-function, який "перенаправляє покажчик, що вказує на сховище функції". Схема не має цього спеціального сховища, а Clojure AFAIK не має ні того, ні symbol-plist.


7

Мала демонстрація:

(setq v1 10)
;;10
v1
;;10
(setq v2 'v1)
;;v1
v2
;;v1
(symbol-value v2)
;;10 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.