什么时候应该声明函数返回类型?

时间:2013-10-09 22:11:55

标签: lisp common-lisp

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

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

(defun bar (a)
  (foo a))

(defun baz (a)
  (bar a))

一个。编译器是否可以优化对BAZ的调用,或者BARBAZ中的返回表单是否应包含在THE形式(FOO中,就像它在{{1}中一样}}?换句话说,如果没有我明确说明,编译器是否会知道将(bar <form>)视为(the <type> (bar <form>))

湾三个定义的相对顺序是否影响(a)的答案?

℃。如果上面的定义发生在三个单独的源文件中,这些源文件被编译成三个单独的fasl文件,那么如何改变(a)的答案?

d。鉴于以下内容:

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

编译器是否可以正确推断VAR1体内VAR2VAR3LET的类型(绑定到DECLARELET(declaim (ftype (function (t) <type>) foo bar baz)) 的类型而不显式声明,或者我应该在绑定后立即添加另一个{{1}}表单吗?

即假设问题(d)中的{{1}}出现在定义了三个函数的文件以外的文件中,以下声明会产生什么影响:

{{1}}
文件顶部的

有(d)的答案吗?

1 个答案:

答案 0 :(得分:2)

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

现在,您的具体清单:

一个。你有什么样的优化?编译器将知道返回值类型,但它将如何使用这些知识非常依赖于实现。

B,C。很可能是的。否则,它必须在编译之前加载文件,或在看到bar之后重新编译foo

d。可能是的。

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