[Question]
  [
## The task
Write a program or function that given three strings `A, B, C` produces an output string where each instance of `B` in `A` has been recursively substituted with `C`.
Recursively substituting means repeating a substitution where at each step all non-overlapping instances of `B` in `A` (chosen greedily from left to right) are replaced with `C` until `B` is no more contained in `A`.
## Input/Output
* You may use any of the [default methods for I/O](https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods?answertab=votes).
* Strings will contain only printable ASCII characters (and may contain *any* of them) .
* `B` will never be an empty string, while `A` and `C` might be.
* Strings are to be considered plaintext, you can't for example treat `B` as a Regex pattern.
* Some combinations of inputs will never terminate. Your program can do anything in those cases.
## Test cases
These are in the format: `A/B/C\nOutput`
```
Hello, world!/world!/PPCG
Hello, PPCG
Uppercase is up/up/down
Uppercase is down
ababababa/aba/ccc
cccbcccba
delete/e/{empty string}
dlt
{empty string}/no/effect
{empty string}
llllrrrr/lr/rl
rrrrllll
+-+-+-+/+-+/+
+
ababababa/aba/bada
badabbadbada
abaaba/aba/ab
abb
((())())())/()/{empty string}
)
```
Examples that don't terminate:
```
grow/ow/oow
loop/lo/lo
```
  
[Answer]
# [Python 2](https://docs.python.org/2/), 43 bytes
```
lambda s,*l:eval('s'+'.replace(*l)'*len(s))
```
[Try it online!](https://tio.run/nexus/python2#fYoxCoAwEAR7X2G3uSg@QPAnNpcYQVhFEvH7MaKFlbMwzc48jJm6uknr1Fr24VQaJDToYtipPhhLgWXYTBLJe1y2o54N1L1Di8dOJ4VUP4X3/huwEAvl4a1ISL4A "Python 2 – TIO Nexus")
Evaluates a string of the form
```
s.replace(*l).replace(*l).replace(*l) ...
```
To reach a fixed point if one exists, it suffices to do replacements equal to the length of the original string.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 2 bytes
```
`:
```
[Try it online!](https://tio.run/nexus/05ab1e#@59g9f9/tFJiEhQq6SgoQank5GSlWAA "05AB1E – TIO Nexus")
**Explanation**
```
`    # split input to stack
 :   # replace (until string doesn't change)
```
This could be `:` for **1 byte** if we didn't have to deal with empty strings.
[Answer]
# ES6 (Javascript), ~~47~~, 43 bytes
* Saved 4 bytes using currying (Thanks @Neil !)
**Golfed**
```
c=>b=>R=a=>(x=a.split(b).join(c))==a?x:R(x)
```
**Try It**
```
Q=c=>b=>R=a=>(x=a.split(b).join(c))==a?x:R(x)
function doit() {
  console.log(Q(C.value)(B.value)(A.value));
}
```
```
A: <input type="text" value="abaaba" id="A"/> B: <input type="text" value="aba" id="B"/> C: <input type="text" value="ab" id="C"/> <input type="submit" onclick="doit();" value="REPLACE"/>
```
[Answer]
## [Retina](https://github.com/m-ender/retina), 27 bytes
Byte count assumes ISO 8859-1 encoding.
```
+`(.+)(?=.*¶\1¶(.*))
$2
G1`
```
Input should be linefeed-separated.
[Try it online!](https://tio.run/nexus/retina#XYyxCsIwFEX39xURFNJG@6i7ODjUsSBuDkmTVxAeTUgr/bN@QH8s1tLJe@7hbvcgHxqT0rJQmbxeinyeXuU8ySLPMtifoSp1Sndi9kcx@shuh9vU9a2CZwgUrelJvHvxCbjU@bED02zgT2stOGIaCAkBO4/UtmQH4CVxCXLEyKBOK7j699EYZ74 "Retina – TIO Nexus") (For convenience, uses a test-suite input format where each line is a slash-separated test cases.)
[Answer]
**C#, 44 Bytes**
**Short Version:**
```
r=(a,b,c)=>a==(a=a.Replace(b,c))?a:r(a,b,c);
```
**Example Program:**
```
using System;
namespace ConsoleApplication1
{
    class Program
    {
    static void Main(string[] args)
        {
            Func<string, string, string, string> r = null;
            r=(a,b,c)=>a==(a=a.Replace(b,c))?a:r(a,b,c);
            Action <string, string, string, string> test =
                (a, b, c, answer) =>
                {
                    var result = r(a, b, c);
                    Console.WriteLine("A: \"{0}\"\r\nB: \"{1}\"\r\nC: \"{2}\"\r\nResult: \"{3}\"\r\n{4}\r\n\r\n",
                        a, b, c, result, result == answer ? "CORRECT" : "INCORRECT"
                        );
                };
            test("Hello, world!", "world!", "PPCG", "Hello, PPCG");
            test("Uppercase is up", "up", "down", "Uppercase is down");
            test("ababababa", "aba", "ccc", "cccbcccba");
            test("delete", "e", "", "dlt");
            test("", "no", "effect", "");
            test("llllrrrr", "lr", "rl", "rrrrllll");
            test("+-+-+-+", "+-+", "+", "+");
            test("ababababa", "aba", "bada", "badabbadbada");
            test("abaaba", "aba", "ab", "abb");
            test("((())())())", "()", "", ")");
            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }
    }
}
```
**Explanation:**
The function is written as a tail recursive expression, avoiding the return keyword and curly brackets by exploiting the following:
* An assignment within parenthesis returns the value assigned
* The left side of the equality check will be evaluated before the right side assignment, allowing us to compare before/after inline, and still access the result
This lets us keep it to a single statement.
**EDIT:**
Went back to omitting the type of function r, since that appears to be acceptable. With type declaration using arrays, it is 68 characters. Without, it is 44 characters.
[Answer]
## Ruby, 29 bytes
```
->a,b,c{1while a.gsub! b,c;a}
```
Given 3 arguments, apply substitution to the first until there is nothing to substitute anymore.
### Explanation
* `1` before the `while` is simply a nop
* `gsub!` returns the string or `nil`if no substitution occurred
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 15 bytes
```
@¥(U=UqV qW}a@U
```
[Test it online!](http://ethproductions.github.io/japt/?v=1.4.4&code=QKUoVT1VcVYgcVd9YUBV&input=IistKy0rLSstKyIgIistKyIgIisi)
### How it works
```
@¥(U=UqV qW}a@U  // Implicit: U, V, W = input strings
            a@U  // Return the first non-negative integer mapped by the function X => U
@          }     // that returns truthily when mapped through this function:
     UqV qW      //   Split U at instances of V, and rejoin with W.
  (U=            //   Set U to this new value.
 ¥               //   Return (old U == new U). This stops the loop when U stops changing.
                 // Implicit: output result of last expression
```
Japt has a recursive-replace built-in, but it sees the first input as a regex. If the inputs were guaranteed to only contain alphanumeric characters this three-byte solution would work:
```
eVW
```
If the input were allowed to contain any char except `^`, `\`, or `]`, this 12-byte solution would be valid instead:
```
eV®"[{Z}]"ÃW
```
[Answer]
## C#, ~~33~~ 49 bytes
Probably, one of the smallest snippets written in C#... And since `Replace` is native to the `string` struct, there's no need for `using`s ( *At least not on VS built-in feature, C# Interactive...* )
Also, since `B` always has a value, the code doesn't need any validations.
---
**Golfed**
```
(a,b,c)=>{while(a!=(a=a.Replace(b,c)));return a;}
```
---
**Ungolfed**
```
(a, b, c) => {
    while( a != ( a = a.Replace( b, c ) ) );
    return a;
}
```
---
**Full code**
```
using System;
namespace Namespace {
    class Program {
        static void Main( string[] args ) {
            Func<string, string, string, string> func = (a, b, c) => {
                // Recursively ( now truly recursive ) replaces every 'b' for 'c' on 'a',
                // while saving the value to 'a' and checking against it. Crazy, isn't it?
                while( a != ( a = a.Replace( b, c ) ) );
                return a;
            };
            int index = 1;
            // Cycle through the args, skipping the first ( it's the path to the .exe )
            while( index + 3 < args.Length ) {
                Console.WriteLine( func(
                    args[index++],
                    args[index++],
                    args[index++]) );
            }
            Console.ReadLine();
        }
    }
}
```
---
**Releases**
* **v1.1** - `+19 bytes` - Fixed solution not being recursive.
* **v1.0** - `33 bytes` - Initial solution.
[Answer]
# Processing, ~~75~~ 72 bytes
```
void g(String a,String[]s){for(;a!=(a=a.replace(s[0],s[1])););print(a);}
```
Prints the results. Call it like `g("llllrrrr", new String[]{"lr","rl"});`
```
void Q110278(String a, String[]s){             //a is the string to be replaced
                                               //s is the array containing the subsitution
  for(; a!=                                    
            (a = a.replace(s[0], s[1])) ;);
  //for-loop where we continuously perform substitution on a
  //until a is equal to substituted a
  //at the end, print the final version of a
  print(a);
}
```
[Answer]
# Mathematica, ~~35~~ 32 Bytes
```
#//.x_:>StringReplace[x,#2->#3]&
```
Arguments given as a sequence. Never terminates for `grow` example, returns `loop` for `loop` example. Three bytes off thanks to Martin's suggestion.
[Answer]
## Pyke, 6 bytes
```
hVQtX:
```
[Try it here!](http://pyke.catbus.co.uk/?code=hVQtX%3A&input=%22llllrrrr%22%2C%22rl%22%2C%22lr%22&warnings=0)
[Answer]
## [///](https://esolangs.org/wiki////), 3 bytes
```
///
```
Put string B after the first slash, C after the second and A at the end, ie:
```
/<B>/<C>/<A>
```
[Try it online!](https://tio.run/nexus/slashes#@6@fU6RflKOfAwRFQPD/PwA "/// – TIO Nexus")
[Answer]
## JavaScript (Firefox 48 or earlier), 43 bytes
```
c=>b=>g=a=>a==(a=a.replace(b,c,'g'))?a:g(a)
```
Takes arguments curried in reverse order. Firefox used to have a non-standard third parameter to `replace` which specified regexp flags. This parameter was removed in Firefox 49.
[Answer]
# SmileBASIC, ~~72~~ 68 bytes
```
I=0DEF R A,B,C
I=INSTR(A,B)?A*(I<0)A=SUBST$(A,I,LEN(B),C)R A,B,C
END
```
One of the rare cases where making a function is actually SHORTER in SmileBASIC.
[Answer]
## Javascript 130 bytes
```
f=(a,b,c)=>a.indexOf(b)<0?a:f(eval("a.replace(/"+b.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&")+"/g,c)"),b,c)
```
Javascript will only replace all simultaneously if you give it a regex. In order to make this regex work for all values, all characters that are used for regex need to be replaced with the escaped version. Finally, the replace is evaluated to replace all instances of B in A with C and passing that back around to the function again.
[Answer]
# q, 15 bytes
```
{ssr[;y;z]/[x]}
```
Example:
```
q){ssr[;y;z]/[x]}["llllrrrr";"lr";"rl"]
"rrrrllll"
```
[link](https://kx.com/download/) to interpreter download
Explanation: [ssr](http://code.kx.com/wiki/Reference/ssr), [/ (converge)](http://code.kx.com/wiki/Reference/Slash#converge)
[Answer]
# Cheddar, 37 bytes
```
(a,b,c)f->a has b?f(a.sub(b,c),b,c):a
```
On phone so TIO link is a bit difficult to add. Basically uses recursion while checking is b is in a. Solution could of been `(a,b,c)->a.sub(Regex{b,"cr"},c)` but doesn't work for some reason.
[Answer]
# [Perl 6](https://perl6.org), 40 bytes
```
{$^b;$^c;($^a,{S:g/$b/$c/}...*eq*)[*-1]}
```
[Try it](https://tio.run/nexus/perl6#bVHNThsxEL7PU0zRit0NiR04UIkVl7aUIiEUUXpqGmnXOwELx15sB4jSPFlvfaee6XgbDkS1Pfb8fJ4Zf/5wdn5xhXoOiNlgcnZ9KZRbdNqQF7ZekDAK6QFzX98vW5czan//P9BH8kE7iw3NnSd8PBofvhfjI1gzNtQrzG/udMAnbQxaF/HJ@XtUzntS0axQW9wmCOjmeN3Xwgl5g8fYee08RofxjvAzNZhyoydDdaC8ei3gab4M2t4mpF/aPkDPOlawgWXglo6FqnrthkKs8OzqE7bO0iiyyfcqmHi30IGEtsXhuBRczp7gOuXYwGKF@8q1hKcv62zWVNlMVUU2q4frrye3MmtkpuRGCDGgh0H5fTA6/LF5yQYXV8KaEb/uFPemdmr3KmB60GhLoSgxkcOJi6m2wyk9d0wGtSWDRY/4/UuEzuhY5DIvk7FsAhtrWnRxhSF67nqTD/O8TG9lelODxU9tyyG@Zhsyt@JShyg6ZpO5ePlCxrhh@gHTvpPbYzL5eA7bSK/Dt44vKGY4JV52klfrnuxbf@@ButlOmUQpBSxNkhqg5X@KJElCayLA2@aldZLmc@50JwBgeHge0njpDSQ1uQAORv2UvcDBbvmmbmtIW8NbbyTAa7Ru2GoAiqIoy39LFqXcKV7@sW6kanVHfwE "Perl 6 – TIO Nexus") (if tio.run gets updated)  
[Try an altered version](https://tio.run/nexus/perl6#XVDNbtswDL7zKdTCqKXWltrLDjV62oZtwFAEWHdaFsCSmVaAIhmW0h943ov11nfaOaW89NCQ/Ch@JEUR2kZk9x@kaWBL0Q3G1LDP159YFzzWiaj1tw0shrCxEaX1/OJcyHSH/pKN@GjTBJsndmJCh@xqNxYr3RQr0/Bi1Vbj3x@Xt6rQqjBqklKOR5vMJvHrtL74Pe2K02/X0rvaenbFjpd@6Y8bWIeBOesxcsFGYIym86X11RIfezQJO0HNcu54eZaxdzbxUpUik62OREbc9OmJxTTQ6lNZlaVoaJCNLG/J/1gvKvY2rWLWy@82Jtnj4BqYdl/RuVCxhzC47kjtj8Xi4xfYV@YYfvZ0wbT0ZzR42yuyLjz49/k5A63eq8owxgBBZ7QAHTpMqFBB5xLA@@WVDwrXa9r0oADgSAYS5QY1OMhhTgGc1bOqGXB2@Lxuuxay0@Rmkhveqq0mpgE450L8N8WFOnhc/POhNq25w1c "Perl 6 – TIO Nexus")
## Expanded:
```
{
  $^b;           # declare second parameter ( not used here )
  $^c;           # declare third parameter  ( not used here )
  (
    $^a,         # declare first parameter, and use it to seed the sequence
    {S:g/$b/$c/} # replace globally
    ...          # keep doing that
    * eq *       # until there are two that match
  )[*-1]
}
```
[Answer]
# PHP, 46 bytes
```
function g($a,$b,$c){echo strtr($a,[$b=>$c]);}
```
[Answer]
# PHP, 102 bytes
```
list($n,$s,$a,$b)=$argv;$f=str_replace($a,$b,$s);while($s!=$f){$s=$f;$f=str_replace($a,$b,$s);}echo$f;
```
[**Test cases (functional)**](https://eval.in/739433)
[**Test case with loop error**](https://eval.in/739436)
[Answer]
# Java - 157 bytes
```
String r(String f){if(f.length()<1)return "";String[]x=f.split("/");if(x[0].contains(x[1]))return r(x[0].replace(x[1],x[2])+'/'+x[1]+'/'+x[2]);return x[0];}
```
For empty input it returns an empty string.
Crashes with `StackOverflowException` error when `B` is empty or it is fed with data like this `A/A/A`.
How it works:
```
r("ABCD/A/F") returns value of r("FBCD/A/F") which returns FBCD
If there is no more characters to be replaced it returns the final output
```
Ungolfed code code with comments:
```
String r (String f) {
    if(f.length() < 1)
        return ""; // For empty input return empty output
    String[] x = f.split("/"); // Get all 3 parameters
    if (x[0].contains(x[1])) // If input contains replaced value
        return r(x[0].replace(x[1],x[2])+'/'+x[1]+'/'+x[2]); // Return value of r() with one character replaced
    return x[0]; // If nothing to replace return the output(modified input)
}
```
[Answer]
# AutoHotkey, 87 bytes
```
StringCaseSense,On
Loop{
IfNotInString,1,%2%,Break
StringReplace,1,1,%2%,%3%
}
Send,%1%
```
`%1%`,`%2%`, and `%3%` are the first 3 arguments passed to a function  
If a function expects a variable argument, the `%`s are dropped  
]