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 |
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.