3

我对应该在 common lisp 中声明函数返回类型的位置和频率感到困惑。如果我理解正确,使用声明提供的信息不需要实现,并且在使用信息时,效果没有很好的定义,并且在不同的实现之间可能不一致,所以这更多是最佳实践的问题而不是正式定义。如果您尝试回答这些问题,请记住这一点。基本上,这就是我想知道的:假设我的目标是最大效率((optimize (debug 0) (safety 0) speed)),原则上何时提供函数返回类型声明,编译器可用于优化的有用信息?这是一个宽泛的问题,我会给出宽泛的答案;但为了更好地了解我的目标,让我将其分解为几个具体问题。给定以下定义:

(defun foo (a)
  (the <type> <form>))

(defun bar (a)
  (foo a))

(defun baz (a)
  (bar a))

一个。编译器是否可以优化对 的调用BAZ,或者是否应该将返回形式包含在一个(看似多余的)形式中BAR,就像它一样?换句话说,编译器会知道在没有我明确表示的情况下将其视为?BAZTHEFOO(bar <form>)(the <type> (bar <form>))

湾。三个定义的相对顺序会影响 (a) 的答案吗?

C。如果上述定义出现在三个单独的源文件中,这些源文件被编译成三个单独的 fasl 文件,那将如何改变 (a) 的答案?

d。鉴于以下情况:

(let ((var1 (foo <form1>))
      (var2 (bar <form2>))
      (var3 (baz <form3>)))
  <form>*)

编译器能否/将正确推断(绑定到的对象)VAR1、、VAR2VAR3在没有显式类型声明的主体内的类型,还是应该在绑定之后LET立即添加另一种形式?DECLARE

e. 假设LETfrom 问题 (d) 出现在定义三个函数的文件以外的文件中,以下声明将产生什么影响:

(declaim (ftype (function (t) <type>) foo bar baz))

在文件的顶部有关于 (d) 的答案?

4

1 回答 1

2

要回答标题中的问题,当您希望人类读者知道某些值具有某些类型时,您应该使用声明。过早的优化是对程序员时间和机器周期的浪费。

现在,您的具体清单:

一个。你有什么样的优化?编译器会知道返回值的类型,但是它将如何使用这些知识在很大程度上取决于实现。

公元前。很可能是的。否则它将不得不在编译之前加载文件或bar在它看到之后重新编译foo

d。大概是。

e. 如果编译器在编译表单时知道函数foo&c let,它应该能够使用该知识。如果定义函数的文件尚未加载,则需要声明。但是请注意,如果您对编译器撒谎,您可能会遇到非常严重的麻烦(例如,段错误)。

于 2013-10-09T23:32:36.120 回答