Tracing a closure
Is it possible to trace a closure in CL? For ex., can I trace foo-3 below?
(defun foo (n)
(lambda (i) (incf n i)))
FOO
(setf foo-3 (foo 3))
#<CLOSUR开发者_如何学CE :LAMBDA (I) (INCF N I)>
(funcall foo-3 2)
5
(funcall foo-3 2)
7
(trace ???)
I don't think this is possible: as far as I know, the trace macro generally works by replacing the function at a given symbol by a wrapper that calls the original and also prints out the tracing bit.
If you're interested in the (complicated) implementation details, the SBCL code is in src/code/ntrace.lisp (you probably want to look at the trace-1 function).
Of course, if all you want to do is print something out when foo-3 is called, you could always put a print statement inside the lambda form in foo...
It is indeed possible to do so. Trace looks for functions in the function-namespace, so make sure to not mix values and functions.
(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
I think the problem here is that trace
requires a function name, rather than there being a problem with tracing closures. Continuing from your example above, you can call foo-3
from a named function, and trace that:
(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
精彩评论