Why does {2, 9, 3, 16, 81, 0.09} //. {x_Integer -> Sqrt[x]} evaluate infinite times?

I think the proper answer here is to use FixedPoint, because //. dives in to the expression. Sqrt[2] contains an integer inside so it replaces it over and over.

FixedPoint[Replace[#, x_Integer :> Sqrt[x], {1}] &, {2, 9, 3, 16, 81, 0.09}]

Notice that I specifically said that it should replace at level 1.


The documentation specifically states:

You should be very careful to avoid infinite loops when you use the //. operator. The command x //. x -> x + 1 will, for example, lead to an infinite loop.

Since only the first rule that matches is applied to a given expression you can, as ciao commented, use:

{2, 9, 3, 16, 81, 0.09} //. {skip_Power :> skip, x_Integer :> Sqrt[x]}
{Sqrt[2], Sqrt[3], Sqrt[3], Sqrt[2], Sqrt[3], 0.09}

Recommended reading:

  • How to perform a depth-first preorder traversal of an expression?
  • substitution rules excluding subscripted variables