2013-07-02 43 views
18

Tôi đang đọc Let Over Lambda, đề cập đến một số tác giả macro phân lớp khá sâu. Thật hấp dẫn và tôi chủ yếu là quản lý để theo kịp nó.Common Lisp Double-Backquote, Unquote, Trích dẫn, Unquote trình tự?

Trong Chương 4 Hoyte thực hiện macro đọc trận đấu CL-PPCRE và thay thế chức năng, chẳng hạn mà bạn có thể làm những việc như:

(#~m/(foo|bar)\d+/ "Some foo99") ; matches! 
(#~s/foo(\d+)/bar\1/, "Some foo99") ; "Some bar99 

Để đạt được điều này, chúng ta định nghĩa một macro mà sử dụng đôi backquote, vì nó thực sự được mở rộng bởi một macro bao bọc, cần giá trị được trích dẫn (nó trả về một dạng lambda). Trong danh sách được trích dẫn gần đây, có một số sử dụng chuỗi sau ,',varname, mà tôi không thể có được đầu của tôi xung quanh. ,' ban đầu làm gì ở đây?

(defmacro! pcre/match-lambda-form (o!args) 
    "Expands to a lambda that applies CL-PPCRE:SCAN" 
    ``(lambda (,',g!str) 
     (cl-ppcre:scan ,(car ,g!args) 
        ,',g!str))) 

Trên thực tế, nó có thể là tốt hơn mà tôi chưng cất mà xuống đến một cái gì đó mà chỉ sử dụng defmacro, cho rõ ràng nếu bạn chưa đọc cuốn sách. str là một biểu tượng và args là danh sách:

(defmacro pcre/match-lambda-form (args) 
    "Expands to a lambda that applies CL-PPCRE:SCAN" 
    ``(lambda (,',str) 
     (cl-ppcre:scan ,(car ,args) 
        ,',str))) 

Are có dấu ngoặc kép về cơ bản đúp trích dẫn những phần bên trong, do đó kết quả có thể không thể viện chứng hai lần? Đặt hiệu quả 'str vào biểu mẫu được mở rộng thay vì chỉ str?

EDIT | Nhờ Terje D. và một số chơi xung quanh trong REPL, đây là khá nhiều tình huống:

(defvar a 42) 

(equal ``(,,a) '(list 42)) ; T 
(equal ``(,a) '(list a)) ; T 
(equal ``(,',a) ''(42))  ; T 
(equal ``(a) ''(a))  ; T (obviously) 

Vì vậy:

  • Gấp đôi-không thể viện chứng, hình thức là hoàn toàn mở rộng.
  • Biểu mẫu không được bỏ phiếu, không được mở rộng.
  • Không được đánh dấu bằng dấu phẩy, biểu mẫu được mở rộng hoàn toàn và kết quả được trích dẫn.
+0

tài liệu tham khảo defmacro cuối cùng của bạn 'str'. Nó là gì? Nó được định nghĩa ở đâu? Bạn có thể chỉ ra cách 'pcre/match-lambda-form' được gọi không? –

+0

Argh, điều này sẽ mất một số giải thích vì có nhiều lớp macro đang diễn ra trong thực tế. Cuốn sách này đang đẩy ranh giới với việc tạo ra macro (cho vui, và cho giáo dục).'str' là một biểu tượng đã được định nghĩa bởi một' LET' kèm theo và đại diện cho một tên biến an toàn để sử dụng. – d11wtq

+0

'pcre/match-lambda-form' được gọi như sau:' (pcre/match-lambda-form '("foo")) ', trong đó' "foo" 'đã được đọc bởi một chuỗi xử lý luồng đọc của biểu mẫu '# ~ m/foo /'. – d11wtq

Trả lời

11

Trong khi đánh giá biểu mẫu được kiểm tra lại gấp đôi, phần sau được xử lý trước và kết quả là biểu mẫu được kiểm tra lại đơn lẻ. Trong quá trình đánh giá biểu mẫu backquoted bên trong, chỉ có các yếu tố được bắt đầu bởi hai dấu phẩy được đánh giá. Tuy nhiên, kết quả của việc đánh giá các phần tử không được bỏ phiếu gấp đôi này vẫn còn (đơn lẻ) không được trích dẫn, và do đó được đánh giá lại khi biểu mẫu được trả về đơn lẻ kết quả được đánh giá. Để đạt được đánh giá chỉ ở dạng backquoted bên trong, một dấu ngoặc kép thông thường phải được chèn vào, kết quả là ,',.

Xem cách

(let ((tmp (gensym))) 
    ``(lambda (,tmp ,,tmp ,',tmp)())) 

đánh giá để

`(LAMBDA (,TMP ,#:G42 #:G42) nil) 
+1

Wow, đó là một chút phức tạp. Tôi chỉ chơi xung quanh với một số backquoting đôi cơ bản và những biến thể của unquoting bây giờ, để xem những gì sẽ xảy ra trong mỗi trường hợp. Tôi nhận được nó ngay bây giờ, cảm ơn :) – d11wtq

+2

@ d11wtq Bạn cũng có thể muốn có một cái nhìn tại phụ lục C (backquote) của 'Common Lisp the Language' có sẵn tại http://www.cs.cmu.edu/Groups/AI/ html/cltl/clm/node1.html, chứa một triển khai mẫu và các ví dụ về cú pháp backquote. –

1

Các, ', X lừa được sử dụng để bảo vệ X từ đánh giá khác.

Xem cách:

 (setq a 'fn) 
    (let ((x 'a)) ``(,,x ,',x)) ==> `(,a a) ==> (fn a) 

    ;; ``,',X ==> `,(quote "the value of X") ==> "the value of X" 

    ;; ``,,X ==> `,"the value of X" ==> "the value of the value of X" 
Các vấn đề liên quan