Tentando entender o que setf
posso fazer, liguei para
(macroexpand '(setf (aref vec i) val))
⇒ (let* ((v vec) (v i)) (aset v v val))
Isso parece obviamente errado.
No entanto, não consegui criar uma instância real em que (setf (aref ..
falha. Por exemplo
(setq vec (make-vector 10 nil) i 3 val 'foo)
⇒ foo
(setf (aref vec i) val)
⇒ foo
vec
⇒ [nil nil nil foo nil nil nil nil nil nil]
Alguém pode explicar o que está acontecendo aqui?
elisp-macros
setf
phs
fonte
fonte
v
símbolos não são os mesmos e(let* ((form (macroexpand '(setf (aref vec i) val))) (symb1 (caar (cadr form))) (symb2 (caar (cdadr form)))) (equal symb1 symb2))
retornamnil
.setf
no arquivo de origemgv.el
parece criar osv
símbolos com um uso de baunilha de(gensym "v")
e isto deve acrescentar um valor de contador após o prefixo "v", criando símbolos uninternedv0
,v1
,v2
, etc.print-gensym
para ver melhor o que está acontecendo.print-gensym
AFAICT :-( Alguém tem uma explicação por que o(gensym "v")
no arquivo de origemgv.el
não acrescentargensym-counter
?!print-gensym
, você provavelmente apenas olhou para o lugar errado (tente emC-h o
vez deC-h f
). Olet*
seu código expandida é provavelmente gerado pelomacroexp-let2
que usamake-symbol
, em vez degensym
.Respostas:
Do seu comentário, você descobriu isso por si mesmo, mas ...
Na expansão macro, você vê a representação impressa de dois símbolos independentes com o mesmo nome. Muito provavelmente, esses dois símbolos não são internos.
Uma representação impressa como essa, se devolvida ao leitor de cisco, não seria equivalente ao original, pois o leitor de cisco estagiaria os símbolos.
Isso é semelhante a:
fonte
print-gensym
eprint-circle
parat
produz uma representação impressa que pode ler de volta para algo equivalente.