Entrambe defvar
e defparameter
dichiareranno una variabile come "variabile ad ambito dinamico". Inoltre, defparameter
imposterà sempre il valore della variabile sul valore inserito come secondo argomento. Questo è diverso da defvar
, imposterà solo il valore della variabile se precedentemente non è stato impostato.
La definizione di una variabile con setf
o setq
nello scope lessicale globale non è definita. Alcune implementazioni creeranno per te una variabile con ambito dinamico, altre no. Potresti visualizzare messaggi diagnostici quando lo fai per la prima volta.
per capire la differenza tra le variabili lessicalmente con ambito e dinamicamente con ambito, provare il seguente frammento di codice:
* (defvar *a* 1)
*A*
* (let ((*a* 5)) (defun demo-a() *a*))
DEMO-A
* (let ((b 5)) (defun demo-b() b))
DEMO-B
* (let ((*a* 100)) (demo-a))
100
* (let ((b 100)) (demo-b))
5
Qui creiamo una variabile in modo dinamico con ambito e una funzione che restituisce il valore (definito all'interno di un vincolante dove ha un valore diverso durante la creazione della funzione, questo non è necessario e fatto solo per sembrare simile alla chiusura lessicale su b). Quindi definiamo una nuova variabile e definiamo una funzione restituisce il suo valore.
Successivamente, chiamiamo entrambe le funzioni, all'interno di chiusure che vincolano un valore a una variabile con lo stesso nome. Nel caso di ambito dinamico, è la stessa variabile. Nel caso lessicale di chiusura (b), hanno semplicemente lo stesso nome, ma non sono la stessa variabile, poiché sono definiti in due diverse chiusure lessicali.
Per quanto riguarda la differenza tra setf
e setq
, cerca di utilizzare sempre setf
(non riesco a pensare a nessun esempio in cui (setq blah blahblah)
avrebbe funzionato e (setf blah blahblah)
non farei la stessa cosa).
Se una variabile che definisco con defvar, posso modificare il valore con defparameter? È il modo corretto per farlo? O solo la variabile definita in defparameter può essere modificata da defparameter? Grazie ~ – sam
Il modo corretto è utilizzare DEFVAR e DEFPARAMETER per l'inizializzazione dei valori nei file, utilizzare l'uno o l'altro per dichiarare le variabili dinamiche nel listener e utilizzare sempre SETF per modificare il valore nel codice non di primo livello. La differenza tra DEFVAR e DEFPARAMETER diventa quindi "Voglio reimpostare il valore ogni volta che carico questo file" (usa defparamete), "oppure no?" (usa defvar). – Vatine