【问题标题】:Why does Erlang have arity in its imports?为什么 Erlang 在它的 import 中有arity?
【发布时间】:2014-02-14 11:00:36
【问题描述】:

我发现 Erlang 的模块 arity import /n 其中 n 是参数的数量相当奇怪。

在 Java 和其他各种语言中,您可以执行以下操作:

import static com.stuff.Blah.myFunction;

无论参数如何,都会导入所有重载的Blay.myFunction(..)

除了我想明确说明为什么语言设计者认为这是一个好主意(我不是要批评这种语言......只是好奇)?

  • 和代码交换有关系吗?
  • 或者它是否与隐藏 guard 方法以进行递归有关?如果是这样,为什么不允许在导出时使用 arity,但在导入时不需要使用 arity?
  • 我为什么要这么明确?那就是导入两个参数函数而不是myFunction的三个参数?

【问题讨论】:

    标签: erlang


    【解决方案1】:

    您应该了解 Erlang 中的导入函数的真正作用。这是一个纯文本转换。如果我执行-import(foo, [bar/1,baz/2]).,这意味着当我编写像bar(5)baz(a, 3) 这样的调用时,编译器会将它们转换为foo:bar(5)foo:baz(a, 3)。这就是它所做的一切,没有别的。它不检查任何东西:

    • 不检查模块foo是否包含函数bar/1baz/2
    • 它甚至不检查模块foo 是否存在。

    实际上,它所做的只是隐藏您正在调用另一个模块中的函数。这就是为什么经验丰富的 Erlangers 的建议是“不要使用它”。那是一个错误。不幸的是,添加愚蠢的东西比删除它们容易得多,所以我们永远无法删除它。

    “和代码交换有关系吗?”

    是的,有点。 Erlang中所有代码处理的单位是模块。所以你编译模块、加载模块、清除和删除模块。这意味着系统中根本不存在模块间依赖关系,并且编译器在编译模块时不会对其他模块做出任何假设。没有假设编译模块的环境与运行它的环境相同。这就是为什么在运行时系统会检查您尝试在另一个中调用的函数是否存在,或者即使模块本身是否存在。这就是为什么import 是纯文本转换的原因。

    【讨论】:

    • 绝对。不要使用导入,它会使代码更难阅读。去过那里,做到了。
    【解决方案2】:

    Erlang 最初是在 Prolog 中开发的。

    在 Prolog 中,arity 为程序编程语言中您认为的“参数,正如我从函数中理解的那样”添加了额外的含义。但该模型不适用于此处。

    所谓的从句'married(X,Y)'。和“已婚(X,Y,Z)。”暗示另一种“已婚”关系,可以声明为已婚/2 和已婚/3。

    在过程编程中,'add(a,b)' 或 'add(a,b,c)' 旨在生成不同数量的参数的相加。在 Prolog 中情况并非如此,在这种情况下,可能有关系“a 和 b,添加”或“a,b 和 c,添加”意味着其他东西。不用说,Prolog 允许您像您期望的函数那样声明“添加”。但它允许更多。更多可用的含义,意味着更多需要控制它。

    与任何模块系统一样,选择要向外部客户端公开的内容是有意义的:因此声明了 arity.

    【讨论】:

      【解决方案3】:

      和代码交换有关系吗?

      有点。 Erlang 中的模块是单独编译的(这是允许代码交换的一部分),与 Java 类不同,因此编译器不知道存在多少个具有不同数量的导入函数版本。当然,它可以假设具有给定名称的函数的所有调用都来自同一个模块,但设计者可能认为它不是特别有用。

      事实上,至少在我的经验中,您根本不想使用导入,就像您在 Java 中很少使用静态导入一样。只需写module:function,比如Class.staticMethod

      或者它是否与隐藏递归的保护方法有关?

      不,因为不导入函数不会以任何方式隐藏它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-15
        • 1970-01-01
        • 2021-03-10
        • 2019-03-20
        • 2016-06-03
        • 2020-12-10
        相关资源
        最近更新 更多