2012-01-13 17 views
29

Por amor al todopoderoso, aún no entiendo el propósito del símbolo 'iamasymbol. Entiendo números, booleanos, cadenas ... variables. Pero los símbolos son demasiado para mi pequeña mente de pensamiento imperativo. ¿Para qué los uso exactamente? ¿Cómo se supone que deben usarse en un programa? Mi comprensión de este concepto es simplemente un fracaso.¿Qué es exactamente un símbolo en lisp/scheme?

+3

Una de estas cosas no es como las otras . :) Mencionas "números", "booleanos", "cadenas", que son todos tipos de datos. Los símbolos también son parte de esa categoría. Las variables no son – dyoo

+1

Vale la pena señalar que Ruby también tiene símbolos. : el padre es un símbolo. Puedes pensar en ello como enum o cadena interna. Mantiene su nombre (útil para entender), pero no es un tipo de Cadena (a menos que la convierta). – ccoakley

+0

https://en.wikipedia.org/wiki/Symbol_(programming) –

Respuesta

26

En Scheme and Racket, un símbolo es como una cadena inmutable que pasa a ser internada para que los símbolos se puedan comparar con eq? (comparación rápida, esencialmente puntero). Los símbolos y las cadenas son tipos de datos separados.

Un uso para símbolos es enumeraciones livianas. Por ejemplo, uno podría decir que una dirección es 'north, 'south, 'east o 'west. Por supuesto, podría usar cadenas para el mismo propósito, pero sería un poco menos eficiente. Usar números sería una mala idea; representar la información de la manera más obvia y transparente posible.

