# How to match Association[]?

The following input:

Cases[{"key" -> Association[]}, HoldPattern["key" -> Association[]]]


Returns {}. Why does it not return {"key" -> Association[]}? I was expecting it to match.

• You should use Verbatim for that. HoldPattern is for patterns – RunnyKine Apr 19 '16 at 15:43
• @RunnyKine I thought I would use HoldPattern to treat the rule itself as a pattern, otherwise the rule is interpreted by Cases (as discussed here: mathematica.stackexchange.com/questions/112333/…) – rmagno Apr 19 '16 at 15:53
• The subtle point here is that Association[] evaluates to <||>, and even though the FullForms of the two are the same, SameQ on them gives False, because the constructor Association[] does a non-trivial job when evaluated, and the result of it is not a normal expression Association[], but a new atomic object. So, we have Unevaluated[Association[]] === Association[] producing False. Therefore, MatchQ[Association[], HoldPattern[Association[]]] gives False, while of course MatchQ[Association[], HoldPattern[Evaluate@Association[]]] gives True. – Leonid Shifrin Apr 19 '16 at 15:58
• @LeonidShifrin: very interesting. I keep forgetting Association is an atomic expression. But how would you suggest I do the matching with Cases? Inspired by your MatchQ example I can see that Cases[{Association[]}, HoldPattern[Evaluate@Association[]]] matches, but it won't match if the expression containing Association is a Rule. For instance: Cases[{"key" -> Association[]}, HoldPattern["key" -> Evaluate@Association[]]] won't match. – rmagno Apr 19 '16 at 16:31
• Use Verbatim, as @RunnyKine suggested. Since it does not prevent evaluation of parts of the pattern, you will then compare evaluated / constructed Association[] in your expression with a similarly evaluated Association[] inside the pattern. Or, much simpler, if you don't care whether or not association is empty, you could use _Association pattern, which is matched in both cases. – Leonid Shifrin Apr 19 '16 at 16:39

To answer the question of why there is no match let's look at the output of Trace:

Cases[{"key" -> Association[]}, HoldPattern["key" -> Association[]]] // Trace

(* {{{{Association[], <||>}, "key" -> <||>, "key" -> <||>},
{"key" -> <||>}}, Cases[{"key" -> <||>}, HoldPattern["key" -> Association[]]], {}} *)


We see that Association[] gets evaluated to <||>, which as Leonid states is not a normal expression and so will not match Association[]. As I suggested in the comments, I think the right approach in this and similar situation where an evaluation might occur with Association[], is to use Verbatim:

Cases[{"key" -> Association[]}, Verbatim["key" -> Association[]]]

(* {"key" -> <||> } *)


If you look at the Trace of the expression, you'll see why it matched.

Cases[{"key" -> Association[]}, Verbatim["key" -> Association[]]] // Trace


Verbatim allows its input to also evaluate, hence both expressions now look the same: "key" -> <||>, hence the match. Finally, if for some reason you really want to use HoldPattern, then I suggest wrapping your expression in Unevaluated:

Cases[Unevaluated[{"key" -> Association[]}], HoldPattern["key" -> Association[]]]

(* {"key" -> <||> } *)

• Thank you. It is quite clear now. – rmagno Apr 19 '16 at 17:08
• @paideia. You're welcome, glad I could help clarify things. – RunnyKine Apr 19 '16 at 17:16
• Just wondering: how to match _ -> Association[] (using Unevaluated is not an option)? – rmagno Apr 19 '16 at 17:33
• @paideia. Unevaluated works for me. Cases[Unevaluated[{_ -> Association[]}], HoldPattern[_ -> Association[]]] – RunnyKine Apr 19 '16 at 17:58