# How to extract part of a held expression without evaluating it

How can I extract part of a held expression without evaluating it?

Clear[w]
Part[HoldForm[w = 3],1,1]
(* w *)
w = 4
Part[HoldForm[w = 3],1,1]
(* 4 *)


Here I would like to obtain "w" again, not its current value. How can I extract the unevaluated symbol on the lhs of the definition, if the symbol has a value already before the definition is made in the hold form? "Part" seems to always evaluate the extracted part of the held expression. Is there a way to prevent this? Of course the problem is the same when I extract part of the rhs of the definition or when I extract any part of any held expression. I would like to use this inside of a function which takes as the argument any expression. This expression is then held and extractions made from it. So the solution should work without knowing in advance what the symbol on the lhs of the definition is and whether it is bound or not.

Thanks for help!

• Use Extract instead, e.g., Extract[HoldForm[w = 3], {1, 1}, Hold] Sep 13, 2018 at 21:25
• @CarlWoll, thanks, this is indeed what I was looking for. But this returns Hold[w]. How do I extract "w" from Hold[w], e.g. for printing it? Sep 13, 2018 at 21:56
• Perhaps you could use HoldForm instead of Hold? Sep 13, 2018 at 22:00
• Yes. Thanks again! Sep 13, 2018 at 22:18
• w = 4; Hold[ w = 3 ][[ {1}, 1 ]]
– Kuba
Sep 14, 2018 at 5:57

## 1 Answer

Like so:

Attributes@holdFormComplete={HoldAllComplete}
MakeBoxes[holdFormComplete@a_,f_]:=MakeBoxes[HoldForm@a,f];
w=4;
Extract[Hold[w=3],{1,1},holdFormComplete]
%//FullForm
(*w*)
(*holdFormComplete[w]*)


Note that MakeBoxes is also HoldAllComplete, so it won't allow HoldForm to leak no matter what is inside it.

• Why not HoldForm directly? Original Hold is a weak link anyway.
– Kuba
Sep 14, 2018 at 5:57