Matching fun M:F/A

Dániel Szoboszlay dszoboszlay@REDACTED
Fri Jan 3 00:15:37 CET 2020


On Thu, 2 Jan 2020 at 13:41, Jesper Louis Andersen <
jesper.louis.andersen@REDACTED> wrote:

> Admitting equality and by extension unification on function values is a
> dangerous game which you usually don't want to play. The reason is that
> equality often has to be tailored to the situation.
>
>
It may be a bit aside to the original topic, but I don't understand this
argument. Erlang already defines equality of function values, even pattern
matching works for them with the = operator. The proposal was not about
(re)defining the semantics of these operations but making the language more
consistent on where does it allow the use of them.

Also, while it's true that function equality is undecidable, functions are
not the only data type where the language's built-in equality and pattern
matching are not tailored to the situation. In fact, it's quite common that
complex data structures allow expressing the same value in different,
unequal forms. For example both {[2],[1]} and {[],[1,2]} describe the same
queue value, yet they won't compare equal. I believe this is something
programmers are expected to understand and be aware of, and therefore they
shall also understand and be aware of the limitations of the built-in
function equality.

Cheers,
Daniel

PS: I played a bit with function equality and pattern matching while
writing my reply, and I personally found all but the last of these examples
intuitive (by the way, they all work with = in place of =:= too):
1> F1 = fun lists:sort/1.
fun lists:sort/1
2> F2 = fun lists:sort/1.
fun lists:sort/1
3> F1 =:= F2.
true
4> F = fun (X) -> F1([x | X]) end.
#Fun<erl_eval.6.128620087>
5> F =:= F.
true
6> G = fun (X) -> F1([x | X]) end.
#Fun<erl_eval.6.128620087>
7> F =:= G.
true
8> H = fun (X) -> F2([x | X]) end.
#Fun<erl_eval.6.128620087>
9> F =:= H.
false

For anyone curious, F and H are not equal because we're in the shell, and
funs created in the shell will essentially take their source code in a free
variable, which for H is the following tuple:
{[{'F2',fun lists:sort/1}],
 {eval,#Fun<shell.21.103068397>},
 {value,#Fun<shell.5.103068397>},
 [{clause,1,
          [{var,1,'X'}],
          [],
          [{call,1,{var,1,'F2'},[{cons,1,{atom,1,x},{var,1,'X'}}]}]}]}

Now it's obvious that while variables F1 and F2 are bound to the same
function value and would compare equal, shell funs using them would also
contain their variable names, which are different.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20200103/3d3b267e/attachment.htm>


More information about the erlang-questions mailing list