Lisp thông thường, 58 ký tự
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
... hoặc 24 ký tự nếu bạn không cho rằng giả định *print-circle*
được đặt toàn cầu thành T
:
#1=(print '(write '#1#))
Biểu diễn in của mã được đọc dưới dạng cấu trúc tuần hoàn, trong đó #1#
trỏ trở lại ô khuyết theo sau #1=
. Chúng tôi trích dẫn các chương trình để chúng không được thực thi. Vì *print-circle*
là T, REPL rất quan tâm để phát ra các biến đọc như vậy trong khi in; đây là những gì đoạn mã trên in ra và trả về:
#1=(write '(print '#1#))
Khi chúng tôi đánh giá mã trên, nó sẽ in:
#1=(print '(write '#1#))
Nếu bạn muốn gắn bó với giá trị mặc định cho *print-circle*
, đó là NIL trong triển khai tuân thủ, thì bạn sẽ phải tạm thời biến lại biến:
#1=(let((*print-circle* t))(print'(write '#1# :circle t)))
Bên trong cơ thể của LET, chúng tôi in những thứ có chữ *print-circle*
T. Vì vậy, chúng tôi có được:
#1=(write
'(let ((*print-circle* t))
(print '#1#))
:circle t)
Như bạn có thể thấy, chương trình mới không khởi động lại *print-circle*
, nhưng vì chúng ta đang sử dụng write
, đó là hàm cấp thấp được gọi bởi print
, chúng ta có thể truyền các đối số bổ sung như :circle
. Mã sau đó hoạt động như mong đợi:
#1=(let ((*print-circle* t))
(print '(write '#1# :circle t)))
Tuy nhiên, bạn cần thực thi các chương trình trên dưới dạng tập lệnh, không phải trong REPL, bởi vì mặc dù bạn in mọi thứ trong khi chăm sóc các cấu trúc vòng tròn, cả hai write
và print
cũng trả về giá trị được in; và trong REPL mặc định, giá trị cũng đang được in, nhưng bên ngoài bối cảnh động *print-circle*
là T.