Thread[Unevaluated@f[{1, 2, 3}, 4]]
{1.946182809, 2.842898138, 3.571798651}
Explanation
Documentation of Thread
:
Thread
evaluates the whole expression before threading.
f[x_, y_] := x + y
Thread[f[{1, 2, 3}, 4]]
=> Thread[{1, 2, 3} + 4] (* Evaluates *)
=> Thread[{5, 6, 7}]
=> {5, 6, 7} (* Threads... trivially *)
Since +
is Listable
, nothing went wrong even though f
was evaluated first.
f[x_, y_] := RandomReal[{x, y}]
Thread[f[{1, 2, 3}, 4]]
=> Thread[RandomReal[{1, 2, 3}, 4]] (* Evaluates... *)
=> (* Error *)
"Evaluate first" passes wrong arguments to RandomReal
.
f[x_, y_] := RandomReal[{x, y}]
Thread[Unevaluated@f[{1, 2, 3}, 4]]
=> Thread[f[{1, 2, 3}, 4]] (* Evaluates *)
=> {f[1,4],f[2,4],f[3,4]} (* Threads *)
=> ...
Unevaluated
helps f
survive the evaluation.
f[x_, y_] := RandomReal[{x, y}]
list = {1, 2, 3};
Thread[Unevaluated@f[list, 4]]
=> Thread[f[list, 4]] (* Evaluates *)
=> f[list, 4] (* Threads... Nothing to thread! *)
=> RandomReal[{1, 2, 3}, 4]
=> (* Error *)
list
should not survive the evaluation, while f
should. We can use Inactive
on f
and Activate
afterwards:
f[x_, y_] := RandomReal[{x, y}]
list = {1, 2, 3};
Activate@Thread[Inactive[f][list, 4]]
=> Activate@Thread[Inactive[f][{1, 2, 3}, 4]] (* Evaluates *)
=> Activate@{Inactive[f][1,4], Inactive[f][2,4], Inactive[f][3,4]} (* Threads *)
=> {f[1,4], f[2,4], f[3,4]} (* Activates *)
=> ...
Actually, there're many simpler and faster ways to do this, like:
f[#, 4] & /@ list
f[#, 4]&/@{1,2,3}
is more natural in this case. $\endgroup$Thread
is somewhat a bit of complicated and I rarely use it. $\endgroup$