I don't like the syntax. When looking at the code I would definitely not expect foo_c(1,2) to be "equivalent" to sub {foo(1,2,@_}. I think the currying would have to have a very very nice syntax to be used in place of anonymous subs. A syntax that would look readable enough to me is
(Except that it would colide with the common usage of three dots in pseudo code.)my $fun = foo( 1, 2, ...); # or using your example $app_server = AppServer->new( logger => log_to_handle( *STDERR, "app-server", ...), other_option => 5, );
It's actually doable, but AFAIK only via source filters. And it is not that long actually:
and the examples:package Curry::Dots; use Filter::Simple; my $braces = qr{ \( (?: (?> [^\(\)]+ ) # Non-parens without backtracking | (??{ $braces }) # Group with matching parens )* \) }x; sub curry { my $f = shift; my $args = \@_; sub { $f->(@$args, @_) }; } FILTER_ONLY code => sub { return unless /,\s*\.\.\.\s*\)/; s/\&\$(\b\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\.\.\ +s*\)/Curry::Dots::curry (\$$1, $2)/g; s/(\$\b\w+)\s*->(\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s +*\.\.\.\s*\)/Curry::Dots::curry ($1->can('$2'), $1, $3)/g; s/(\b\w+)\s*->(\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\ +.\.\.\s*\)/Curry::Dots::curry ($1->can('$2'), '$1', $3)/g; s/\$(\b\w+)\s*->\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\. +\.\s*\)/Curry::Dots::curry (\$$1, $2)/g; s/(\b\w+)\s*\(([^\(\)]*(?:$braces[^\(\)]*)*)\s*,\s*\.\.\.\s*\) +/Curry::Dots::curry (\\\&$1, $2)/g; }; 1;
Tested with Perl v5.8.0 (ActivePerl build 805).use strict; use Curry::Dots; sub foo { print "@_\n"; } sub Obj::method {print "Obj::method( @_)\n"} sub Obj::new {bless {}, 'Obj'} my $f1 = foo(1, 2, ...); $f1->(3); my $f2 = &$f1( 99, ...); $f2->(0); my $f3 = $f1->(7,... ); $f3->(123); my $obj = new Obj; my $f4 = $obj->method(987, 654, ...); $f4->(321); my $f5 = Obj->method(55,...); $f5->(22);
It only supports the simpler types of calls like foo(params, ...), &$foo(params, ...), $foo->(params, ...), $obj->Method(params, ...) and Class->Method(params, ...) and it uses just \w+ for variable/function/method/class names which definitely is not correct regexp for identifiers in Perl.
Jenda
|
We'd like to help you learn to help yourself Look around you, all you see are sympathetic eyes Stroll around the grounds until you feel at home -- P. Simon in Mrs. Robinson |
In reply to Re: Near-free function currying in Perl
by Jenda
in thread Near-free function currying in Perl
by tmoertel
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |