Setf mở rộng kỳ lạ


7

Cố gắng hiểu những gì setfcó thể làm, tôi gọi

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

Điều này rõ ràng là sai.

Tuy nhiên tôi không thể tạo ra một ví dụ thực tế khi (setf (aref ..thất bại. Ví dụ

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

Ai đó có thể giải thích những gì đang xảy ra ở đây?


2
ĐỒNG Ý. Giờ thì tôi đã hiểu. Hai vbiểu tượng không giống nhau và (let* ((form (macroexpand '(setf (aref vec i) val))) (symb1 (caar (cadr form))) (symb2 (caar (cdadr form)))) (equal symb1 symb2))trả về nil.
phs

1
Kỳ lạ thay, các mã cho setftrong tập tin nguồn gv.eldường như để tạo ra các vbiểu tượng với một sử dụng vani của (gensym "v")và điều này nên nối thêm một giá trị truy cập sau "v" tiền tố, tạo ra những biểu tượng uninterned v0, v1, v2vv
PHS

2
Bạn có thể muốn chơi với print-gensymđể thấy rõ hơn những gì đang diễn ra.
Stefan

@stefan: Tôi có emacs-26.1 và nó không có print-gensymAFAICT :-( Có ai có lời giải thích tại sao (gensym "v")tệp trong nguồn gv.elkhông xuất hiện không gensym-counter?!
phs

1
Tôi khá chắc chắn rằng bạn có print-gensym, bạn có thể chỉ nhìn nhầm chỗ (thử C-h othay vì C-h f). Các let*trong mã mở rộng của bạn có khả năng tạo ra bởi macroexp-let2đó sử dụng make-symbolchứ không phải là gensym.
Stefan

Câu trả lời:


8

Từ nhận xét của bạn, bạn đã tự mình tìm ra điều này, nhưng ...

Trong phần mở rộng vĩ mô, bạn sẽ thấy biểu diễn được in của hai biểu tượng độc lập có cùng tên. Nhiều khả năng cả hai biểu tượng đó là không liên quan.

Một đại diện được in như thế này, nếu được gửi lại cho trình đọc lisp, sẽ không tương đương với bản gốc, vì trình đọc lisp sẽ thực hiện các ký hiệu.

Điều này tương tự như:

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

3
Đáng lưu ý rằng cài đặt print-gensymprint-circleđể ttạo ra một bản trình bày có thể đọc lại thành một cái gì đó tương đương.
npostavs
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.