【问题标题】:Step Eval Common LispStep Eval Common Lisp
【发布时间】:2017-04-07 05:20:29
【问题描述】:

我一直在尝试寻找一种方法来进行“步骤”评估。我在哪里调用 a 函数,它会评估常见 lisp 的最嵌套列表。

例如:

'(+ 2 (+ 3 4))
; would eval to:
'(+ 2 7)

在那个例子中,它只计算了 3 + 4 并停在那里。它没有像 lisp 通常那样继续 eval 2 + 7。

所以我希望代码找到嵌套最多的列表并评估嵌套最多的列表,而不评估整个列表。

例如:

'(+ 2 3 4 5 (+ 4 5 (- 5 6) 1 (+ 10 8 5 (- 10 11))) 10 7)

它会找到最嵌套的列表(- 10 11),然后对其进行评估:

'(+ 2 3 4 5 (+ 4 5 (- 5 6) 1 (+ 10 8 5 -1)) 10 7)

同样,它只评估一次,而不是一次评估整个列表。

有没有人知道您如何才能对最嵌套的列表进行逐步评估?要使用 eval 或其他东西来执行列表中最嵌套的部分,而不是一次 evaling 整个列表?我遇到的问题是我不知道如何评估最嵌套的列表然后将其重新组合在一起。我不知道如何处理这个问题。请告诉我一个 lisper 大师是如何做到这一点的。

【问题讨论】:

  • 表达式是一个嵌套列表。只需遍历这个嵌套列表,如果它是 terminal 列表,则调用 eval。您首先需要学习如何使用函数遍历嵌套列表。
  • 我设法编写了一个可以到达最嵌套部分的函数,但我不知道如何将它重新组合在一起。也许我只是在想象这个错误之类的。

标签: lisp common-lisp


【解决方案1】:

我们使用step:

(step (+ 2 (+ 3 4)))
step 1 --> (+ 2 (+ 3 4))
Step 1 [4]> step
step 2 --> 2
Step 2 [5]> step
step 2 ==> value: 2
step 2 --> (+ 3 4)
Step 2 [6]> step
step 3 --> 3
Step 3 [7]> step
step 3 ==> value: 3
step 3 --> 4
Step 3 [8]> step
step 3 ==> value: 4
step 2 ==> value: 7
step 1 ==> value: 9
9

它并不完全符合您的要求,但非常接近。原因是 Common Lisp 需要完全按照步进器执行的顺序来评估表达式。

【讨论】:

    【解决方案2】:

    求值的顺序是从左到右的,所以如果你想模仿 Common Lisp 的行为,求最深的嵌套列表并不完全正确。

    您宁愿必须先评估第一个嵌套表单。假设格式正确的输入:

    (defun step-eval (form)
      (let ((sub-index (position-if #'listp form)))
        (if sub-index
            ;; there is a deeper list to step first
            (append (subseq form 0 sub-index)
                    (list (step-eval (nth sub-index form)))
                    (subseq form (1+ sub-index)))
            ;; no deeper list, eval this
            (eval form))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-16
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 2020-07-17
      • 2021-04-04
      • 1970-01-01
      相关资源
      最近更新 更多