常见的lisp让我们绑定,而不是执行?

时间:2015-10-16 17:29:17

标签: common-lisp

在此代码中

(defun foo ()
   . . .
   (let ((bar (foo)))
      (if bar
         . . .)))
let行中

let只是绑定,对吧?它实际上并没有foo运行。我假设在foo语句中第一次运行if(递归),对吗?如果我认为是正确的,有没有办法让let实际执行foo然后将结果分配给bar

2 个答案:

答案 0 :(得分:5)

有一个答案显示了一个示例,说明了的行为。但是,通过实现的一个例子并不能确切地回答它是否假设表现那样,或者实现是否可以自由地做不同的事情,或者是否有&#sa; sa实施中的错误。要了解应该发生的事情,您需要查看文档。幸运的是,Common Lisp HyperSpec可以在线免费获取。 的文档说:

  

Special Operator LET, LET*

     

让我们让*创建新的变量绑定并执行一系列   使用这些绑定的表单。让我们并行执行绑定   并让*按顺序执行。

     

表格

 (let ((var1 init-form-1)
       (var2 init-form-2)
       ...
       (varm init-form-m))
   declaration1
   declaration2
   ...
   declarationp
   form1
   form2
   ...
   formn)
     

首先计算表达式init-form-1,init-form-2等,   按此顺序,保存结果值。然后是所有变量   varj绑定到相应的值;每个绑定都是词汇   除非有相反的特别声明。表达方式   然后按顺序评估formk;除了最后一个之外的所有值都是   丢弃(也就是说,let的主体是隐含的预测)。

因此,评估(执行)所有表单,然后将结果绑定到值,然后评估正文中的表单。

答案 1 :(得分:2)

在您提供的示例中,评估foo,然后将其分配给bar。您可以通过简单地评估以下内容来测试:

(let ((foo (+ 1 2)))
  (if (= foo 3)
      foo
      nil))
; => 3

比照PCL: Syntax and SemanticsLispdoc

修改

正如@ paulo-madeira在评论中提到的那样,这还不足以进行测试,因为你不知道每个评估的时间。请参阅他的评论,了解如何使用FORMAT对其进行测试。无论如何,要点是,LET你建议评估foo并将其分配给bar,这意味着你的函数foo是根据自身定义的,这意味着你&# 39;没有好处。