Mi sto insegnando un po 'più elisp e ho riscontrato il seguente problema:
Se voglio ripristinare una variabile di elenco, questa non verrà aggiornata dopo la prima valutazione. Ecco un esempio di codice:
(defun initilize ()
(setq example '(3)))
(defun modify ()
(initilize)
(message "%S" example)
(setcar example 2))
; M-x eval-buffer RET
(modify) ; message --> (3)
(modify) ; message --> (2)
(modify) ; message --> (2)
Sono interessato a due cose. Il primo è quello di saperne di più su ciò che sta accadendo "sotto il cofano", quindi perché funziona la prima volta e fallisce nelle chiamate successive?
La seconda e più pratica domanda è come reinizializzare correttamente l'elenco o c'è un altro modo comune di fare qualcosa del genere?
Una soluzione alternativa che ho riscontrato è utilizzare un elenco citato e valutare il contenuto in questo modo:
(setq example `(,3))
example
non è mai stato dichiarato come variabile, quindi setq
deve comportarsi come se dichiarasse una nuova variabile, ma in seguito quando si chiama di initialize
nuovo viene creata una nuova variabile, mentre modify
ricorda quella vecchia ... in ogni caso non si tratta di un comportamento previsto, tuttavia l'uso di setq
con qualcosa che non è stato introdotto in precedenza come variabile potrebbe anche essere indefinito.
'(3)
è trattato come un valore letterale, quindi una volta che (setcar '(3) 2)
, ogni volta che si fa (defvar foo '(3))
o (let ((foo '(3)))
e così via è probabile ottenere un valore di foo
pari a '(2)
. Dico "probabile" perché questo comportamento non è garantito, è una sorta di ottimizzazione che l'interprete fa ogni volta che lo desidera, qualcosa noto come eliminazione della sottoespressione delle costanti (un caso particolare di). Quindi, ciò che ha scritto abo-abo non è esattamente il motivo. È più come modificare una stringa letterale in C (che in genere genera un avviso).
'(some list)
di essereeq
a'(some list)
- mai .C'è generalmente alcuna garanzia in Lisp quel codice che cita visibilmente un elenco rendimenti nuova struttura della lista ogni volta. In alcune implementazioni Lisp potrebbe o potrebbe accadere qualche volta. In altri, non lo fa mai. Il codice non dovrebbe comunque dipendere da tali comportamenti dall'implementazione. Se si desidera una nuova struttura di elenco, utilizzarelist
ocons
o equivalente.