0
$\begingroup$

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}}

$\endgroup$
1
  • 3
    $\begingroup$ Use RuleDelayed. a1/.{x_Integer,y_Integer} :> {x,a2[[y]]}. $\endgroup$ Jun 7, 2019 at 18:04

1 Answer 1

2
$\begingroup$

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 (->).

$\endgroup$

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.