Por otro ejemplo, SXML es una representación de XML utilizando listas, símbolos y cadenas. En particular, las cadenas representan datos de caracteres y los símbolos representan nombres de elementos. Por lo tanto, el XML <em>hello world</em> estaría representado por el valor (list 'em "hello world"), que puede escribirse de manera más compacta '(em "hello world").

Otro uso para los símbolos es como claves. Por ejemplo, podría implementar una tabla de métodos como símbolos de mapeo de un diccionario para funciones de implementación. Para llamar a un método, busca el símbolo que corresponde al nombre del método. Lisp/Scheme/Racket hace que realmente sea fácil, porque el lenguaje ya tiene una correspondencia incorporada entre identificadores (parte de la sintaxis del lenguaje) y símbolos (valores en el idioma). Esa correspondencia facilita el soporte de macros, que implementan extensiones sintácticas definidas por el usuario para el idioma. Por ejemplo, se podría implementar un sistema de la clase como una biblioteca de macro, utilizando la correspondencia implícita entre "nombres de método" (una noción sintáctica definida por el sistema de clases) y símbolos:

(send obj meth arg1 arg2) 
=> 
(apply (lookup-method obj 'meth) obj (list arg1 arg2)) 

(En otro Lisps, lo que 's dijo que es principalmente truish, pero hay cosas adicionales que debe saber, como paquetes y funciones vs ranuras variables, IIRC.)

+1

Nota: desde hace unos meses, muchos otros valores de raqueta están internados, como p. cadenas e inexacts y expresiones regulares que aparecen como literales. –

+1

Si vienes de C o C# (simplemente adivinando por tu nombre de usuario, nodo .NET): usa un símbolo cuando usarías un 'enum' en esos idiomas (y las enumeraciones no son etiquetas para números específicos). 'enum {north, south, east, west}' podría ser ''north''' south' ''east''' west'. No necesita "declarar" aquellos que tiene que hacer en C con 'enum'. Solo adelante y úsalas. Sin embargo, un símbolo no puede hacer 'enum {north = 123}'. Para eso, necesitarías hacerlo más como un C '# define':' (define north 123) '. –

5

Un símbolo es solo un nombre especial para un valor. El valor puede ser cualquier cosa, pero el símbolo se usa para referirse al mismo valor cada vez, y este tipo de cosas se usa para hacer comparaciones rápidas. Como dices que eres un pensamiento imperativo, son como constantes numéricas en C, y así es como generalmente se implementan (números almacenados internamente).

+2

En particular, dos símbolos se pueden verificar para la igualdad en tiempo constante mediante el uso de (eq? Sym1 sym2). Los símbolos no son un concepto de "Esquema" o "Lisp": son generales. Piense en el término "tabla de símbolos". (Http://en.wikipedia.org/wiki/Symbol_table) Los símbolos en un lenguaje como Scheme o Racket simplemente exponen este concepto de un valor que es como una cadena, pero con esta propiedad adicional de una rápida comprobación de igualdad. – dyoo

7

Los símbolos en lisp son identificadores legibles por humanos. Ellos son todos solteros. Entonces, si declara 'foo en alguna parte de su código y luego usa' foo nuevamente ', apuntará al mismo lugar en la memoria.

Uso de la muestra: diferentes símbolos pueden representar diferentes piezas en un tablero de ajedrez.

23

Un símbolo es un objeto con una representación de cadena simple que (por defecto) está garantizado internado; es decir, cualquier dos símbolos que se escriben de la misma forma son el mismo objeto en la memoria (igualdad de referencia).

¿Por qué Lisps tiene símbolos? Bueno, en gran medida es un artefacto del hecho de que Lisps incorpora su propia sintaxis como un tipo de datos del lenguaje.Los compiladores e intérpretes usan símbolos para representar identificadores en un programa; dado que Lisp le permite representar la sintaxis de un programa como datos, proporciona símbolos porque son parte de la representación.

¿De qué sirven aparte de eso? Bueno, algunas cosas:

  • Lisp se utiliza comúnmente para implementar lenguajes incrustados específicos del dominio. Muchas de las técnicas utilizadas para eso provienen del mundo del compilador, por lo que los símbolos son una herramienta útil aquí.
  • Las macros en Common Lisp generalmente implican tratar con símbolos con más detalle de lo que proporciona esta respuesta. (Aunque, en particular, la generación de identificadores únicos para expansiones macro requiere ser capaz de generar un símbolo que está garantizado para nunca ser igual a cualquier otro.)
  • tipos de enumeración fijos son mejor implementados como símbolos que las cuerdas, porque los símbolos pueden ser comparados por igualdad de referencia.
  • Existen muchas estructuras de datos que puede construir donde puede obtener un beneficio de rendimiento al usar símbolos e igualdad de referencia.
+1

La mejor respuesta. – day

+0

¿Te importa proporcionar un ejemplo simple? –

+0

¿Qué pasa con '(eq (make-symbol" test ") (make-symbol" test "))'? Creo que su afirmación sobre los símbolos que se garantiza que serán internados se aplica solo si esos símbolos son * leídos *. Punto realmente interesante sobre los compiladores, sin embargo; Nunca lo pensé así :-) –

1

De Estructura e Interpretación de Programas Informáticos Segunda Edición de Harold Abelson y Gerald Jay Sussman 1996:

Con el fin de manipular símbolos que necesitamos un nuevo elemento en nuestro idioma: la capacidad de cita un objeto de datos. Supongamos que queremos construir la lista (a b). No podemos lograr esto con (enumerar a b), porque esta expresión construye una lista de los valores de a y b en lugar de los símbolos mismos. Este problema es bien conocido en el contexto de las lenguas naturales, donde las palabras y oraciones pueden ser considerados ya sea como entidades semánticas o como personaje cuerdas (entidades sintácticas). La práctica común en los lenguajes naturales es usar comillas para indicar que una palabra o una oración se debe tratar literalmente como una cadena de caracteres. Por ejemplo, la primera letra de "John" es claramente "J." Si le decimos a alguien "diga su nombre en voz alta", esperamos escuchar el nombre de esa persona. Sin embargo, si le decimos a alguien “decir‘su nombre’en voz alta,” que esperamos oír las palabras “su nombre”. Tenga en cuenta que nos vemos obligados a anidar comillas para describir lo que alguien podría decir. Podemos seguir esta misma práctica para identificar listas y símbolos que son para ser tratados como objetos de datos en lugar de como expresiones para evaluar. Sin embargo, nuestro formato de cotización difiere del de los idiomas naturales en que colocamos una comilla (tradicionalmente, el símbolo de comilla simple ') solo al comienzo del objeto que se va a cotizar. Podemos salirse con la suya en la sintaxis Scheme porque confiamos en espacios en blanco y paréntesis para delimitar objetos . Por lo tanto, el significado del carácter de comilla simple es citar el siguiente objeto . Ahora podemos distinguir entre símbolos y sus valores:

(define a 1) 

(define b 2) 

(list a b) 
(1 2) 

(list ’a ’b) 
(a b) 

(list ’a b) 
(a 2) 

listas que contienen símbolos se parecen a las expresiones de nuestro lenguaje:

(* (+ 23 45) (+ x 9)) 
(define (fact n) (if (= n 1) 1 (* n (fact (- n 1))))) 

Ejemplo: Diferenciación simbólica