2011-07-29 47 views
7

追溯CL中的关闭有可能吗?例如,我可以跟踪下面的foo-3吗?追踪关闭

(defun foo (n) 
    (lambda (i) (incf n i))) 
FOO 
(setf foo-3 (foo 3)) 
#<CLOSURE :LAMBDA (I) (INCF N I)> 

(funcall foo-3 2) 
5 
(funcall foo-3 2) 
7 
(trace ???) 
+1

好问题! –

回答

1

确实有可能这样做。 Trace在函数名称空间中查找函数,因此请确保不要混合使用值和函数。

(setf (symbol-function 'test) 
    (let ((n 0)) 
    (lambda (x) 
    (incf n x)))) 
=> 
#<Interpreted Closure TEST> 
(trace test) 
... 
(test 4) 
=> 
0[2]: (TEST 4) 
0[2]: returned 4 
4 
(test 3) 
=> 
0[2]: (TEST 3) 
0[2]: returned 7 
7 
+0

谢谢!我一直在通过http://www.gnu.org/s/emacs/manual/html_node/elisp/Symbol-Components.html#Symbol-Components,http://www.dreamsongs.com/Separation.html和CLTL。现在我对此有了一个很好的感觉。关于这个值得参考的命名空间的任何其他资源? – user869081

3

我不认为这是可能的:据我所知,跟踪宏通常的工作原理是通过调用原来还打印出跟踪位的包装在一个给定的符号替换功能。

如果您对(复杂的)实现细节感兴趣,SBCL代码位于src/code/ntrace.lisp(您可能需要查看trace-1函数)。

当然,如果你想要做的就是打印出来的东西时富-3被调用时,你总是可以把打印语句foo中的拉姆达表单内...

+1

是否有关于闭包的基础知识,使得为它们编写追踪函数变得不可能? – user869081

0

我觉得这里的问题是该trace需要一个函数名称,而不是跟踪闭包有问题。从上面的示例继续,可以从命名函数调用foo-3,并跟踪:

(defun call-foo-3 (i) 
    (funcall foo-3 i)) 
(trace call-foo-3) 
(call-foo-3 2) 
    0: (CALL-FOO-3 2) 
    0: CALL-FOO-3 returned 15