8

Trong thực tế Common Lisp của Chapter 8, Macros: Xác định riêng của bạn, chúng ta định nghĩa một macro with-gensyms như sau:Sự khác nhau giữa `(& xs còn lại)` và `xs` trong defmacro danh sách đối số chính thức

(defmacro with-gensyms ((&rest names) &body body) 
    `(let ,(loop for n in names collect `(,n (gensym))) 
    ,@body)) 

là gì mục đích của (&rest names)? Nếu chúng ta thay thế nó chỉ với names, hiệu ứng có vẻ giống nhau. Trong cả hai trường hợp, chúng tôi chuyển một danh sách các ký hiệu thành "gensym-ed".

Trả lời

9

Sự khác biệt:

(&rest names) chỉ khớp các danh sách. Khi ai đó đang sử dụng vĩ mô với cái gì khác, lỗi xuất phát từ giãn nở vĩ mô:

debugger gọi trên SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR:

lỗi khi phân tích cú pháp lập luận để DEFMACRO WITH-GENSYMS:

giả sublist A để đáp ứng lambda-list (&REST NAMES)

names khớp với mọi thứ. Khi ai đó đang sử dụng vĩ mô với không phải là một danh sách, sau đó các lỗi xuất phát từ vĩ mô LOOP, mà cần có một danh sách:

debugger gọi trên TYPE-ERROR: Giá trị A không phải là loại LIST.

Vì vậy, bạn nhận được lỗi tốt hơn và sớm hơn.

+0

Vì vậy, nó thành ngữ để sử dụng '((& rest args))' khi chúng ta mong đợi 'args' là một danh sách? –

+0

@TianxiangXiong: bạn có muốn sử dụng cấu trúc cụ thể hơn không? –

+0

Vâng, tôi cho là vậy. –

Các vấn đề liên quan