I believe Stefan R has given the answer to this question in a comment.
As I understand it, these were primarily added due to their convenience in Entity-related queries (via the operator form). See their respective refpages for examples.
The following notable differences exist between the SubsetQ and ContainsAll:
ContainsAll has an operator form, SubsetQ doesn't
ContainsAll has the SameTest option
ContainsAll handles sparse arrays as normal lists, SubsetQ complains about atomic objects.
SubsetQ allows any head, ContainsAll doesn't
SubsetQ[f[1,2,3], f[1,2]]
(* True *)
SubsetQ[f[1, 2, 3], g[1, 2]]
During evaluation of SubsetQ::heads: Heads f and g at positions 1 and 2 are expected to be the same.
(* SubsetQ[f[1, 2, 3], g[1, 2]] *)
ContainsAll[f[1, 2, 3], f[1, 2]]
(* ContainsAll[f[1, 2, 3], f[1, 2]] *)
ContainsAll[association, values] checks for the existence of all values, not key -> value pairs. SubsetQ arguably misbehaves with associations. Demonstration below:
SubsetQ[<|a -> 1, b -> 4|>, <|a -> 1, b -> 4|>]
(* True *)
SubsetQ[<|a -> 1, b -> 4|>, <|a -> 1, c -> 4|>] (* note the different keys *)
(* True *)
SubsetQ[<|a -> 1, b -> 4|>, {1, 4}]
During evaluation of SubsetQ::heads: Heads Association and List at positions 1 and 2 are expected to be the same.
(* SubsetQ[<|a -> 1, b -> 4|>, {1, 4}] *)
ContainsAll does this:
ContainsAll[<|a -> 1, b -> 4|>, <|a -> 1, b -> 4|>]
(* True *)
ContainsAll[<|a -> 1, b -> 4|>, <|a -> 1, c -> 4|>] (* note the different keys *)
(* True *)
ContainsAll[<|a -> 1, b -> 4|>, {1, 4}]
(* True *)
The following similarities exist that are worth pointing out:
- Neither take the multiplicity of elements into account.
Entity-related queries (via the operator form). See their respective refpages for examples. – Stefan R Jul 15 '15 at 15:11