Estou me ensinando um pouco mais sobre elisp e encontrei o seguinte problema:
Se eu quiser redefinir uma variável de lista, ela não será atualizada após a primeira avaliação. Aqui está um exemplo de código:
(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)
Estou interessado em duas coisas. A primeira é aprender mais sobre o que está acontecendo "oculto", então por que funciona pela primeira vez e falha nas chamadas subseqüentes?
A segunda e mais prática questão é como reinicializar a lista corretamente ou existe outra maneira comum de fazer algo assim?
Uma solução alternativa que encontrei é usar uma lista citada e avaliar o conteúdo assim:
(setq example `(,3))
example
nunca foi declarado como uma variável, então setq
deve estar agindo como se declarasse uma nova variável, mas mais tarde, quando você ligar initialize
novamente, uma nova variável está sendo criada, enquanto se modify
lembra da antiga ... em qualquer caso, esse não é um comportamento esperado; no entanto, o uso de setq
algo que não foi introduzido anteriormente como uma variável também pode ser indefinido.
'(3)
é tratado como um valor literal, uma vez que você (setcar '(3) 2)
, sempre que você fizer (defvar foo '(3))
ou (let ((foo '(3)))
e assim por diante você provavelmente irá obter um valor de foo
igual '(2)
. Eu digo "provável" porque esse comportamento não é garantido, é um tipo de otimização que o intérprete faz sempre que parece, algo conhecido como eliminação de subexpressão de constantes (um caso específico de). Então, o que abo-abo escreveu não é exatamente o motivo. É mais como modificar uma string literal em C (que geralmente gera um aviso).
'(some list)
para sereq
a'(some list)
- sempre .Não é geralmente nenhuma garantia em Lisp que o código que visivelmente cita uma lista de retornos nova estrutura de lista de cada vez. Em algumas implementações do Lisp, pode ser, ou pode ser por algumas vezes. Em outros, isso nunca acontece. De qualquer forma, seu código não deve depender de nenhum comportamento da implementação. Se você deseja uma nova estrutura de lista, uselist
oucons
ou equivalente.