在此代码中
(defun foo ()
. . .
(let ((bar (foo)))
(if bar
. . .)))
在let
行中,let
只是绑定,对吧?它实际上并没有foo
运行。我假设在foo
语句中第一次运行if
(递归),对吗?如果我认为是正确的,有没有办法让let
实际执行foo
然后将结果分配给bar
?
答案 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 Semantics或Lispdoc。
正如@ paulo-madeira在评论中提到的那样,这还不足以进行测试,因为你不知道每个评估的时间。请参阅他的评论,了解如何使用FORMAT
对其进行测试。无论如何,要点是,LET
你建议评估foo
并将其分配给bar
,这意味着你的函数foo
是根据自身定义的,这意味着你&# 39;没有好处。