Let's assume a=b, that is, a has value b. In a given expression like e.g.

a + i + HoldForm[a + k] + l

I would like to substitute - while the whole expression is being held globally - every symbol by its value, unless the symbol is wrapped in a local HoldForm. The form

HoldForm[a + i + HoldForm[a + k] + l] /. s_Symbol :> RuleCondition[s,ValueQ[s]]

returns b + i + (b + k) + l,

that is, all symbols of the expression have been substituted by their values, including the second appearance of a. How can I identify symbols which are wrapped in a local HoldForm and exclude them from this substitution procedure? Or do I have to take a completely different approach?

Thanks for help!

  • $\begingroup$ Developer`ReplaceAllUnheld[Unevaluated[a + i + HoldForm[a + k] + l], s_Symbol :> RuleCondition[s, ValueQ[s]]] would probably do the job. But what you ask is so incredibly clumsy, I recommend you rethink your code in the first place. $\endgroup$
    – QuantumDot
    Jan 26, 2020 at 20:39
  • $\begingroup$ Thanks. This goes into the right direction, but I need to keep the outer HoldForm. The Unevaluated is not enough. Except for the substitutions mentioned, no evaluation of the expression should take place. $\endgroup$ Jan 26, 2020 at 21:52

1 Answer 1


ReplaceAll works top-down, so you can add a rule to your replacement to leave HoldForm objects alone. Assuming the outer Hold wrapper isn't HoldForm you could do:

held = Hold[a + i + HoldForm[a + k] + l];
rule = {h_HoldForm :> h, HoldPattern[s_Symbol] :> RuleCondition[s]};

held /. rule

Hold[b + i + HoldForm[a + k] + l]

If the outer Hold wrapper is a HoldForm, then you would need to change the wrapper before applying the above rule, so you could do something like:

held = HoldForm[a + i + HoldForm[a + k] + l];

Apply[HoldForm] @ ReplaceAll[rule] @ Apply[Hold] @ held

HoldForm[b + i + HoldForm[a + k] + l]

  • $\begingroup$ Thanks a lot. This is exactly what I was looking for. And I learned a lot from your answer, too. $\endgroup$ Jan 27, 2020 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.