1
$\begingroup$

If I have

v1 = RandomInteger[5, 10];
v2 = RandomInteger[5, 10];
Remove[f]

then, not surprisingly

MapThread[f,{v1,v2}]
%/.f[a_,b_]->a==b

gives (for example)

{f[5,2],f[4,1],f[3,3],f[3,4],f[1,2],f[3,4],f[1,0],f[3,0],f[4,0],f[1,1]}
{False,False,True,False,False,False,False,False,False,True}

and

Thread[f[v1,v2]]
%/.f[a_,b_]->a==b

gives the same results

{f[5,2],f[4,1],f[3,3],f[3,4],f[1,2],f[3,4],f[1,0],f[3,0],f[4,0],f[1,1]}
{False,False,True,False,False,False,False,False,False,True}

But if I define

f[a_,b_] := a==b

then MapThread and Thread no longer give the same results:

MapThread[f,{v1,v2}]
Thread[f[v1,v2]]

gives

{False,False,True,False,False,False,False,False,False,True}
False

What's going on here? Why do the same expressions result in different evaluations? Why does Thread "collapse" the list of truth values when MapThread does not?


Note that a related example in the documentation is misleading about what happens here. It shows how

Thread[{a,b,c}=={x,y,z}]

evaluates to

{a==x,b==y,c==z}

but that's only true if the elements of the first group can't be compared to the elements of the second.

$\endgroup$
  • 2
    $\begingroup$ Thread isn't Hold* so f[v1,v2] evaluates immediately $\endgroup$ – b3m2a1 Sep 7 '17 at 18:19
  • 1
    $\begingroup$ I devoted a separate section to this in my book $\endgroup$ – Leonid Shifrin Sep 7 '17 at 18:34