Pieces of Pi

```13:36	shortcircuit	http://rosettacode.org/wiki/Pi
13:37	* shortcircuit	things Perl6 should implement that task as a sequence.
13:37	shortcircuit	*thinks
```

Well, can’t turn down a challenge like that.

The task is to create a program to continually calculate and output the next digit of pi. The program should continue forever (until it is aborted by the user) calculating and outputting each digit in succession. The output should be a decimal sequence beginning 3.14159265 …

First, research.

Ah, not only is it a cool project, but it is a chance to rework some Haskell code into Perl 6. Shiny!

So, it looks like the core of their approach is this function:

```> stream :: (b->c) -> (b->c->Bool) -> (b->c->b) -> (b->a->b) ->
>           b -> [a] -> [c]
> stream next safe prod cons z (x:xs)
>   = if safe z y
>     then y : stream next safe prod cons (prod z y) (x:xs)
>     else stream next safe prod cons (cons z x) xs
>       where y = next z
```

You know, some algorithms make more sense when they are made recursive. Maybe it’s just because I’m not a hardcore functional programmer, but in this case recursion mostly serves to obfuscate the code. Here’s my attempt to rewrite it in Perl 6:

```sub stream(&next, &safe, &prod, &cons, \$z is copy, @x is copy) {
gather loop {
my \$y = next(\$z);
if safe(\$z, \$y) {
take \$y;
\$z = prod(\$z, \$y);
} else {
\$z = cons(\$z, @x.shift)
}
}
}
```

To my mind, even though this is longer, it’s vastly clearer. There is one major problem, however: it doesn’t actually work. That `@x is copy` there is not guaranteed to work when you pass in an infinite list; and the entire point of this routine is to pass in infinite lists! I don’t know of a graceful way to handle this in Perl 6. This next works:

```sub stream(&next, &safe, &prod, &cons, \$z is copy, @x) {
my \$x-list = @x.iterator.list;
gather loop {
my \$y = next(\$z);
if safe(\$z, \$y) {
take \$y;
\$z = prod(\$z, \$y);
} else {
\$z = cons(\$z, \$x-list.shift)
}
}
}
```

It feels like there should be some more automatic way to do that in p6. Maybe something like “@x is ro-iterator”? (Yeah, that’s an ugly name.)

Update: Ugly `&`s deleted from the sub bodies at moritz_++’s suggestion.