追踪闭包

发布于 2024-11-27 07:50:43 字数 230 浏览 0 评论 0原文

是否可以在 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 ???)

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))
#<CLOSURE :LAMBDA (I) (INCF N I)>

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对岸观火 2024-12-04 07:50:43

我认为这是不可能的:据我所知,跟踪宏通常通过将给定符号处的函数替换为调用原始函数并打印出跟踪位的包装器来工作。

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

当然,如果您只想在调用 foo-3 时打印一些内容,那么您始终可以在 foo 的 lambda 形式中放置一条 print 语句...

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...

岁吢 2024-12-04 07:50:43

确实可以这样做。 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

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
三生路 2024-12-04 07:50:43

我认为这里的问题是 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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文