programacion lambdas expresiones common caracteristicas functional-programming lisp common-lisp symbols

functional programming - lambdas - ¿Cuál es la diferencia entre una variable y un símbolo en LISP?



lambdas java (7)

En términos de alcance? ¿Implementación actual en memoria? La sintaxis? Por ejemplo, si (deja 1) ¿Es ''a'' una variable o un símbolo?


Agregando una nota al margen de las respuestas anteriores:

Los recién llegados a Lisp a menudo no están seguros de para qué son exactamente los símbolos, además de ser los nombres de las variables. Creo que la mejor respuesta es que son como constantes de enumeración, excepto que no tienes que declararlas antes de usarlas. Por supuesto, como han explicado otros, también son objetos. (Esto no debería parecer extraño para los usuarios de Java, en el que las constantes de enumeración también son objetos).


Citando de la HyperSpec de Common Lisp :

symbol n. Un object de type symbol .

variable n. Un binding en el namespace "variable".

binding n. una asociación entre un name y lo que el nombre denota. (…)

Tiempo de explicación.

Lo que Lisp llama símbolos está bastante cerca de lo que muchos idiomas llaman variables. En una primera aproximación, los símbolos tienen valores; cuando evalúa la expresión x , el valor de la expresión es el valor del símbolo x ; cuando escribe (setq x 3) , asigna un nuevo valor a x . En la terminología de Lisp, (setq x 3) une el valor 3 al símbolo x .

Una característica de Lisp que la mayoría de los lenguajes no tiene es que los símbolos son objetos ordinarios (los símbolos son objetos de primera clase, en la terminología del lenguaje de programación). Cuando escribe (setq xy) , el valor de x convierte en el valor de y en el momento de la asignación. Pero puede escribir (setq x ''y) , en cuyo caso el valor de x es el símbolo y .

En términos conceptuales, existe un environment que es una tabla de asociación de símbolos a valores. Evaluar un símbolo significa buscarlo en el entorno actual. (Los entornos también son objetos de primera clase, pero esto está fuera del alcance de esta respuesta). Un enlace se refiere a una entrada particular en un entorno. Sin embargo, hay una complicación adicional.

La mayoría de los dialectos Lisp tienen múltiples espacios de nombres, al menos un espacio de nombres de variables y un espacio de nombres de funciones. De hecho, un entorno puede contener varias entradas para un símbolo, una entrada para cada espacio de nombres. Una variable, estrictamente hablando, es una entrada en un entorno en el espacio de nombres de variables . En la terminología de Lisp de todos los días, a un símbolo se le conoce como variable cuando lo que le interesa es su vinculación como variable.

Por ejemplo, en (setq a 1) o (let ((a 1)) ...) , a es un símbolo. Pero como las construcciones actúan sobre la variable de enlace para el símbolo a , es común referirse a a como una variable en este contexto.

Por otro lado, en (defun a (...) ...) o (flet ((a (x) ...)) ...) , a es también un símbolo, pero estas construcciones actúan sobre su función vinculante, por lo que a no se consideraría una variable.

En la mayoría de los casos, cuando un símbolo aparece sin comillas en una expresión, se evalúa buscando su enlace variable. La excepción principal es que en una llamada de función (foo arg1 arg2 ...) , se utiliza la función de enlace para foo . El valor de un símbolo entre comillas ''x (quote x) es en sí mismo, como con cualquier expresión entre comillas. Por supuesto, hay muchas formas especiales en las que no necesita citar un símbolo, incluidos setq , let , flet , defun , etc.


La respuesta de Jörg apunta en la dirección correcta. Déjame añadirle un poco.

Hablaré de Lisps que son similares a Common Lisp.

Los símbolos como estructura de datos.

Un símbolo es una estructura de datos real en Lisp. Puede crear símbolos, puede usar símbolos, puede almacenar símbolos, puede pasar símbolos y los símbolos pueden formar parte de estructuras de datos más grandes, por ejemplo, listas de símbolos. Un símbolo tiene un nombre, puede tener un valor y puede tener un valor de función.

Así que puedes tomar un símbolo y establecer su valor.

(setf (symbol-value ''foo) 42)

Por lo general, uno escribiría (setq foo 42) , o (set ''foo 42) o (setf foo 42) .

Símbolos en el código que denota variables

¡Pero!

(defun foo (a) (setq a 42))

o

(let ((a 10)) (setq a 42))

En los dos formularios anteriores en el código fuente hay símbolos y a se escribe como un símbolo y al usar la función READ para leer esa fuente, aparece un símbolo a en alguna lista. Pero la operación setq NO establece el valor del símbolo de a en 42 . Aquí LET y DEFUN introducen una VARIABLE a que escribimos con un símbolo. Así, la operación SETQ luego establece el valor de la variable en 42 .

