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: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |