<div dir="ltr">> <span style="font-family:arial,helvetica,sans-serif">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.</span><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Ah so this is the question I aimed to sidestep. This is not about anonymous funs nor un-exported functions.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">As Dániel expresses I think more clearly than I: </div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">> 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.</div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div><br></div><div>Now I understand the use for this "cleaning up of some dark corner of the Erlang language" might not be obvious yet</div><div>and it may bring more puzzling (to newcomers?) than expressiveness powers. I'm only asking:</div><div><br></div><div>Is there a story behind this maybe unfortunate language result?</div><div>How do you feel about being able to pattern match on fun M:F/A?</div><div><br></div><div>Thanks & happy new years</div><div>-- </div><div>Pierre Fenoll</div></div><div><br></div></div></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 3 Jan 2020 at 00:16, Dániel Szoboszlay <<a href="mailto:dszoboszlay@gmail.com">dszoboszlay@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On Thu, 2 Jan 2020 at 13:41, Jesper Louis Andersen <<a href="mailto:jesper.louis.andersen@gmail.com" target="_blank">jesper.louis.andersen@gmail.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div style="font-family:arial,helvetica,sans-serif">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.<br></div></div><div class="gmail_quote"><div style="font-family:arial,helvetica,sans-serif"><br></div></div></div></blockquote><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Cheers,</div><div>Daniel</div><div><br></div><div>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):</div><div><font face="monospace">1> F1 = fun lists:sort/1.<br>fun lists:sort/1<br>2> F2 = fun lists:sort/1.<br>fun lists:sort/1<br>3> F1 =:= F2.<br>true<br>4> F = fun (X) -> F1([x | X]) end.<br>#Fun<erl_eval.6.128620087><br>5> F =:= F.<br>true<br>6> G = fun (X) -> F1([x | X]) end.<br>#Fun<erl_eval.6.128620087><br>7> F =:= G.                       <br>true<br>8> H = fun (X) -> F2([x | X]) end.<br>#Fun<erl_eval.6.128620087><br>9> F =:= H.                       <br>false</font><br></div><div><br></div><div>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:</div><div><font face="monospace">{[{'F2',fun lists:sort/1}],<br> {eval,#Fun<shell.21.103068397>},<br> {value,#Fun<shell.5.103068397>},<br> [{clause,1,<br>          [{var,1,'X'}],<br>          [],<br>          [{call,1,{var,1,'F2'},[{cons,1,{atom,1,x},{var,1,'X'}}]}]}]}<br></font></div><div><font face="monospace"><br></font></div><div>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.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
</blockquote></div></div>
</blockquote></div>