为什么Erlang的进口产品具有优势?

时间:2014-01-23 17:59:25

标签: erlang

我找到了Erlang的模块arity import /n,其中n是参数的数量而非奇怪。

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

import static com.stuff.Blah.myFunction;

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

此外我想明确为什么语言设计师认为这是一个好主意(我不是在试图批评这种语言......只是好奇)?

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

3 个答案:

答案 0 :(得分:9)

你应该知道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纯粹是文本转换的原因。

答案 1 :(得分:2)

Erlang最初是在Prolog中开发的。

在Prolog中,arity为你认为是'参数的东西增加了额外的含义,正如我从过程编程语言中的函数中理解的那样。但这种模式不适用于此。

所谓的条款'已婚(X,Y)。'和'结婚(X,Y,Z)。'意味着一种不同的“已婚”关系,可以宣布为已婚/ 2和已婚/ 3。

在程序编程中,'add(a,b)'或'add(a,b,c)'旨在生成不同数量的参数。这不是Prolog中的情况,在那里可以建立关系'a和b,添加'或'a,b和c,添加'意味着别的东西。毋庸置疑,Prolog允许您按照您期望的函数来声明“添加”。但它允许更多。更多可用的含义,意味着更多需要控制它。

和任何模块系统一样,选择要向外部客户端公开的内容是有道理的:因此arity的声明。

答案 2 :(得分:1)

  

是否与代码交换有关?

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

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

  

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

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