Setf expansão estranha


7

Tentando entender o que setfposso 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?


2
ESTÁ BEM. Eu entendo agora. Os dois vsí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))retornam nil.
phs

11
Estranhamente, o código para setfno arquivo de origem gv.elparece criar os vsí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 uninterned v0, v1, v2, etc.
PHS

2
Você pode brincar print-gensympara ver melhor o que está acontecendo.
Stefan

@stefan: Eu tenho emacs-26.1 e não tem print-gensymAFAICT :-( Alguém tem uma explicação por que o (gensym "v")no arquivo de origem gv.elnão acrescentar gensym-counter?!
PHS

11
Eu tenho certeza que você tem print-gensym, você provavelmente apenas olhou para o lugar errado (tente em C-h ovez de C-h f). O let*seu código expandida é provavelmente gerado pelo macroexp-let2que usa make-symbol, em vez de gensym.
Stefan

Respostas:


8

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:

(list (make-symbol "v") (make-symbol "v"))
(v v)

3
Vale notar que a configuração print-gensyme print-circlepara tproduz uma representação impressa que pode ler de volta para algo equivalente.
N
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.