# Pattern ReplaceAll warning

Why does the following code give me a warning, but then still work?

a1={{1,2},{3,1}}
a2={"foo","bar"}
a1/.{x_Integer,y_Integer}->{x,a2[[y]]}


After a "Part: The expression y cannot be used as a part specification" warning, it correctly gives this:

{{1,bar},{3,foo}}

• Use RuleDelayed. a1/.{x_Integer,y_Integer} :> {x,a2[[y]]}. – Shredderroy Jun 7 '19 at 18:04

Consider the rule:

a2={"foo", "bar"};
{x_Integer, y_Integer} -> {x, a2[[y]]}


Part::pkspec1: The expression y cannot be used as a part specification.

{x_Integer, y_Integer} -> {x, {"foo", "bar"}[[y]]}

Notice how a2[[y]] tried to evaluate, but issues a message because you can't use y as a part specification. Since Mathematica typically returns inputs back as outputs when things go wrong, when you later substitute values for x and y with your rule application you get:

{{1, {"foo", "bar"}[[2]]}, {3, {"foo", "bar"}[[1]]}}


which can now evaluate because the part specification is an integer.

As Shredderroy says, the proper way to do this is to use RuleDelayed (:>) instead of Rule (->).