FunctionalPerl
view release on metacpan or search on metacpan
},
"runtime" : {
"recommends" : {
"B::Deparse" : "0",
"Clone" : "0",
"Encode" : "0",
"Eval::WithLexicals" : "0",
"JSON" : "0",
"LWP::UserAgent" : "0",
"Method::Signatures" : "0",
"PadWalker" : "0",
"Term::ReadLine::Gnu" : "0",
"Text::Markdown" : "0"
},
"requires" : {
"Digest" : "0",
"File::Path" : "0",
"Getopt::Long" : "0",
"Import::Into" : "0",
"Math::BigInt" : "0",
"NEXT" : "0",
- t-slow
- t-extra
recommends:
B::Deparse: '0'
Clone: '0'
Encode: '0'
Eval::WithLexicals: '0'
JSON: '0'
LWP::UserAgent: '0'
Method::Signatures: '0'
PadWalker: '0'
Term::ReadLine::Gnu: '0'
Text::Markdown: '0'
requires:
Digest: '0'
File::Path: '0'
Getopt::Long: '0'
Import::Into: '0'
Math::BigInt: '0'
NEXT: '0'
PerlIO::utf8_strict: '0'
Makefile.PL view on Meta::CPAN
repository => {
type => 'git',
url => "https://github.com/pflanze/functional-perl.git",
web => "https://github.com/pflanze/functional-perl",
},
},
prereqs => {
runtime => {
recommends => {
"Term::ReadLine::Gnu" => 0,
"PadWalker" => 0,
"B::Deparse" => 0,
"Eval::WithLexicals" => 0,
#"Sub::Call::Tail" => 0, currently broken
"Method::Signatures" => 0,
#"Function::Parameters" => 0, not used anymore
# examples/:
"JSON" => 0,
does various details differently.
Please ask [me](http://leafpair.com/contact) if you'd like to meet up
in London, Berlin or Switzerland to get an introduction in person.
## Dependencies
* to use `bin/perlrepl`, `bin/fperl` or the repl in the intro and
examples scripts interactively, `Term::ReadLine::Gnu` and
`PadWalker` (and optionally `Eval::WithLexicals` if you want to use
the :m/:M modes, and `Capture::Tiny` to see code definition location
information and `Sub::Util` from `Scalar::List::Utils` to see
function names when displaying code refs.)
* to run the test suite: `Test::Requires`
* to run all the tests (otherwise some are skipped): in addition to
the above, Perl version >= 5.020, `Test::Pod::Snippets`,
`BSD::Resource`, `Method::Signatures`, `Sub::Call::Tail`,
`Text::CSV`, `DBD::CSV`, `Text::CSV`, `URI`, `Text::Markdown`,
docs/howto.md view on Meta::CPAN
$s->for_each (sub { print "> ".$_[0]."\n" });
$s = xfile_lines $path; # reopen the file from the start
$s->for_each (sub { print "again: > ".$_[0]."\n" });
}
This is probably the ugliest part when programming functionally in
Perl. Perhaps the interpreter could be changed (or a lowlevel module
written) so that lexical variables are automatically cleared upon
their last access (and something like @_ = () is enough to clear it from
the perl calling stack, if not automatic). An argument against this is
inspection using debuggers or modules like `PadWalker`, so it will
have to be enabled explicitely (lexically scoped).
### Stack memory and tail calls
Another, closely related, place where the perl interpreter does not
release memory in a timely (enough for some programs) manner, are
subroutine calls in tail position. The tail position is the place of
the last expression or statement in a (subroutine) scope. There's no
need to remember the current context (other than, again, to aid
docs/intro.md view on Meta::CPAN
- Run it from somewhere in your program by using `use FP::Repl;` and
calling `repl;`.
- Register the repl to be run upon encountering uncaught exceptions
by adding `use FP::Repl::Trap;` somewhere to your code.
- Run the [bin/perlrepl](../bin/perlrepl) script, which takes the
`-M` option like perl itself to load modules of your choice. Or
[bin/fperl](../bin/fperl) which calls the repl with most Functional
Perl modules preloaded.
You need to install `Term::ReadLine::Gnu` and `PadWalker` (and
`Capture::Tiny` to see code definition location information and
`Sub::Util` to see function names when displaying code refs) to use
the repl. Once you've done that, from the shell run:
$ cd functional-perl
$ bin/fperl
Or if you installed the project, just
$ fperl
examples/fibs view on Meta::CPAN
use Cwd 'abs_path';
our ($mydir, $myname);
BEGIN {
my $location = (-l $0) ? abs_path($0) : $0;
$location =~ /(.*?)([^\/]+?)_?\z/s or die "?";
($mydir, $myname) = ($1, $2);
}
use lib "$mydir/../lib";
use Chj::TEST use => "PadWalker";
use FP::List ":all";
use FP::Ops ":all";
use FP::Lazy ":all";
use FP::Stream ":all";
use FP::BigInt;
use Chj::Backtrace;
# fibs :: [Integer]
# fibs = 1:1:zipWith (+) fibs (tail fibs)
lib/Chj/Serialize.pm view on Meta::CPAN
package Chj::Serializable::Closure;
use FP::Struct ["env", "code_id"], 'FP::Struct::Show', 'FP::Abstract::Pure';
_END_
}
{
package Chj::Serialize::Closure;
use PadWalker qw(closed_over set_closed_over);
use FP::Repl::WithRepl qw(WithRepl_eval);
use B::Deparse;
use FP::Predicates ":all";
our $deparse = B::Deparse->new("-p", "-l", "-q");
use FP::Struct [
[\&is_hash, "_closure_generator_code_to_id"],
[\&is_hash, "_id_to_closure_generator_code"],
[\&is_hash, "_id_to_closure_generator"],
lib/FP/Repl/Dependencies.pm view on Meta::CPAN
use strict;
use warnings;
use warnings FATAL => 'uninitialized';
use Term::ReadLine;
$Term::ReadLine::Gnu::VERSION
or die "dependency Term::ReadLine::Gnu not present";
# now also depend on PadWalker etc.
require FP::Repl::Repl;
1
lib/FP/Repl/Repl.pm view on Meta::CPAN
my $context = wantarray ? "list" : "scalar"; ## no critic
$lp->context($context);
WithRepl_eval { $lp->eval($allcode) }
} else {
my @v = sort keys %{ $maybe_lexicals // {} };
my $allcode
= $prelude
. (@v ? 'my (' . join(", ", @v) . '); ' : '') . 'sub {'
. $code . "\n" . '}';
my $thunk = &WithRepl_eval($allcode) // return;
PadWalker::set_closed_over($thunk, $maybe_lexicals)
if defined $maybe_lexicals;
WithRepl_eval { &$thunk() }
}
}
sub _completion_function {
my ($attribs, $package, $lexicals) = @_;
sub {
my ($text, $line, $start, $end) = @_;
my $part = substr($line, 0, $end);
lib/FP/Repl/StackPlus.pm view on Meta::CPAN
#
=head1 NAME
FP::Repl::StackPlus - Stack including lexical variables
=head1 SYNOPSIS
my $stack = FP::Repl::StackPlus->get($numbers_of_levels_to_skip);
# same as FP::Repl::Stack, but frames also have `lexicals`, a hash
# as delivered from PadWalker
=head1 DESCRIPTION
I'm pretty sure this is still re-inventing some wheel...
=head1 SEE ALSO
L<FP::Repl::Stack>, L<PadWalker>
=head1 NOTE
This is alpha software! Read the status section in the package README
or on the L<website|http://functional-perl.org/>.
=cut
package FP::Repl::StackPlus;
lib/FP/Repl/StackPlus.pm view on Meta::CPAN
# stackframe!
sub equal {
my $s = shift;
my ($v) = @_;
die "not implemented (yet?)";
}
_END_
}
use PadWalker qw(peek_my);
# TODO/XXX: see comments in commit 'StackPlus: don't die in peek_my
# (HACK)'; this should be replaced with something clean /
# investigated.
our $maybe_peek_my = sub {
my ($skip) = @_;
my $res;
if (
eval {
$res = peek_my($skip);
t/pod_snippets.t view on Meta::CPAN
use strict;
use warnings;
use warnings FATAL => 'uninitialized';
use lib "./meta";
use FunctionalPerl::TailExpand;
use FunctionalPerl::ModuleList;
use FunctionalPerl::Dependencies 'module_needs';
use Chj::Backtrace;
use Chj::xperlfunc ":all";
use Test::Requires qw(Test::Pod::Snippets PadWalker FP::Repl::AutoTrap);
# ^ PadWalker only to give a more proper error message to the user; sigh.
use Test::More;
use FP::Repl::WithRepl qw(withrepl WithRepl_eval);
use FP::Carp;
sub myeval {
@_ == 1 or fp_croak_arity 1;
my ($str) = @_;
if (FP::Repl::AutoTrap::possibly_activate) {
withrepl {
&WithRepl_eval($str)
( run in 0.989 second using v1.01-cache-2.11-cpan-05444aca049 )