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, 2014 at 6:51

1 Answer 1

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]
  • $\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$ Feb 27, 2014 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, 2014 at 7:57

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.