# How do I get the length of held list without evaluating the list?

I used Extract with Hold to retrieve a sublist containing expressions I didn't want evaluating, e.g.

foo = Extract[OwnValues[test], {1, 2}, Hold]
(* Hold[{expr1, expr2, expr3}] *)


I'm sorry to ask such a trivial question, but, how do I get the length of that list?

Obviously Length@foo returns 1 because the top-level head is Hold. But attempting to access the lower levels seems to cause evaluation one way or another. What technique am I missing?

• Use Unevaluated instead of Hold or obtain expression where each list entry is wrapped in Hold. – Wizard Feb 27 '14 at 6:51

test = Hold[{Print@2; 1, 2, 3}];


One of many ways would be

test /. Hold[l_List] :> Length@Unevaluated@l


A couple others

Function[l, Length@Unevaluated@l, HoldAll] @@ test
test /. Hold[{args___}] :> Length@Hold[args]

• Ah, I see. As @Wizard was saying, I was trying to use Unevaluated, but my attempts would evaluate too little. Substitution's what I needed. Thanks! – Andrew Cheong Feb 27 '14 at 7:54
• @acheong87, if you'll do it more than once, you could create a function using your own idea of Extract, such as lengthAt[expr_, pos_] := Extract[expr, pos, Function[l, Length@Unevaluated@l, HoldAll]]. Then, lengthAt[test, 1] – Rojo Feb 27 '14 at 7:57