2010-08-28 17 views

risposta

18

punti risposta di Jörg nella giusta direzione. Lascia che ti aggiunga un po '.

Parlerò di Lisps simili a Common Lisp.

simboli come una struttura di dati

Un simbolo è una vera e propria struttura di dati in Lisp. Puoi creare simboli, puoi usare simboli, puoi memorizzare simboli, puoi passare simboli e simboli possono essere parte di strutture di dati più grandi, per esempio liste di simboli. Un simbolo ha un nome, può avere un valore e può avere un valore di funzione.

Quindi puoi prendere un simbolo e impostarne il valore.

(setf (symbol-value 'foo) 42) 

Di solito si potrebbe scrivere (setq foo 42), o (set 'foo 42) o (setf foo 42).

simboli in codice che denota variabili

Ma!

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

o

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

In entrambe le forme sopra nel codice sorgente non ci sono simboli e a è scritto come un simbolo e utilizzando la funzione READ di leggere quella fonte restituisce un simbolo a in qualche lista. Ma l'operazione setq NON imposta il valore del simbolo di a su 42. Qui lo LET e lo DEFUN introducono un VARIABLEa che scriviamo con un simbolo. Pertanto, l'operazione SETQ imposta il valore della variabile su 42.

lessicale vincolante

Quindi, se guardiamo:

(defvar foo nil) 

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

Introduciamo una variabile globale FOO.

Nella barra il primo SETQ imposta il valore del simbolo della variabile globale FOO. Il secondo SETQ imposta la variabile locale BAZ su 3. In entrambi i casi usiamo lo stesso SETQ e scriviamo la variabile come un simbolo, ma nel primo caso lo FOO dona una variabile globale e quei valori di memoria nel valore del simbolo. Nel secondo caso, BAZ denota una variabile locale e come il valore viene memorizzato, non lo sappiamo. Tutto quello che possiamo fare è accedere alla variabile per ottenere il suo valore. In Common Lisp non è possibile prendere un simbolo BAZ e ottenere il valore della variabile locale. Non abbiamo accesso ai collegamenti alle variabili locali e ai loro valori usando simboli. Questa è una parte del modo in cui il binding lessicale delle variabili locali funziona in Common Lisp.

Ciò porta ad esempio all'osservazione, che nel codice compilato senza informazioni di debug registrate, il simbolo BAZ è scomparso. Può essere un registro nel processore o implementato in altro modo. Il simbolo FOO è ancora lì, perché lo usiamo come variabile globale.

vari usi di simboli

Un simbolo è un tipo di dati, una struttura di dati in Lisp.

Una variabile è una cosa concettuale. Le variabili globali sono basate su simboli. Variabili lessicali locali non.

Nel codice sorgente scriviamo tutti i tipi di nomi per funzioni, classi e variabili mediante simboli.

V'è una certa sovrapposizione concettuale:

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

nel codice sorgente di cui sopra, defun, foo, bar, setq e baz sono tutti i simboli.

DEFUN è un simbolo che fornisce una macro. FOO è un simbolo che fornisce una funzione. SETQ è un simbolo che fornisce un operatore speciale. BAZ è un simbolo utilizzato come dati. Quindi la citazione prima di BAZ. BAR è una variabile. Nel codice compilato il suo simbolo non è più necessario.

4

Lisp utilizza ambienti che sono simili alle mappe (chiave -> valore) ma con meccanismi aggiuntivi incorporati per concatenare gli ambienti e controllare i collegamenti.

Ora, simboli sono più o meno, chiavi (ad eccezione di simboli forma particolare), e punto ad un valore,
cioè funzione, intero, lista, ecc
Dal Comune Lisp ti dà un modo per modificare i valori, ovvero con setq, i simboli in alcuni contesti
(il tuo esempio) sono anche variabili.

9

A simbolo è un nome per una cosa. Una variabile è un puntatore mutabile a una posizione di memoria mutabile.

Nello snippet di codice che hai mostrato, sia let che a sono simboli. Nell'ambito del blocco let, il simbolo a indica una variabile attualmente associata al valore 1.

Ma il nome della cosa non è la cosa stessa. Il simbolo a non è una variabile. È un nome per una variabile. Ma solo in questo specifico contesto. In un contesto diverso, il nome a può riferirsi a una cosa completamente diversa.

Esempio: il simbolo jaguar può, a seconda del contesto, indicare

+1

Bene, questa risposta punta nella giusta direzione. –

+0

+1 per menzionare simboli che significano cose diverse in diversi contesti. Questo aiuta davvero quando cerchi di capire la differenza tra ** x ** e ** # 'x ** e **' x **. – Baggers

11

Citando dal Common Lisp HyperSpec:

symboln. an object di typesymbol.

variablen. a binding nella "variabile" namespace.

bindingn. un'associazione tra uno name e quello che il nome denota. (...)

Ora di spiegazione.

Ciò che Lisp chiama i simboli è abbastanza vicino a quello che molte lingue chiamano variabili. In prima approssimazione, i simboli hanno dei valori; quando si valuta l'espressione x, il valore dell'espressione è il valore del simbolo x; quando scrivi (setq x 3), assegni un nuovo valore a x. Nella terminologia Lisp, (setq x 3) associa il valore 3 al simbolo x.

Una caratteristica di Lisp che la maggior parte delle lingue non hanno è che i simboli sono oggetti ordinari (i simboli sono oggetti di prima classe, nella terminologia del linguaggio di programmazione). Quando si scrive (setq x y), il valore di x diventa qualunque sia il valore di y al momento dell'assegnazione. Ma è possibile scrivere (setq x 'y), nel qual caso il valore di x è il simbolo .

Concettualmente, c'è uno environment che è una tabella di associazione da simboli a valori. Valutare un simbolo significa cercarlo nell'ambiente attuale. (Anche gli ambienti sono oggetti di prima classe, ma questo va oltre lo scopo di questa risposta.) Un legame fa riferimento a una particolare voce in un ambiente. Tuttavia, c'è un'ulteriore complicazione.

La maggior parte dei dialoghi Lisp ha più spazi dei nomi, almeno uno spazio dei nomi di variabili e uno spazio dei nomi di funzioni. Un ambiente può infatti contenere più voci per un simbolo, una voce per ogni spazio dei nomi. Una variabile, in senso stretto, è una voce in un ambiente nello spazio dei nomi delle variabili. Nella terminologia Lisp di tutti i giorni, un simbolo è spesso definito come una variabile quando il suo legame come una variabile è ciò che ti interessa.

Per esempio, in (setq a 1) o (let ((a 1)) ...), a è un simbolo. Ma poiché i costrutti agiscono sul binding variabile per il simbolo a, è comune fare riferimento a a come variabile in questo contesto.

D'altra parte, in (defun a (...) ...) o (flet ((a (x) ...)) ...), a è un simbolo anche, ma questi costrutti agiscono sul legame sua funzione, quindi a non sarebbe considerato una variabile.

Nella maggior parte dei casi, quando un simbolo appare non quotato in un'espressione, viene valutato cercando il suo legame variabile. L'eccezione principale è che in una chiamata di funzione (foo arg1 arg2 ...), viene utilizzata la funzione di associazione per foo. Il valore di un simbolo quotato 'x o (quote x) è esso stesso, come qualsiasi espressione quotata. Naturalmente, ci sono un sacco di forme particolari in cui non è necessario citare un simbolo, tra cui setq, let, flet, defun, ecc

1

simbolo e variabile sono 2 cose diverse. Come nel simbolo matematico è un valore. E le variabili hanno lo stesso significato che in matematica.

Ma la tua confusione deriva dal fatto che il simbolo è la meta rappresentazione di una variabile.

Cioè se si fa

(setq a 42) 

Basta definire una variabile a. Tra l'altro il modo in cui la memoria comune è gettare la struttura di un simbolo.

In common lips il simbolo è una struttura con proprietà diverse. Ognuno può essere l'accesso con funzione come symbol-name, symbol-function ...

Nel caso di variabili si può accedere al suo valore di via s symbol-value

? (symbol-value 'a) 
42 

Questo non è il caso comune di ottenere il valore di un .

? a 
42 

Nota che i simboli sono auto valutazione che significa che se si chiede un simbolo si ottiene il simbolo non i symbol-value

? 'a 
A 
2

Un simbolo è un oggetto dati Lisp. Una "forma" Lisp significa un oggetto Lisp che deve essere valutato. Quando un simbolo stesso viene usato come un modulo Lisp, cioè quando si valuta un simbolo, il risultato è un valore associato a quel simbolo. Il modo in cui i valori sono associati ai simboli è una parte profonda della lingua Lisp. Se il simbolo è stato dichiarato "speciale" o non cambia notevolmente il modo in cui funziona la valutazione.

I valori lessicali sono contrassegnati da simboli, ma non è possibile manipolarli come oggetti.A mio parere, spiegare nulla in Lisp in termini di "puntatori" o "luoghi" non è il modo migliore.

1

Aggiunta di una nota a margine per le risposte di cui sopra:

I nuovi arrivati ​​a Lisp spesso non sono sicuro di quello che i simboli sono per, oltre ad essere i nomi delle variabili. Penso che la risposta migliore è che sono come costanti di enumerazione, tranne che non si deve dichiarare loro prima di utilizzarli. Naturalmente, come altri hanno spiegato, sono anche oggetti. (Questo non dovrebbe sembrare strano per gli utenti di Java, in cui le costanti di enumerazione sono oggetti troppo.)

Problemi correlati