Skip to main content
Fix Typo
Source Link
SnzFor16Min
  • 2.2k
  • 8
  • 21
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
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 *)
f[x_, y_] := RandomReal[{x, y}]

Thread[f[{1, 2, 3}, 4]]
=> Thread[RandomReal[{1, 2, 3}, 4]] (* Evaluates *)
=> (* Error *)
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 *)
=> ...
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
Source Link
SnzFor16Min
  • 2.2k
  • 8
  • 21

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 *)
f[x_, y_] := RandomReal[{x, y}]

Thread[f[{1, 2, 3}, 4]]
=> Thread[RandomReal[{1, 2, 3}, 4]] (* Evaluates *)
=> (* Error *)
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 *)
=> ...