Enlace léxico

Entonces, si nos fijamos en:

(defvar foo nil) (defun bar (baz) (setq foo 3) (setq baz 3))

Introducimos una variable global FOO .

En la barra, el primer SETQ establece el valor del símbolo de la variable global FOO . El segundo SETQ establece la variable local BAZ en 3 . En ambos casos, usamos el mismo SETQ y escribimos la variable como un símbolo, pero en el primer caso, el FOO dona una variable global y esos valores se almacenan en el valor del símbolo. En el segundo caso, BAZ denota una variable local y cómo se almacena el valor, no lo sabemos. Todo lo que podemos hacer es acceder a la variable para obtener su valor. En Common Lisp no hay forma de tomar un símbolo BAZ y obtener el valor de la variable local. No tenemos acceso a los enlaces de variables locales y sus valores utilizando símbolos. Eso es parte de cómo funciona el enlace léxico de variables locales en Common Lisp.

Esto lleva, por ejemplo, a la observación de que en el código compilado sin información de depuración registrada, el símbolo BAZ se ha ido. Puede ser un registro en su procesador o implementado de otra manera. El símbolo FOO todavía está allí, porque lo usamos como una variable global.

Varios usos de los símbolos.

Un símbolo es un tipo de datos, una estructura de datos en Lisp.

Una variable es una cosa conceptual. Las variables globales se basan en símbolos. Variables léxicas locales no.

En el código fuente escribimos todo tipo de nombres para funciones, clases y variables usando símbolos.

Hay una superposición conceptual:

(defun foo (bar) (setq bar ''baz))

En el código de FUENTE anterior, defun , foo , bar , setq y baz son todos símbolos.

DEFUN es un símbolo que proporciona una macro. FOO es un símbolo que proporciona una función. SETQ es un símbolo que proporciona un operador especial. BAZ es un símbolo utilizado como datos. Así la cita ante BAZ . BAR es una variable. En el código compilado su símbolo ya no es necesario.


Lisp usa entornos que son similares a los mapas (clave -> valor) pero con mecanismos adicionales incorporados para encadenar entornos y controlar enlaces.

Ahora, los símbolos son bastante, teclas (excepto símbolos de formas especiales), y apuntan a un valor
Es decir, función , entero , lista , etc.
Como Common Lisp le proporciona una manera de alterar los valores, es decir, con setq , los símbolos en algunos contextos
(Tu ejemplo) también son variables .


Símbolo y variable son 2 cosas diferentes. Como en el símbolo matemático es un valor. Y variable tiene el mismo significado que en matemática.

Pero tu confusión vino del hecho de que el símbolo es la representación meta de una variable.

Eso si lo haces

(setq a 42)

Usted acaba de definir una variable a. Por cierto, la forma en que se almacenan los objetos es la estructura de un símbolo .

En los labios comunes el símbolo es una estructura con diferentes propiedades. Se puede acceder a cada uno con una función como symbol-name symbol-function ...

En el caso de la variable puede acceder a su valor a través de s symbol-value

? (symbol-value ''a) 42

Este no es el caso común de obtener el valor de a.

? a 42

Tenga en cuenta que los símbolos se autoevalúan, lo que significa que si solicita un símbolo, obtiene el símbolo no el symbol-value del symbol-value

? ''a A


Un símbolo es un nombre para una cosa. Una variable es un puntero mutable a una ubicación de almacenamiento mutable.

En el fragmento de código que mostró, tanto los símbolos let como a son. Dentro del alcance del bloque let , el símbolo a denota una variable que actualmente está vinculada al valor 1 .

Pero el nombre de la cosa no es la cosa en sí misma. El símbolo a no es una variable. Es un nombre para una variable. Pero sólo en este contexto específico. En un contexto diferente, el nombre a puede referirse a una cosa completamente diferente.

Ejemplo: el símbolo jaguar puede, según el contexto, denotar


Un símbolo es un objeto de datos Lisp. Una "forma" de Lisp significa un objeto Lisp que se pretende evaluar. Cuando un símbolo en sí se usa como una forma de Lisp, es decir, cuando evalúa un símbolo, el resultado es un valor que está asociado con ese símbolo. La forma en que los valores se asocian con los símbolos es una parte profunda del lenguaje de Lisp. Si el símbolo ha sido declarado "especial" o no cambia mucho la forma en que funciona la evaluación.

Los valores léxicos se indican mediante símbolos, pero usted no puede manipular esos símbolos como objetos. En mi opinión, explicar nada en Lisp en términos de "punteros" o "ubicaciones" no es la mejor manera.