erlang中的函数相等/排序

时间:2012-10-25 20:53:00

标签: erlang undefined-behavior ambiguity

将Erlang中的函数与运算符=:===<>=<>=进行比较是什么意思?我正在玩翻译,并得到了这些结果:

Eshell V5.9.2  (abort with ^G)
1> X = fun() -> {} end.
#Fun<erl_eval.20.82930912>
2> Y = fun() -> {} end.
#Fun<erl_eval.20.82930912>
3> 
3> {X == X, X =:= X}.
{true,true}
4> {X >= X, X =< X}.
{true,true}
5> {X > X, X < X}.
{false,false}
6> 
6> {X == Y, X =:= Y}.
{true,true}
7> {X >= Y, X =< Y}.
{true,true}
8> {X > Y, X < Y}.
{false,false}

这是有道理的。看起来它正在比较两个函数的抽象语法树。

但是在这个会话中XY再次定义相同但又不同,现在也是X<Y

Eshell V5.9.2  (abort with ^G)
1> X = fun() -> {} end.
#Fun<erl_eval.20.82930912>
2> 
2> {X == X, X =:= X}.
{true,true}
3> {X >= X, X =< X}.
{true,true}
4> {X > X, X < X}.
{false,false}
5> 
5> Y = fun() -> {} end.
#Fun<erl_eval.20.82930912>
6> 
6> {X == Y, X =:= Y}.
{false,false}
7> {X >= Y, X =< Y}.
{false,true}
8> {X > Y, X < Y}.
{false,true}

所以看起来它并没有比较AST 任何类型的唯一引用。也许是比较引用,只是发生了一些优化,XY绑定到同一个引用?如果对此有一些解释,不同的VM或不同的节点会发生什么?

2 个答案:

答案 0 :(得分:3)

壳中的2评价之间的差异来自空白行6&gt;。如果你看一下使用函数erlang:fun_info / 1的乐趣,你会发现在这种情况下,子句存储了不同的数字(即2而不是1)。

如果再次输入Y的定义(没有空白行),您将得到一个错误的匹配,如果您之前输入一个空行,则表示没问题。

我认为这是使用shell的副作用,但行为在程序中是一致的。当然是&gt;的含义或者&lt;对于一个有趣的事情并不明显,但是==是的。一个好处是Erlang术语的顺序是定义的,因此可以对具有可预测行为的任何术语的列表进行排序:

number < atom < reference < fun < port < pid < tuple < list < bit string

答案 1 :(得分:1)

此行为在Shell和已编译模块中有所不同。至于模块中的===:=运算符,我很确定这些运算符会在出现以下情况时返回true

  • 两个函数都在代码中的同一位置定义(在shell中是不正确的!)
  • 根据各自的(== / =:=)运算符,它们的有效闭包是相等的。

例如带有代码的

test(A, B) ->
  fun(C) -> {A, C} end.

以下内容应满足:

> test(1, x) == test(1, y).
true.
> test(1, x) =:= test(1, y).
true.
> test(1, x) == test(1.0, y).
true.
> test(1, x) =:= test(1.0, y).
false.

请注意,B不属于内部函数的闭包,因此不影响比较结果。