sub zeta(\$s) { [\+] map -> \n { 1 / n**\$s }, 1..* } say zeta(2)[1000]; ##```## sub infix:<+>(Irrational \$x, Irrational \$y) { Irrational.new: gather while True { (state \$n)++; take \$x[\$n] + \$y[\$n]; } } ##``````## sub infix:<==>(Irrational \$x, Irrational \$y) { while True { (state \$n)++; return \$x[\$n] == \$y[\$n]; } } ##``````## package Real; # the accuracy number below is only for display. # It does not affect the (infinite) precision of the numbers. our \$accuracy = 1e-3; use overload '+' => sub { my (\$a, \$b) = map { \$_->() } my (\$x, \$y) = @_; bless sub { sub { \$a->() + \$b->() } }, ref \$x; }, '*' => sub { my (\$a, \$b) = map { \$_->() } my (\$x, \$y) = @_; bless sub { sub { \$a->() * \$b->() } }, ref \$x; }, q{""} => sub { my \$x = shift->(); my \$a = \$x->(); my \$b; while (abs(\$a - (\$b = \$x->())) > \$accuracy) { \$a = \$b; } return "\$b (±\$accuracy)"; }, ; 1; package Test; my \$one = bless sub { sub {1} }, 'Real'; sub Exp { my \$x = shift; bless sub { # Here I use floating points for convenience # but obviously I should use only rationals. my (\$s, \$p, \$n) = (1, 1, 1); sub { \$s += \$p *= \$x / \$n++ } }, 'Real'; } sub Arctan { my \$x = shift; bless sub { # same remark here about the use of floating points my (\$s, \$p, \$n) = (0, 1, -1); sub { \$s += (-1)**++\$n * (\$p *= \$x) / (2*\$n + 1) } }, 'Real'; } print \$one, "\n"; print my \$two = \$one + \$one, "\n"; print my \$three = \$two + \$one, "\n"; print my \$e = Exp(1), "\n"; print \$e + \$one, "\n"; print \$e * \$e, "\n"; print (\$three + \$one) * Arctan(1); ```