Erlang中的函数等式和排序

tcomlyy6  于 2022-12-08  发布在  Erlang
关注(0)|答案(2)|浏览(142)

What does it mean to compare functions in Erlang with the operators =:= , == , < , > , =< , >= ?
I was playing around with the interpreter and got these results:

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}

This makes sense. It looks like it's comparing the abstract syntax tree of the two functions.
But in this session X and Y are defined the same once again but are different, also now 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}

So it looks like it's not comparing the AST or any sort of unique references. Maybe it is comparing references, just some optimization is happening and X and Y get bound to the same reference? If there is some explanation for this, what happens across different VMs or different nodes?

bwitn5fc

bwitn5fc1#

shell中2求值之间的差异来自空行6〉。如果您使用函数erlang:fun_info/1查看fun,您将看到在这种情况下,该子句使用不同的数字存储(即2而不是1)。
如果你再次输入Y的定义(没有空行)你会得到一个不好的匹配,如果你之前输入一个空行,它是OK的。
我认为这是使用shell的一个副作用,但是行为在程序中是一致的。当然,〉或〈的意思对于一个有趣的程序来说并不明显,但是==是的。一个好的方面是Erlang项的顺序被定义了,所以可以对任何具有可预测行为的项进行排序:

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

h7appiyu2#

This behavior is different in shell and in compiled module. As for == and =:= operators in modules I am pretty sure that these operators return true iff:

  • Both functions are defined in the same place in code (isn't true in shell!)
  • Their effective closures are equal according to the respective ( == / =:= ) operator.

For instance with code

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

the following shall hold:

> 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.

Note that B does not belong to the closure of inner function therefore not influencing the comparison result.

相关问题