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

Here is my code.

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


The pop-up message ReplaceRepeated::rrlim suggests that this rule can be applied an infinite number of times.

I am supposed to get {Sqrt,Sqrt,Sqrt,Sqrt,Sqrt,0.09}

What's wrong with my code here?

• Hint: After the first pass, what is the head of the first list element's (Sqrt) contents? – ciao Feb 29 at 10:16
• @ciao, Power. How to make it work ? {Sqrt,Sqrt,Sqrt,Sqrt,Sqrt,0.09} – kile Feb 29 at 10:18
• One way might be {y : Power[_, _] -> y, x_Integer -> Sqrt[x]} for the rules. More importantly, do you see why the example evaluates infinitely? – ciao Feb 29 at 10:20
• @ciao,x_Integer still assumes Sqrt and Sqrt are Integer. – kile Feb 29 at 10:26
• Perhaps a better response to @OkkesDulgerci would be to point out that his code changes 9 to 3, not to Sqrt as desired. – Michael E2 Feb 29 at 14:36

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, Sqrt, Sqrt, Sqrt, Sqrt, 0.09}


• Very nice solution, exactly as was asked in OP. Maybe one can add that some confusion arises due to the fact that Replace has levelspec option, whereas ReplaceAll and ReplceRepeated---no. – yarchik Mar 1 at 9:16
• A slight generalization: list //. {x_Integer :> Sqrt[x], skip_?NumericQ :> With[{x = Simplify[skip]}, If[IntegerQ[x], Sqrt[x], skip]]}. In case other numeric expression are in the original list. – Michael E2 Mar 1 at 18:04

I think the proper answer here is to use FixedPoint, because //. dives in to the expression. Sqrt 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.

• Can you please point to the place in the documentation where it is written that //. should dive into subexpressions. – yarchik Feb 29 at 11:28
• It is basically doing /. repeatedly until it doesn't change any more. The documentation of /. (ReplaceAll). Which has as first line: applies a rule or list of rules in an attempt to transform each subpart of an expression expr. – SHuisman Feb 29 at 11:30
• @yarchik "expr//.rules effectively applies /. repeatedly, until the results it gets no longer change." (Docs for ReplaceRepeated) See also the documentation for the error message – Michael E2 Feb 29 at 14:38
• @MichaelE2 Why then this {2, 9, 3, 16, 81, 0.09} //. {x_ /; (Head[x] == Integer) -> Sqrt[x]} does not work? Sorry, if it is something obvious. – yarchik Feb 29 at 18:12
• it works, but again, it dives deeper in to the expression because you're using //. (or /.) – SHuisman Feb 29 at 20:54