【问题标题】:Common lisp: break, but return input instead of nil?Common lisp:break,但返回输入而不是nil?
【发布时间】:2013-09-26 12:05:36
【问题描述】:

我是 lisp 新手,正在学习中。

标准 common lisp break 函数 1. 将您弹出到调试器中,并且 2. 如果您选择继续,则返回 nil。

在我看来,将您弹出到调试器但返回其输入的中断函数将非常有用。然后,您可以在给定的 s 表达式周围透明地插入它,以查看该点的程序状态。

所以我可以做类似的事情

CL-USER> (break-transparent (+ 1 2))

这会让我进入调试器,让我环顾四周,然后返回

3

lisp 中是否有这样的东西,如果没有,有没有办法制作这样的东西?我还不擅长宏。

谢谢,

编辑: Doug Currie 在下面用一个简单的宏很好地回答了这个问题。这是我为其他任何有此问题的人稍作修改的版本,它在调试器窗口中显示了break-transparent front and center 的参数。

(defmacro break-transparent (exp)
  `(let ((x ,exp)) (break "argument to break: ~:S" x) x))

【问题讨论】:

    标签: lisp common-lisp


    【解决方案1】:

    由于您已在稍作修改的版本中添加了您问题的其他答案中的宏,因此这是一个固定版本,它不会添加可能会干扰现有标识符的新标识符:

    (defmacro break-transparent (value)
      (let ((g (gensym)))
        `(let ((,g ,value))
          (break "argument to break: ~:S" ,g)
          ,g)))
    

    【讨论】:

      【解决方案2】:

      您可以将break-transparent 写成一个扩展为:

      (progn
        (break)
        (+ 1 2))
      

      或者如果你真的想在休息前评估表达式:

      (let ((x (+ 1 2)))
        (break)
        x)
      

      所以,

      (defmacro (break-transparent exp)
        `(let ((x ,exp)) (break) x))
      

      【讨论】:

      • 完美!谢谢。我对其进行了一些更改,以便 break 将在调试器窗口中显示其参数,而无需在回溯中寻找“x”。 (defmacro break-transparent (exp) `(let ((x ,exp)) (break "argument to break: ~:S" x) x)) 。 (break-transparent (+ 1 2)) 在调试器窗口中生成输出“argument to break: 3”并返回 3。
      • 在宏中引入一个新的标识符x 是不好的。它可能会干扰现有的x。使用gensym 创建一个保证唯一的标识符。
      • 新的标识符x只会干扰let体中的代码,不会干扰exp; let 的主体完全在我们的控制之下,因此没有现有的x 可以干扰。通常我会在任何情况下使用gensym,但这只会使答案复杂化。
      • @DougCurrie:确实,很难想象这会成为问题的情况,但仍有可能,例如,如果break-transparent 包含在代码遍历宏的参数形式中用其他东西替换所有出现的x
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-21
      • 2017-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多