【问题标题】:STEP macro does not work in Clozure CLSTEP 宏在 Clozure CL 中不起作用
【发布时间】:2012-03-13 23:21:48
【问题描述】:

我想使用步进函数来查看它是如何达到预期输出的,但它不起作用。

就像这个简单的例子:

(STEP (IF (ODDP 3) 'YES 'NO))

但什么也没发生。

有没有什么优化让我看不到trace步骤???

如何关闭它?

谢谢!

【问题讨论】:

  • "在技术上允许符合规范的实现除了正常执行表单之外不采取任何行动。在这种情况下,(step form) 等价于,例如,(let ( ) 形式)。在这种情况下的实现中,相关文档应提及该事实。” (CLHS) 我不知道 Clozure 是否采用这种“解决方案”...
  • 这里有一个关于 SBCL 的相关问题:stackoverflow.com/questions/8617064/…

标签: common-lisp ccl


【解决方案1】:

这个库不再分布在 quicklisp 上,但是当作为本地 quicklisp 项目安装时它会成功构建。

【讨论】:

    【解决方案2】:

    使用 cl-stepper:step 代替 cl-user:step ,因为 Clozure CL 不支持它。 如果您已经安装了 quicklisp,请尝试安装它:像这样。

    (ql:quickload "com.informatimago.common-lisp.lisp.stepper")
    
    (defpackage :test (:use :cl-stepper))
    (in-package :test)
    
    (def bar (hoge)
    ;; define some function
    )
    
    (step (bar 3))
    

    【讨论】:

      【解决方案3】:

      因为 CL:STEP 没有在 CCL 上实现,所以我实现了 com.informatimago.common-lisp.lisp.stepper。 您可以使用 quicklisp 获得它。 文档位于:https://gitorious.org/com-informatimago/com-informatimago/source/2b53ae44e8fa4d040fafcf4d93976500a8e464dc:common-lisp/lisp/stepper-packages.lisp#L146

      【讨论】:

      【解决方案4】:

      CCL 不支持 STEP。

      TRACE 解决方案:

      当使用 DEFUN 定义(全局命名的)函数 FOO 时,允许编译器假定对该函数名称的函数引用是指正在定义的函数(除非它们在词法上被遮蔽);因此,它可以在自调用(从 FOO 中调用 FOO)时跳过隐含的 SYMBOL-FUNCTION(“调用 FOO 的函数单元中的任何内容”)。这会在这些调用中节省一两条指令,但是(因为TRACE 通过更改 SYMBOL-FUNCTION 返回的内容来工作)无法跟踪那些内联的自调用。

      但是,如果函数名在 self 调用时声明为 NOTINLINE,编译器就不能这样做(甚至不能假设 DEFUN 定义的东西以后不会重新定义):

      示例:

      ? (defun fact (x acc)
          (declare (notinline fact))
          (if (= x 0)
              acc
              (fact (- x 1) (* x acc))))
      
      ? (trace fact)
      NIL
      
      ? (fact 3 1)
      0> Calling (FACT 3 1) 
       1> Calling (FACT 2 3) 
        2> Calling (FACT 1 6) 
         3> Calling (FACT 0 6) 
         <3 FACT returned 6
        <2 FACT returned 6
       <1 FACT returned 6
      <0 FACT returned 6
      
      ? (step (fact 3 1))
      0> Calling (FACT 3 1) 
       1> Calling (FACT 2 3) 
        2> Calling (FACT 1 6) 
         3> Calling (FACT 0 6) 
         <3 FACT returned 6
        <2 FACT returned 6
       <1 FACT returned 6
      <0 FACT returned 6
      

      这就是对编译器说的方式,“作为一个政策问题,我宁愿能够跟踪调用自身并使用 DEFUN 定义的函数,并且不关心每个 self- 节省几个周期。打电话”。

      来自:DebugWithOpenMCL

      或评估以下形式:

      (DECLAIM (OPTIMIZE (DEBUG 3)))
      

      在定义任何要跟踪的函数之前。

      【讨论】:

        【解决方案5】:

        我认为 Clozure CL 不支持步进。 IIRC 还没有人资助这个功能。它需要一些工作,因为 Clozure CL 缺少解释器(可以相对轻松地支持步进)。

        其他实现支持步进。

        【讨论】:

        • 快速查看源代码证实了这一点。来自 ccl:lib;macros.lisp: (defmacro step "..." (form) form)。
        猜你喜欢
        • 2020-04-16
        • 1970-01-01
        • 1970-01-01
        • 2012-01-25
        • 1970-01-01
        • 1970-01-01
        • 2016-08-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多