Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

A "Fun"ctional Attempt

by withering (Monk)
on Jun 04, 2015 at 08:14 UTC ( [id://1129033]=perlmeditation: print w/replies, xml ) Need Help??

Perl is somewhat functional itself -- if the concept, "functional", which we're talking about, mainly means using functions as first-class objects instead of wiping almost all side effects out. However, lacking of sugar such as useful prototypes, pattern matching, or list comprehensions makes Perl less attractive in some functional situation (for fun, perhaps).

There are a few attempts I made to achieve a better experience when programming perl for fun. For example:

#!/usr/bin/env perl use HOI::Comprehensions; use HOI::Match; sub slowsort { HOI::Match::pmatch( 'nil' => sub { [] }, 'pivot :: unsorted' => sub { my $left = HOI::Comprehensions::comp( sub { $x }, x => $un +sorted )->( sub { $x <= $pivot } ); my $right = HOI::Comprehensions::comp( sub { $x }, x => $u +nsorted )->( sub { $x > $pivot } ); [ @{slowsort($left->force)}, $pivot, @{slowsort($right->fo +rce)} ] }, )->(@_) } my $res = slowsort [3, 4, 1, 2, 5, 6]; print @$res, "\n";

where HOI::Match and HOI::Comprehensions are used to give a simple description of the whole computation. It should be noted that the code is not so strict since it assumes the existence of local variables. Scopes are dynamic, and bound variables are bound by names, as the ones in a typical lambda calculus theory.

It is still not clear to me whether such sugar ideas are welcomed or not. Any suggestion or criticism is welcomed. I am looking forward for your replies.

Replies are listed 'Best First'.
Re: A "Fun"ctional Attempt
by Athanasius (Archbishop) on Jun 04, 2015 at 09:43 UTC

    Hello withering,

    It should be noted that the code is not so strict since it assumes the existence of local variables.

    Package global variables, actually. And it’s easy to make it work under strict:

    use strict; use warnings; use HOI::Comprehensions; use HOI::Match; sub slowsort { HOI::Match::pmatch ( 'nil' => sub { [] }, 'pivot :: unsorted' => sub { our ($x, $unsorted, $pivot); my $left = HOI::Comprehensions::comp( sub { $x }, x => $u +nsorted )->( sub { $x <= $pivot } ); my $right = HOI::Comprehensions::comp( sub { $x }, x => $u +nsorted )->( sub { $x > $pivot } ); return [ @{slowsort($left->force)}, $pivot, @{slowsort($ri +ght->force)} ]; }, )->(@_) } my $res = slowsort [3, 4, 1, 2, 5, 6]; print @$res, "\n";

    Output:

    19:35 >perl -c 1262_SoPW.pl 1262_SoPW.pl syntax OK 19:37 >perl 1262_SoPW.pl 123456 19:37 >

    I see from that you are the author of the HOI::Comprehensions and HOI::Match modules. For the benefit of those of us who don’t know as much as we’d like about functional programming, perhaps you could give some explanation of what the code is doing, and of its advantages over equivalent code written in the imperative or object oriented paradigms?

    Thanks,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thanks for reply and the workaround under "use strict". The solution works well, although it is a little different from my own consideration, which hopes that those variables need no declaration.

      The demo code give such an algorithm - it looks like quicksort, but it's simpler and much slower. The function takes a list, taking its first element as a "pivot". Then the remaining list (tail of the list), namely "unsorted", is divided into two sub-lists: one contains elements which are no bigger than the pivot, and the other contains elements which are bigger than the pivot. The same process is applied to the two sub-lists unless the argument list is empty.

      Quicksort is much faster, for it costs less time when dividing the original list. In addition, the strategy to choose a pivot is sometimes ingenious.

      As for advantages of functional style over other paradigms, my opinion is that most of the time a piece of code which follows functional paradigm runs under a heavier burden, perhaps from its runtime mainly. However, there are reasons for following such discipline:

      1. To think from a different perspective, which tells one to focus on functions and their composition, encourages one to write operators (i.e. functions that return functions) as glue between operations. Thus, some achievement in reusability could be somewhat reached.

      2. More or less, such discipline encourages one to write smaller functions with clearer boundaries.

      I myself usually consider functional paradigm able to be graceful. It's actually not always graceful, however.

Re: A "Fun"ctional Attempt
by Laurent_R (Canon) on Jun 04, 2015 at 18:02 UTC
    It is not possible to speak about functional programming in Perl without mentioning Mark Jason Dominus's Higher Order Perl (HOP), in my view a fabulous book.

    It is available on line (http://hop.perl.plover.com/book/). I started to read it on line, and very quickly decided that I needed to buy it. And I am very happy that I did buy it. For me, the best IT book that I read in the last 10 years.

      Yes, it is a masterwork about functional paradigm in Perl. It is HOP that introduces me to the discipline.

      I am only attempting to offer some auxiliary tools to make functional programming easier. Whether a piece of code -- even with such tools -- is "functional" depends on its author.

        I must say that I don't fully understand your examples. I need to take more time to study them.

        But looking at what comprehensions are (I only had a very vague idea), it seems to me that it would be possible to implement them with the gather and take functions of Perl 6. And it should not be too difficult to implement a gather and take functionality in pure Perl 5. I think that Damian has implemented a CPAN module doing that. The only difficulty might be to make that really lazy, but combining an iterator and gather and take might do the trick.

        But I'll look further at your modules this week-end (hopefully), this looks interesting.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1129033]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-25 14:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found