¿Qué hace `valor-símbolo`?

13

Los documentos no me hicieron más sabio:

Esta función devuelve el valor almacenado en la celda de valor del símbolo. Aquí es donde se almacena el valor actual (dinámico) de la variable. Si la variable no tiene enlace local, este es simplemente su valor global. Si la variable es nula, se señala un error de variable nula.

¿Cuál es el punto del valor del símbolo? ¿Dónde y cuándo necesito usarlo?

El gato no divertido
fuente
3
Gracias por intentar encontrar la respuesta preguntando a Emacs. Ese es el enfoque correcto: pregúntele primero a Emacs, y luego pregunte aquí sobre lo que todavía no está claro, díganos en su pregunta lo que ya ha intentado. ¡Prestigio!
Drew

Respuestas:

13

Lo necesita cuando, en el código Elisp, desea obtener el valor de un símbolo, es decir, su valor cuando se considera como una variable.

Tenga en cuenta que un símbolo de Elisp tiene varias características / características:

  • Tiene un nombre (que función symbol-namele da)
  • Puede tener un valor, cuando se considera como una variable (que symbol-valueda)
  • Podría nombrar una función, cuando se considera como una función (que symbol-functionda)
  • Tiene una lista de propiedades (que symbol-plistda)

Piense en un símbolo como un objeto, con varios atributos.

Dibujó
fuente
1
Tenga en cuenta también que (como lo indica la documentación) symbol-valuesiempre devuelve el enlace dinámico para el símbolo. No puede obtener valores léxicos de esta manera.
phils
2
Consulte también la C-h i g (elisp) Symbol Components RETdocumentación sobre estas diversas celdas / componentes de símbolos.
phils
@phils: Hm, me pregunto: (setq lexical-binding t) (let ((v 42)) (message "lex: %S, val: %S" lexical-binding (symbol-value 'v))). Pero sí, eso es lo que dice en (elisp) Lexical Binding: " funciona como symbol-value, boundp'y set'solo recupera o modifica el enlace dinámico de una variable (es decir, el contenido de la celda de valor de su símbolo) ". Sin embargo, no se dice nada al respecto Symbol Components.
Dibujó
10

(Doh, @Drew ya puso algo de lo siguiente. De todos modos, aquí hay algunos detalles adicionales).

Como explica la página del manual sobre componentes de símbolos , hay cuatro componentes (celdas) para cada símbolo: su celda de nombre de impresión, su celda de valor, su definición de función y su lista de propiedades. La celda de valor o la celda de función pueden ser nulas y la lista de propiedades puede ser nula.

Como el manual también señala:

Debido a que cada símbolo tiene celdas de valores y funciones separadas, los nombres de las variables y los nombres de las funciones no entran en conflicto.

Por eso puedes tener, por ejemplo:

(setq test "kittens")
(defun test ()
  (message "puppies"))
(symbol-value 'test)    ; => "kittens"
(symbol-function 'test) ; => (lambda nil (message "puppies"))
Dan
fuente
1
Ah, que es valor en lugar de función, lo hizo mucho más fácil de entender. Gracias.
The Unfun Cat
8

Aquí hay un poco de referencia histórica (no he nacido aún cuando ocurrieron los eventos descritos, así que tal vez alguien más conocedor me corrija. Todo esto es de leer artículos viejos y algunos libros).

Habiendo prescindido del descargo de responsabilidad, parece que en los días de Fortran vs Lisp "simbólico" era una especie de palabra de moda como "orientado a objetos" es hoy. Es decir, los programas se veían típicamente como enormes fórmulas matemáticas en las que los números eventualmente se conectarían y los marcadores de posición para los números eran irrelevantes. Toda la información simbólica contenida en un programa desaparecerá tan pronto como se ejecute, compile o interprete. La novedad de Lisp era que permitía que los símbolos persistieran en un programa incluso después de ejecutarse, compilarse o interpretarse. Esto inspiró una terminología como "álgebra simbólica" (como en la manipulación de fórmulas algebraicas como se hace en papel / pizarra en lugar de por cálculo directo). Para respaldar esto (y otras cosas simbólicas), los símbolos debían estar equipados con un nombre y algunas propiedades. Desde un punto de vista no simbólico, se podría decir que "los símbolos son simplemente punteros nombrados", y si bien esto no es cierto, en todo caso son más punteros a estructuras, pero a efectos prácticos, los símbolos son designadores de la izquierda lado de la mano de un par de valores variables. Esto también hace posible versymbol-value funcionan como referencia de puntero en lenguajes no simbólicos.

Los Lisps modernos varían en cuanto a la cantidad de valores que se pueden asociar con un símbolo (supongamos que tiene un lenguaje no simbólico con múltiples pilas / montones de memoria, podría imaginar una situación en la que el mismo puntero tiene significado cuando se interpreta en el contexto de diferentes pilas / muchísimo). Entonces, los lenguajes Lisp2 (Emacs Lisp es uno de esos lenguajes) tienen un almacenamiento separado para funciones y variables, es por eso que también hay un symbol-function, que "hace referencia a un puntero que apunta a un almacenamiento de funciones". Scheme no tiene este almacenamiento especial y Clojure AFAIK, no tiene ni eso ni eso symbol-plist.

wvxvw
fuente
7

Pequeña demostración:

(setq v1 10)
;;10
v1
;;10
(setq v2 'v1)
;;v1
v2
;;v1
(symbol-value v2)
;;10 
abo-abo
fuente