1
A
回答
5
#1=(defun x() (write '#1# :circle t))
1
定義我:defun定義,記錄源
拉斯的答案是一個聰明的一個,使用循環結構指的是內源的來源。另一個可能對於一般內省目的更有用的選項是定義一個特殊變量,以提供對正在定義的表單的訪問。這裏有一個初步,但並不完全拋光,版本:
(defpackage #:introspective-common-lisp
(:use "COMMON-LISP")
(:shadow "DEFUN")
(:nicknames #:icl))
(in-package #:icl)
(defvar *current-form* nil
"The current form being evaluated (typically a definition form.")
(defmacro defun (&whole form name lambda-list &body body)
"Like CL:DEFUN, except that within BODY, *CURRENT-FORM* is bound to
the defining ICL:DEFUN form."
`(cl:defun ,name ,lambda-list
(let ((*current-form* ',form))
,@body)))
(defun x()
"A function that prints its source."
(print *current-form*))
CL-USER> (in-package #:icl)
#<PACKAGE "INTROSPECTIVE-COMMON-LISP">
ICL> (x)
(DEFUN X
NIL
(PRINT *CURRENT-FORM*))
(DEFUN X
NIL
(PRINT *CURRENT-FORM*))
記住NIL
和()
是Common Lisp中同樣的事情,所以(defun x() ...)
是一樣的(defun x nil ...)
。當然,您可以檢查*current-form*
的值,然後決定打印()
,但這裏的要點是您可以訪問該表單,並且現在可以隨意打印它(無論您想要什麼)用它)。
更好的聲明處理
通過解析人體
隨着Common Lisp中的宏設施,這其實是一個相當容易的事,而且我能夠在很短的時間內湊齊了這一個。但是,要注意一些細節。在這個初始版本,我擴大了定製icl:defun
宏
`(cl:defun ,name ,lambda-list
(let ((*current-form* ',form))
,@body)))
這將錯位的聲明從body
,雖然。這確實需要是這樣的:
`(cl:defun ,name ,lambda-list
,@(util:body-declarations body)
(let ((*current-form* ',form))
,@(util:body-forms body)))
有包在那裏,將解析身體進入聲明/文檔字符串和形式,它不是太難推出自己的,無論是。
通過使用&輔助變量
你也可以跳過let
乾脆,並添加一個&aux
變量的cl:defun
的拉姆達名單,但要做到這一點,那麼你最好需要檢查是否有已經lambda列表中的一個&aux
關鍵字,因爲您不想添加多餘的關鍵字。這並不難,但它確實使我們的代碼變得更加複雜一些:
(eval-when (:compile-toplevel :load-toplevel :execute)
(cl:defun with-aux-variable (lambda-list name &optional value)
"Returns a new lambda list like LAMBDA-LIST (which should be an
ordinary lambda list), but with an NAME as an &aux variable with the
specified VALUE."
(let ((tail (if (member '&aux lambda-list)
(list (list name value))
(list '&aux (list name value)))))
(append lambda-list tail)))
) ; eval-when
(defmacro defun (&whole form name lambda-list &body body)
"Like CL:DEFUN, except that within BODY, *CURRENT-FORM* is bound to
the defining ICL:DEFUN form."
`(cl:defun ,name ,(with-aux-variable lambda-list
'*current-form*
(list 'quote form))
,@body))
+0
謝謝你這樣準確的答案:) – 2014-10-31 11:58:10
相關問題
- 1. 打印功能本身python 3
- 2. Clojure打印功能
- 3. Openlayers打印功能
- 4. javascript打印功能
- 5. Python打印功能
- 6. Vimscript打印功能?
- 7. JQuery打印功能不會打印
- 8. 打印功能打印結果?
- 9. 打印功能:我的標量和文本不打印
- 10. 打印的功能,幾次
- 11. 打印逆轉功能
- 12. 犀牛打印功能
- 13. 涉及打印功能
- 14. 的Python - 從打印功能
- 15. 提供打印功能4
- 16. PHP打印功能逃生
- 17. 打印所有功能 - cakephp
- 18. Python3中的打印功能
- 19. 功能多次打印
- 20. 功能打印PHP呼應
- 21. ARM7打印/輸出功能
- 22. 打印sympy輸入功能
- 23. 數組打印功能 - C++
- 24. 在asp.net中打印功能
- 25. Fancybox - 添加打印功能
- 26. 功能打印不工作
- 27. Python 3的打印功能
- 28. Python打印功能問題
- 29. 功能輸出不打印?
- 30. 從功能上打印Python
這是quine,但不是OP所要求的 - 「一種打印自身的功能」。 – coredump 2014-10-29 15:30:46
非常感謝:) – 2014-10-31 11:58:42