http://www.perlmonks.org?node_id=405660


in reply to Re^2: A mini-language for sequences (part 1)
in thread A mini-language for sequences (part 1)

Okay, the title was meant to be inflammatory. Don't read too much into it.

Perl leaves much to be desired as a functional programming language. Not having currying, pattern matching, proper tail recursion, and real garbage collection are limiting, painful even.

What frustrates me most about Perl (from a FP perspective, at least) is the distinction between builtins and user functions. If anyone can tell me how to get around that without writing sub {$_[0] + $_[1]} everywhere, I'd be most grateful.

Update: I realize that this complaint is a bit vague. What I really want to do is take coderefs to builtins and operators and pass them to higher-order functions. To the best of my knowledge, this is not an easy thing to do.

--
Yours in pedantry,
F o x t r o t U n i f o r m

"Anything you put in comments is not tested and easily goes out of date." -- tye

Replies are listed 'Best First'.
Re: Why Perl Is Not My Favourite Functional Programming Language
by iblech (Friar) on Nov 06, 2004 at 17:32 UTC

    When Perl 6 is ready, you will be able to use:

    my $plus_op_subref = \&infix:+; my $not_op_subref = \&prefix:!; say $plus_op_subref.(3, 2); # 5

    not tested ;)

      Some slight tweaking is in order. The backslashes are not needed, since &foo is already a reference in scalar context. You don't need the dot to dereference the routine value either, though it doesn't hurt anything. You don't need the last $ if you bind to &plus_op_subref instead. Also, one thing you couldn't know, since I just changed it, is that all operator names now use a variant of hash subscript syntax, so the name of the builtin addition operator is any of:
      infix:«+» infix:<<+>> infix:{'+'}
      So I'd currently write your code as:
      my &plus_op_subref = &infix:«+»; my &not_op_subref = &prefix:«!»; say plus_op_subref(3, 2); # 5
      See http://www.wall.org/~larry/syn for preprints of the most recent Synopses. And http://www.wall.org/~larry/apo has Apocalypses annotated with "Update" sections.

        Just read the message on p6l :)

        Another idea, I think it'd be most efficient if we'd bind &plus_op_subref to &infix:«+» at compile-time:

        my &plus_op_subref ::= &infix:«+»; my &not_op_subref ::= &prefix:«!»; say plus_op_subref(3, 2); # 5

        Discussing about Perl 6 is fun :)

Re: Why Perl Is Not My Favourite Functional Programming Language
by itub (Priest) on Nov 06, 2004 at 00:11 UTC
    Have you tried prototypes?
      Have you tried prototypes?

      Briefly. I don't fully grok the try/catch example in perldoc perlsub, so I may be missing something, but my failed attempts look like:

      #! /usr/bin/perl use strict; use warnings; sub curry(&@) { my ($fn, @args) = @_; return sub { $fn->(@args, @_); } } &curry(+, 2)->();
      which of course does not compile. (There's also the issue that in order to really do higher-order functions with prototypes, I'd need to somehow examine fn's prototype and preserve it in the returned sub.)

      I'm thinking that a source filter might help, turning builtins used as values into anonymous subs, but I don't know very much about source filters — I'm not even sure that they do what I think they do.

      --
      Yours in pedantry,
      F o x t r o t U n i f o r m

      "Anything you put in comments is not tested and easily goes out of date." -- tye

        Perhaps I misunderstood what you wanted. While you are certainly in trouble if you want to curry the + operator, I see no problem with a function such as sum.

        use strict; use warnings; use List::Util qw(sum); sub curry(&@) { my ($fn, @args) = @_; return sub { $fn->(@args, @_); } } my $f = curry { sum(@_) } 5; print $f->(3); # prints 8 (5 + 3)
      How would prototypes help? All that does is allow for some syntactic sugar. It doesn't deal with the problems FoxtrotUniform mentioned. In addition, Perl5 doesn't really have solid support for lists, and arrays are not lists. Perl6 will deal with it better, by allowing you to pass lists to a function, but Perl5 requires you to deal with array references, which is just another hack.

      Being right, does not endow the right to be rude; politeness costs nothing.
      Being unknowing, is not the same as being stupid.
      Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
      Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

        I was refering to the idea that prototypes allow you to imitate the way builtins such as grep and map are called (without having to say "sub", but now I'm not so sure if it that was the issue).
Re: Why Perl Is Not My Favourite Functional Programming Language
by jdporter (Paladin) on Nov 08, 2004 at 04:25 UTC