2012-01-13 15 views
29

Per amore dell'onnipotente devo ancora capire lo scopo del simbolo 'iamasymbol. Capisco numeri, booleani, stringhe ... variabili. Ma i simboli sono troppo per la mia piccola mente imperativa. Per cosa li uso esattamente? Come dovrebbero essere usati in un programma? La mia comprensione di questo concetto è semplicemente fallita.Che cosa è esattamente un simbolo in lisp/schema?

+3

Una di queste cose non è come le altre . :) Si parla di "numeri", "booleani", "stringhe", che sono tutti tipi di dati. Anche i simboli fanno parte di quella categoria. Le variabili non lo sono. – dyoo

+1

Vale la pena notare che Ruby ha anche dei simboli. : genitore è un simbolo. Puoi immaginarlo come un enum o una stringa internata. Mantiene il suo nome (utile per la comprensione), ma non è un tipo String (a meno che non lo si converta). – ccoakley

+0

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

risposta

26

In Schema e Racket, un simbolo è come una stringa immutabile che viene internata in modo che i simboli possano essere confrontati con eq? (confronto veloce, essenzialmente puntatore). I simboli e le stringhe sono tipi di dati separati.

Un utilizzo per i simboli è enumerazioni leggere. Ad esempio, si potrebbe dire che una direzione è 'north, 'south, 'east o 'west. Ovviamente potresti usare stringhe per lo stesso scopo, ma sarebbe leggermente meno efficiente. Usare i numeri sarebbe una cattiva idea; rappresentare le informazioni nel modo più ovvio e trasparente possibile.

Per un altro esempio, SXML è una rappresentazione di XML che utilizza elenchi, simboli e stringhe. In particolare, le stringhe rappresentano i dati dei caratteri ei simboli rappresentano i nomi degli elementi. Quindi l'XML <em>hello world</em> sarebbe rappresentato dal valore (list 'em "hello world"), che può essere scritto in modo più compatto '(em "hello world").

Un altro uso per i simboli è come chiavi. Ad esempio, è possibile implementare una tabella dei metodi come dizionario che associa i simboli alle funzioni di implementazione. Per chiamare un metodo, si cerca il simbolo che corrisponde al nome del metodo. Lisp/Scheme/Racket rende questo veramente facile, perché la lingua ha già una corrispondenza incorporata tra identificatori (parte della sintassi del linguaggio) e simboli (valori nella lingua). Questa corrispondenza facilita il supporto dei macro , che implementano estensioni sintattiche definite dall'utente nella lingua. Ad esempio, si potrebbe realizzare un sistema di classe come libreria macro, utilizzando la corrispondenza implicita tra "nomi metodo" (nozione sintattica definito dal sistema classe) e simboli:

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

(In altre Lisps, ciò che Ho detto che è per lo più vero, ma ci sono altre cose da sapere, come pacchetti e funzioni vs slot variabili, IIRC.)

+1

Nota: alcuni mesi fa, molti altri valori di Racket sono internati, come ad es. stringhe e inexacts e regexps che appaiono come letterali. –

+1

Se provieni da C o C# (solo indovinando dal tuo nome utente, .NET noob): usa un simbolo quando userai un 'enum' in quei linguaggi (e le enumerazioni non sono etichette per numeri specifici). 'enum {nord, sud, est, ovest}' potrebbe essere ''north''' south'' 'east' '' west'. Non è necessario "dichiarare" quelli come in C con 'enum'. Basta andare avanti e usarli. Tuttavia un simbolo non può fare 'enum {north = 123}'. Per farlo dovresti farlo più simile a C '# define':' (define north 123) '. –

5

Un simbolo è solo un nome speciale per un valore. Il valore potrebbe essere qualsiasi cosa, ma il simbolo viene utilizzato ogni volta per riferirsi allo stesso valore, e questo genere di cose viene utilizzato per confronti rapidi. Come dici tu sei un pensiero imperativo, sono come le costanti numeriche in C, e questo è il modo in cui vengono solitamente implementate (numeri memorizzati internamente).

+2

In particolare, due simboli possono essere controllati per l'uguaglianza in tempo costante usando (eq? Sym1 sym2). I simboli non sono un concetto "Scheme" o "Lisp": sono generali. Pensa al termine "tabella dei simboli". (Http://en.wikipedia.org/wiki/Symbol_table) I simboli in una lingua come Schema o Racket stanno semplicemente esponendo questo concetto di un valore simile a una stringa, ma con questa proprietà extra di controllo veloce dell'uguaglianza. – dyoo

