There exist many related posts, but has it ever been explained in a clear and detailed enough way?
Notice a variant of the question in title is
Why doesn't
lst = {a, b, c}; Thread[Unevaluated@f[lst]]
return
{f[a], f[b], f[c]}
?
There exist many related posts, but has it ever been explained in a clear and detailed enough way?
Notice a variant of the question in title is
Why doesn't
lst = {a, b, c}; Thread[Unevaluated@f[lst]]
return
{f[a], f[b], f[c]}
?
ANSWERING THE QUESTION IN THE TITLE:
I'm not sure exactly what you don't understand about this, but I can take you through this step by step.
b = a
is a symbol assignment. It tells Mathematica "from now on, replace b
with a
."
Next, f[a_] := b
defines a replacement rule. The a_
is a named pattern, and it is unrelated to the symbol a
mentioned in the first line. This rule is exactly the same as the rule f[x_] := b
-- the rule doesn't care what you name the pattern. It tells Mathematica to "replace every expression with f
as the head and one argument with b
".
Finally, f[1]
is evaluated. The second rule tells Mathematica to replace this with b
. Then the first rule tells Mathematica to replace this with a
.
I'm not sure what exactly is confusing about this. It's important to understand that Mathematica is a pattern-replacement machine.
ANSWERING THE SECOND QUESTION:
Unevaluated@f[lst]
tells Mathematica not to evaluate "lst
", so, as far as Thread
is concerned, lst
is just an undefined symbol.
So, Thread[Unevaluated@f[lst]]
is evaluated the same way as Thread[f[X]]
where X
is just an undefined symbol, which would give f[X]
.
So,Thread[Unevaluated@f[lst]]
gives f[lst]
.
Next, f[lst]
is evaluated, it gives f[{a,b,c}]