Answers:
静态类型系统是一种静态分析,但是有很多静态分析通常不在类型系统中进行编码。例如:
模型检查是用于并发系统的一种分析和验证技术,它使您可以证明您的程序在所有可能的线程交织下都表现良好。
数据流分析收集有关变量可能值的信息,这些信息可以确定某些计算是否是冗余的,还是未考虑某些错误。
抽象解释通常以保证分析终止的方式保守地模拟程序的效果,而类型检查器的实现方式可以类似于抽象解释器。
分离逻辑是一种程序逻辑(例如,在Infer分析器中使用),可用于推理程序状态,并标识诸如空指针取消引用,无效状态和资源泄漏之类的问题。
基于合同的编程是一种指定前提条件,后置条件,副作用和不变式的方法。Ada对合同具有本地支持,并且可以静态验证其中一些合同。
优化的编译器会进行许多小的分析,以构建可在优化期间使用的中间数据结构,例如SSA,内联成本估算,指令配对信息等。
非声明式静态分析的另一个示例可以在Hack typechecker中找到,其中常规的控制流构造可以优化变量的类型:
$x = get_value();
if ($x !== null) {
$x->method(); // Typechecks because $x is known to be non-null.
} else {
$x->method(); // Does not typecheck.
}
说到“精炼”,回溯到类型系统领域,精炼类型(如LiquidHaskell中使用的)与谓词配对,保证谓词可以保存“精炼”类型的实例。而依赖类型则更进一步,允许类型依赖于值。依赖类型的“ hello world”通常是数组串联函数:
(++) : (a : Type) -> (m n : Nat) -> Vec a m -> Vec a n -> Vec a (m + n)
在此,++
采用类型的两个操作数Vec a m
和Vec a n
,作为载体与元素类型a
和长度m
和n
(分别是,这是自然数Nat
)。它返回一个与元素类型相同的向量,其长度为m + n
。并且这个功能抽象地证明了这种约束,在不知道的特定值m
和n
,所以向量的长度可以是动态的。
int
,int -> int
,forall a. a -> a
),以术语(例如,0
,(+ 1)
,\x -> x
)。其它分析可归于无关数据类型不同的特性,例如,副作用(pure
,io
),可见性(public
,private
),或状态(open
,closed
)。实际上,可以在与类型检查/推断相同的实现中检查其中的许多属性,因此区别并不十分明确。
@JonPurdy的答案更好,但我想补充一些例子:
明显:
语法检查
林亭
不明显:
Rust使程序员能够指定“绑定”是否可变,并强制执行这些约束。
这是相关的:某些语言允许某些代码在编译时运行,这意味着在编译时可能会捕获许多原本是运行时错误的内容。一些示例是标有pragma的宏和Nim语言过程。compileTime
半静态输入: