Erlang的类型系统和静态分析
以下shell 经过windows 测试,注意新建 OTP_HOME ?HOME ?的环境变量为erlang安装目录
%dialyzer --build_plt -r "%OTP_HOME%/lib/kernel-2.15/ebin"
?
% 生成plt
dialyzer --build_plt -r "%OTP_HOME%/lib/erts-5.9/ebin"
dialyzer --add_to_plt --plt "%OTP_HOME%/.dialyzer_plt" -c "%OTP_HOME%/lib/kernel-2.15/ebin"
dialyzer --add_to_plt --plt "%OTP_HOME%/.dialyzer_plt" -c "%OTP_HOME%/lib/stdlib-1.18/ebin"
dialyzer --add_to_plt --plt "%OTP_HOME%/.dialyzer_plt" -c "%OTP_HOME%/lib/mnesia-4.6/ebin"
dialyzer --add_to_plt --plt "%OTP_HOME%/.dialyzer_plt" -c "%OTP_HOME%/lib/crypto-2.1/ebin"
dialyzer --add_to_plt --plt "%OTP_HOME%/.dialyzer_plt" -c "%OTP_HOME%/lib/sasl-2.2/ebin"
?
% dialyzer --build_plt --apps erts kernel stdlib mnesia crypto
% dialyzer --add_to_plt --apps crypto
?
?
“Erlang 是动态类型的语言,因而不能进行静态分析,所生成的文档也不包含有助于理解的类型信息”——这是惯常的看法,广为流行,而且被看作是 Erlang 在开发大型系统时的一个短板(大型系统意味着更强烈的静态分析需求和更严重的依赖文档进行沟通)。
然而 Erlang 是一个有着 20 多年历史的成熟系统,它早已发展出了一套自己的类型标注系统,不仅用来生成文档,更重要的是可以据此对源码进行静态分析,通过程序来排除一些低级的和隐藏的错误。在这方面, Erlang OTP 的源码本身及其文档就是最好的例子。在 《Erlang 程序设计》 的附录A部分,对于这个系统的使用已经进行了充分的说明。
需要强调的一点是在 Erlang 语言的背后还有一个活跃的社区(后者更为重要),其 EPP 过程一直都在持续不断地推进语言本身的进化。这方面最新的成果便是:在 R13 中,将此前文档级的 @spec,@type 标注升级为语言级的 -spec,-type 标注。可以预期的一点是,在未来的版本中,这些方面仍将持续推进。
litaocheng 同学的这篇“Erlang类型及函数声明规格”,风格严谨,论述详尽,涵盖了最新的语言特性,是任何一个程序员想要开发“严肃 Erlang 程序”的必读文档。
?
Erlang类型及函数声明规格
Author: litaocheng
Mail: litaocheng@gmail.com
Date: 2009.6.8
Copyright: This document has been placed in the public domain.
Contents:
概述
Erlang为动态语言,变量在运行时动态绑定,这对于我们获取函数的参数及返回值的类型信息具有一定的难度。为了弥补这个不足,在Erlang中我们可以通过type及spec定义数据类型及函数原型。通过这些信息,我们对函数及调用进行静态检测,从而发现一些代码中问题。同时,这些信息也便于他人了解函数接口,也可以用来生成文档。
意义
规范
类型及其定义语法
数据类型由一系列Erlang terms组成,其有各种基本数据类型组成(如 integer() , atom() , pid() )。Erlang预定义数据类型代表属于此类型的所有数据,比如 atom() 代表所有的atom类型的数据。
数据类型,由基本数据类型及其他自定义数据类型组成,其范围为对应数据类型的合集。比如:
litao@litao:~/erltest$ dialyzer -r ./spec参考
[1] EEP 8,Types and function specifications (http://www.erlang.org/eeps/eep-0008.html)
[2] reRestructureText (http://docutils.sourceforge.net/docs/user/rst/quickref.html)
[3] dialyzer (http://www.erlang.org/doc/man/dialyzer.html)