Erlang中的函数等式和排序

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

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

  1. Eshell V5.9.2 (abort with ^G)
  2. 1> X = fun() -> {} end.
  3. #Fun<erl_eval.20.82930912>
  4. 2> Y = fun() -> {} end.
  5. #Fun<erl_eval.20.82930912>
  6. 3>
  7. 3> {X == X, X =:= X}.
  8. {true,true}
  9. 4> {X >= X, X =< X}.
  10. {true,true}
  11. 5> {X > X, X < X}.
  12. {false,false}
  13. 6>
  14. 6> {X == Y, X =:= Y}.
  15. {true,true}
  16. 7> {X >= Y, X =< Y}.
  17. {true,true}
  18. 8> {X > Y, X < Y}.
  19. {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 ?

  1. Eshell V5.9.2 (abort with ^G)
  2. 1> X = fun() -> {} end.
  3. #Fun<erl_eval.20.82930912>
  4. 2>
  5. 2> {X == X, X =:= X}.
  6. {true,true}
  7. 3> {X >= X, X =< X}.
  8. {true,true}
  9. 4> {X > X, X < X}.
  10. {false,false}
  11. 5>
  12. 5> Y = fun() -> {} end.
  13. #Fun<erl_eval.20.82930912>
  14. 6>
  15. 6> {X == Y, X =:= Y}.
  16. {false,false}
  17. 7> {X >= Y, X =< Y}.
  18. {false,true}
  19. 8> {X > Y, X < Y}.
  20. {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项的顺序被定义了,所以可以对任何具有可预测行为的项进行排序:

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

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

the following shall hold:

  1. > test(1, x) == test(1, y).
  2. true.
  3. > test(1, x) =:= test(1, y).
  4. true.
  5. > test(1, x) == test(1.0, y).
  6. true.
  7. > test(1, x) =:= test(1.0, y).
  8. false.

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

展开查看全部

相关问题