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?

  • $\begingroup$ Use Unevaluated instead of Hold or obtain expression where each list entry is wrapped in Hold. $\endgroup$ – 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]
| improve this answer | |
  • $\begingroup$ 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! $\endgroup$ – Andrew Cheong Feb 27 '14 at 7:54
  • 1
    $\begingroup$ @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] $\endgroup$ – Rojo Feb 27 '14 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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