gpt4 book ai didi

Erlang:在代码中添加类型规范会让透析器更有效吗?

转载 作者:行者123 更新时间:2023-12-02 09:38:06 27 4
gpt4 key购买 nike

我有一个项目,代码中没有 -spec-type,目前 Dialyzer 可以找到一些警告,其中大多数都在机器生成的代码中。

在代码中添加类型规范会让透析器发现更多错误吗?

题外话,有没有什么工具可以检查是否违反规范?

最佳答案

添加类型规范将显着提高 Dialyzer 的准确性。

因为 Erlang 是一种动态语言,Dialyzer 必须默认对类型进行相当广泛的解释,除非您给它提示以缩小它将通过的“成功”类型。可以将其想象为为 Dialyzer 提供一个过滤器,通过该过滤器可以将一组可能的成功转换为应该工作的显式类型的子集。

这与 Haskell 不同,Haskell 的默认假设是失败,并且所有代码都必须以成功类型编写才能进行编译——Dialyzer 必须默认假设成功,除非它确定类型将要失败。

类型规范是其中的主要部分,但 Dialyzer 也会检查防护,因此像这样的函数

increment(A) -> A + 1.

不一样
increment(A) when A > 100 -> A + 1.

虽然两者都可以输入为

-spec increment(integer()) -> integer().

大多数时候您只关心整数值 integer() , pos_integer() , neg_integer() ,或non_neg_integer() ,但有时您需要仅在一侧限制的任意范围 - 并且类型语言当前无法表示这一点(尽管我个人希望看到 100..infinity 的声明按预期工作)。

when A > 100 的无界范围需要一个守卫,但有一个有界范围,如 when A > 100 and A < 201可以单独在类型规范中表示:

-spec increment(101..200) -> pos_integer().
increment(A) -> %stuff.

除了调用 length/1 之外,守卫速度很快 (你可能永远不会在守卫中真正需要它),所以在你真正知道并且能够证明你有来自守卫的性能问题之前,不要担心性能开销。使用守卫和类型规范来约束 Dialyzer 非常有用。作为您自己的文档,它也非常有用,特别是如果您使用 edoc,因为类型规范将显示在那里,使 API 不那么神秘,并且一目了然。

有一些关于在现有代码库中使用 Dialyzer 的有趣文献。这里有详细记录的经验:Gradual Typing of Erlang Programs: A Wrangler Experience 。 (不幸的是,我之前学到的一些其他链接已经消失或移动了。(!.!)仔细阅读 Wrangler 论文,浏览 User's Guideman page ,使用 Dialyzer,以及一些先前的经验不过,在像 Haskell 这样的类型系统中,您不仅可以为使用 Dialyzer 做好充分准备。)

[顺便说一句,我之前曾与一些人讨论过指定“纯”函数,这些函数可以通过符号或使用不同的定义语法来保证强类型(可能是 Prolog 的 :- 而不是Erlang 的 -> ...或其他),但是尽管这很酷,而且即使现在也很可能将副作用集中在程序的一小部分中,并将所有结果传递回 {Results, SideEffectsTODO} 的元组中。 ,这根本不是一个迫切的需求,Erlang 按原样工作得非常好。但 Dialyzer 确实非常有帮助,可以让您了解自己迷失的地方!]

关于Erlang:在代码中添加类型规范会让透析器更有效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34390452/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com