This will eventually stop… Given an input string S, print S followed by a non-empty separator in the following way:

Step 1: S has a 1/2 chance of being printed, and a 1/2 chance for the program to terminate.

Step 2: S has a 2/3 chance of being printed, and a 1/3 chance for the program to terminate.

Step 3: S has a 3/4 chance of being printed, and a 1/4 chance for the program to terminate.

…

Step n: S has a n/(n+1) chance of being printed, and a 1/(n+1) chance for the program to terminate.


Notes

The input string will only consist of characters that are acceptable in your language's string type.

Any non-empty separator can be used, as long as it is always the same. It is expected that the separator is printed after the last print of S before the program terminates.

The program has a 1/2 chance of terminating before printing anything.

A trailing new line is acceptable.

Your answer must make a genuine attempt at respecting the probabilities described. Obviously, when n is big this will be less and less true. A proper explanation of how probabilities are computed in your answer (and why they respect the specs, disregarding pseudo-randomness and big numbers problems) is sufficient.


Scoring
This is code-golf, so the shortest answer in bytes wins.
C#, 94 85 bytes

My first answer!

using System;s=&gt;{var r=new Random();for(var i=2;r.Next(i++)&gt;0;)Console.Write(s+" ");}


Previous attempt (I liked that goto):

using System;s=&gt;{var i=2;var r=new Random();a:if(r.Next(i++)&gt;0){Console.Write(s+" ");goto a;}}


Ungolfed:

using System;
class P
{
    static void Main()
    {
        Action&lt;string&gt; f = s =&gt;
        {
            var r = new Random();
            for (var i = 2; r.Next(i++) &gt; 0;) Console.Write(s + " ");
        };

        f("test");

        Console.ReadKey();
    }
}


Note: in C# the Random.Next(N) method returns a nonnegative integer in the [0, N-1] range, so we can just check that the number returned is greater than 0.