7

I simboli in lisp sono identificativi leggibili. Sono tutti singleton. Quindi se dichiari di essere "da qualche parte nel tuo codice e poi usi di nuovo", riporterà allo stesso posto nella memoria.

Esempio di utilizzo: simboli diversi possono rappresentare pezzi diversi su una scacchiera.

23

Un simbolo è un oggetto con una semplice rappresentazione di stringa che (per impostazione predefinita) è garantito per essere internato; Ad esempio, qualsiasi due simboli che sono stati scritti allo stesso modo sono lo stesso oggetto nella memoria (uguaglianza di riferimento).

Perché i Lisps hanno simboli? Bene, è in gran parte un artefatto del fatto che Lisps ha incorporato la propria sintassi come un tipo di dati della lingua.I compilatori e gli interpreti usano i simboli per rappresentare gli identificatori in un programma; poiché Lisp consente di rappresentare la sintassi di un programma come dati, fornisce simboli perché fanno parte della rappresentazione.

Cosa sono utili oltre a quello? Bene, alcune cose:

  • Lisp è comunemente usato per implementare lingue specifiche del dominio incorporato. Molte delle tecniche utilizzate provengono dal mondo del compilatore, quindi i simboli sono uno strumento utile qui.
  • I macro in Common Lisp di solito implicano la gestione dei simboli in modo più dettagliato di quanto non fornisca questa risposta. (Anche se in particolare, la generazione di identificatori univoci per le espansioni macro richiede di essere in grado di generare un simbolo che non è mai uguale a nessun altro.)
  • I tipi di enumerazione fissi vengono implementati meglio come simboli rispetto alle stringhe, perché i simboli possono essere confrontati da uguaglianza di riferimento.
  • Esistono molte strutture di dati che è possibile costruire in cui è possibile ottenere un vantaggio prestazionale dall'uso di simboli e uguaglianza di riferimento.
+1

La migliore risposta. – day

+0

Ti dispiace fornire un semplice esempio? –

+0

E riguardo '(eq (make-symbol" test ") (make-symbol" test "))'? Penso che la tua affermazione sul fatto che i simboli siano internati si applica solo se quei simboli sono * letti *. Punto davvero interessante sui compilatori, però; Non ci avevo mai pensato :-) –

1

Da Struttura e Interpretazione dei programmi per computer Seconda edizione da Harold Abelson e Gerald Jay Sussman 1996

Al fine di manipolare i simboli di cui abbiamo bisogno di un nuovo elemento nella nostra lingua: la capacità di citare un oggetto dati. Supponiamo di voler costruire l'elenco (a b). Non possiamo farlo con (lista a b), perché questa espressione costruisce un elenco dei valori di a e b piuttosto che i simboli stessi. Questo problema è ben noto nel contesto delle lingue naturali, dove le parole e le frasi possono essere considerate come entità semantiche o come stringhe di carattere (entità sintattiche). La pratica comune nei linguaggi naturali consiste nell'utilizzare le virgolette per indicare che una parola o una frase deve essere trattata letteralmente come una stringa di caratteri . Ad esempio, la prima lettera di "John" è chiaramente "J." Se diciamo a qualcuno "dì il tuo nome ad alta voce", ci aspettiamo di sentire il nome di quella persona . Tuttavia, se diciamo a qualcuno "dì" il tuo nome "ad alta voce," ci aspettiamo di sentire le parole "il tuo nome". Si noti che siamo costretti a nidificare le virgolette per descrivere ciò che qualcun altro potrebbe dire. Possiamo seguire questa stessa pratica per identificare elenchi e simboli che sono da trattare come oggetti dati anziché come espressioni da valutare. Tuttavia, il nostro formato per le citazioni differisce da quello delle lingue naturali in e viene inserito un virgolette (tradizionalmente, il simbolo di virgoletta singola ') solo all'inizio dell'oggetto da quotare. Possiamo farla franca con la sintassi Scheme perché ci basiamo su spazi vuoti e parentesi per delimitare gli oggetti . Quindi, il significato del carattere di citazione singola è di citare l'oggetto successivo . Ora siamo in grado di distinguere tra i simboli ed i loro valori:

(define a 1) 

(define b 2) 

(list a b) 
(1 2) 

(list ’a ’b) 
(a b) 

(list ’a b) 
(a 2) 

liste contenenti simboli può guardare proprio come le espressioni della nostra lingua:

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

Esempio: Differenziazione simbolica

Problemi correlati