FunctionalPerl
view release on metacpan or search on metacpan
t/perl/weaken-coderef view on Meta::CPAN
#!/usr/bin/env perl
# Copyright (c) 2015-2020 Christian Jaeger, copying@christianjaeger.ch
# This is free software. See the file COPYING.md that came bundled
# with this file.
use strict;
use warnings;
use warnings FATAL => 'uninitialized';
use Test::Requires qw(BSD::Resource);
import BSD::Resource;
use Scalar::Util "weaken";
use FP::Carp;
sub rss {
@_ == 0 or fp_croak_arity 0;
(BSD::Resource::getrusage(BSD::Resource::RUSAGE_SELF()))[2]
}
sub naturals {
my $f;
$f = sub {
my ($n) = @_;
my $f = $f;
sub {
if ($n > 0) { [$n, &$f($n - 1)] }
else {
undef
}
}
};
my $f_ = $f;
weaken $f;
goto &$f_;
}
sub stream_sum {
my ($s) = @_;
#weaken $_[0];
# ^ not necessary here, since, unlike with FP::Lazy::Promise,
# resulting value is not saved in its 'generating container'
my $tot = 0;
LP: {
if (my $fs = &$s) {
($tot, $s) = ($$fs[0] + $tot, $$fs[1]);
goto LP;
} else {
$tot
}
}
}
@ARGV == 2 or die "usage: $0 n N";
my ($n, $N) = @ARGV;
my $start = rss;
my $res;
for (1 .. $N) {
my $ns = naturals $n;
$res = stream_sum $ns;
}
print $res, "\n";
my $end = rss;
if (($end - $start) / $start > 1.5) {
die "leaked: $start .. $end";
}
( run in 1.868 second using v1.01-cache-2.11-cpan-0d23b851a93 )