Setf seltsame Erweiterung

7

Ich versuchte zu verstehen, was setfich tun kann, und rief an

(macroexpand '(setf (aref vec i) val))
⇒ (let* ((v vec) (v i)) (aset v v val))

Dies scheint offensichtlich falsch.

Ich konnte jedoch keine tatsächliche Instanz erstellen, bei der ein Fehler (setf (aref ..auftritt. Z.B

 (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]

Kann jemand erklären, was hier los ist?

phs
quelle
2
OK. Ich verstehe jetzt. Die beiden vSymbole sind nicht identisch und (let* ((form (macroexpand '(setf (aref vec i) val))) (symb1 (caar (cadr form))) (symb2 (caar (cdadr form)))) (equal symb1 symb2))kehren zurück nil.
Phs
1
Merkwürdigerweise ist der Code für setfin Quelldatei gv.elscheint die zu schaffen vSymbole mit einer Vanille-Verwendung (gensym "v")und dies sollte einen Zählerwert nach dem „v“ Präfix anfügen, uninterned Symbole zu schaffen v0, v1, v2etc.
phs
2
Vielleicht möchten Sie mit spielen, print-gensymum besser zu sehen, was los ist.
Stefan
@stefan: Ich habe Emacs-26.1 und es hat keine print-gensymAFAICT :-( Hat jemand eine Erklärung, warum die (gensym "v")In-Source-Datei gv.elnicht angehängt wird gensym-counter?!
Phs
1
Ich bin mir ziemlich sicher print-gensym, dass Sie wahrscheinlich nur an der falschen Stelle gesucht haben (versuchen Sie es C-h ostattdessen C-h f). Der let*in Ihrem erweiterten Code wird wahrscheinlich eher von macroexp-let2verwendet make-symbolals verwendet gensym.
Stefan

Antworten:

8

Aus Ihrem Kommentar haben Sie dies selbst herausgefunden, aber ...

In der Makroerweiterung sehen Sie die gedruckte Darstellung zweier unabhängiger Symbole mit demselben Namen. Höchstwahrscheinlich sind beide Symbole nicht interterniert.

Eine gedruckte Darstellung wie diese wäre, wenn sie an den Lisp-Leser zurückgegeben würde, nicht gleichbedeutend mit dem Original, da der Lisp-Leser die Symbole internieren würde.

Dies ist ähnlich wie:

(list (make-symbol "v") (make-symbol "v"))
(v v)
Phils
quelle
3
Bemerkenswert ist diese Einstellung print-gensymund print-circleum teine gedruckte Darstellung zu erzeugen, die auf etwas Äquivalentes zurücklesen kann.
Npostavs