FunctionalPerl

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

      },
      "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",

META.yml  view on Meta::CPAN

    - 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,

README.md  view on Meta::CPAN

    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 )