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
my $fun = foo( 1, 2, ...);
# or using your example
$app_server = AppServer->new(
logger => log_to_handle( *STDERR, "app-server", ...),
other_option => 5,
);
(Except that it would colide with the common usage of three dots in pseudo code.)
It's actually doable, but AFAIK only via source filters. And it is not that long actually:
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;
and the examples:
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);
Tested with Perl v5.8.0 (ActivePerl build 805).
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 |