我很困惑我应该在常见的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
和BAZ
中的返回表单是否应包含在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
体内VAR2
,VAR3
和LET
的类型(绑定到DECLARE
,LET
和(declaim (ftype (function (t) <type>) foo bar baz))
的类型而不显式声明,或者我应该在绑定后立即添加另一个{{1}}表单吗?
即假设问题(d)中的{{1}}出现在定义了三个函数的文件以外的文件中,以下声明会产生什么影响:
{{1}}文件顶部的
有(d)的答案吗?
答案 0 :(得分:2)
要回答标题中的问题,您应该在希望人类读者知道某些值具有某些类型时使用声明。 过早优化会浪费程序员的时间和机器周期。
现在,您的具体清单:
一个。你有什么样的优化?编译器将知道返回值类型,但它将如何使用这些知识非常依赖于实现。
B,C。很可能是的。否则,它必须在编译之前加载文件,或在看到bar
之后重新编译foo
。
d。可能是的。
即如果编译器在编译foo
表单时知道函数let
&amp; c,它应该能够使用该知识。如果尚未加载定义函数的文件,则声明是必要的。但是请注意,如果你撒谎到编译器,你可能会遇到非常严重的麻烦(例如,segfault)。