-
-
29 May 2002 01:44:19 UTC
- Distribution: Perl6-Currying
- Source (raw)
- Browse (raw)
- Changes
- How to Contribute
- Issues
- Testers (535 / 0 / 0)
- Kwalitee
Bus factor: 1- 88.00% Coverage
- License: unknown
- Activity
24 month- Tools
- Download (4.95KB)
- MetaCPAN Explorer
- Permissions
- Subscribe to distribution
- Permalinks
- This version
- Latest version
++ed by:1 non-PAUSE user- Dependencies
- unknown
- Reverse dependencies
- CPAN Testers List
- Dependency graph
- NAME
- VERSION
- SYNOPSIS
- DESCRIPTION
- REFERENCES
- DEPENDENCIES AND INTERACTION
- DIAGNOSTICS
- AUTHOR
- BUGS
- COPYRIGHT
NAME
Perl6::Currying - Perl 6 subroutine currying for Perl 5
VERSION
This document describes version 0.05 of Perl6::Currying, released May 29, 2002.
SYNOPSIS
use Perl6::Currying; sub add ($a,$b) { $a + $b } # Define a sub with named params print add(1,2); # Call it my $incr = &add.prebind(a=>1); # Bind the $a argument to 1 # to create an increment subroutine print $incr->(3), "\n"; # Increment a number
DESCRIPTION
The Perl6::Currying module lets you try out the new Perl 6 explicit higher-order function syntax in Perl 5.
In Perl 6 any subroutine can be "partially bound". That is, you can supply some of its arguments and thereby create another subroutine that calls the original with those arguments automatically supplied.
Subroutine parameters are partially bound by calling the
prebind
method on the subroutine. This method call returns a reference to a new subroutine that calls the original subroutine, inserting into its argument list the prebound arguments. For example:# Perl 6 code sub divide ($numerator, $denominator) { return $numerator / $denominator; } my $halve = ÷.prebind(denominator=>2);
Note that it's necessary to use the
&
sigil to indicate that the methodCODE::prebind
is to be called on aCODE
object÷
, not theWhatever::prebind
of theWhatever
object returned by callingdivide
. To get the latter, we would write:divide().prebind(...)
or:
divide.prebind(...)
Having prebound the denominator, if we now call the subroutine referred to by
$halve
the effect is to calldivide
with an automagically supplied denominator of 2. That is:# Perl 6 code print divide(42,2); # calls ÷...prints 21 print $halve(42); # calls ÷...prints 21
It's also possible to prebind all the arguments of a subroutine, either all at once:
# Perl 6 code my $pi_approx = ÷.prebind(numerator=>22,denominator=>7); print $pi_approx(); # prints 3.14285714285714
or in stages:
# Perl 6 code my $pi_legislated = $halve.prebind(numerator=>6); print $pi_legislated(); # prints 3
Note that we didn't need the
&
sigil before$halve
since this syntax is unambiguously a call (through a reference to aCODE
object) toCODE::prebind
.You can also use the Perl 6 aliasing operator (
:=
) to create new named subroutines by partially binding existing ones. For example:# Perl 6 code &reciprocal := ÷.prebind(numerator=>1); print reciprocal(10) # prints 0.1
Parameter binding in Perl 5
The Perl6::Currying module allows you to use the same syntax in Perl 5.
That is, you can supply some of the arguments to a (specially prototyped) Perl 5 subroutine and thereby create another subroutine that calls the original with those arguments automatically supplied.
The new subroutine is created by calling the
prebind
method on the original subroutine. For example:# Perl 5 code use Perl6::Currying; sub divide ($numerator, $denominator) { return $numerator / $denominator; } my $halve = ÷.prebind(denominator=>2);
Notes:
As the above example implies, Perl6::Currying gives you the (limited) ability to declare Perl 5 subroutines with named parameters. Currently those parameters must be a list of comma-separated scalars, as shown above. Each parameter becomes a lexical scalar variable within the body of the subroutine.
For forward compatibility, to prebind parameters in Perl 5, the Perl 6 method call syntax (
$objref.methodname(...)
) is used, rather than the Perl 5 syntax ($objref->methodname(...)
).To be consistent with Perl 6, it's still necessary to use the
&
sigil to indicate that the method to be called isCODE::prebind
, not theprebind
of the object returned by callingdivide
.
Having prebound the denominator, if we now call the subroutine referred to by
$halve
the effect is to calldivide
with an automagically supplied denominator of 2. That is:# Perl 5 code print divide(42,2); # calls ÷...prints 21 print $halve->(42); # calls ÷...prints 21
Note that since these are just normal Perl 5 subroutine calls, the Perl 5 call-through-reference syntax (
$subref->(...)
) is used, rather than the Perl 6 syntax ($subref.(...)
).It's also possible to prebind all the arguments of a subroutine, either all at once:
# Perl 5 code use Perl6::Currying; my $pi_approx = ÷.prebind(numerator=>22,denominator=>7); print $pi_approx->(); # prints 3.14285714285714
or in stages:
# Perl 5 code use Perl6::Currying; my $pi_legislated = $halve.prebind(numerator=>6); print $pi_legislated(); # prints 3
You can also use Perl 5 typeglobs to create new named subroutines by partially binding existing ones. For example:
# Perl 5 code *reciprocal = ÷.prebind(numerator=>1); print reciprocal(10) # prints 0.1
REFERENCES
A quick introduction: http://www.tunes.org/~iepos/introduction-to-logic/chap00/sect00.html
Definition of currying: http://www.cs.nott.ac.uk/~gmh//faq.html#currying
Implementation in Haskell: http://www.haskell.org/tutorial/functions.html
DEPENDENCIES AND INTERACTION
The module is implemented using Filter::Simple and requires that module to be installed.
This module can be used in conjunction with the Perl6::Placeholders module. For example:
use Perl6::Currying; use Perl6::Placeholders; $add = { $^a + $^b }; my $incr = $add.prebind(b=>1); print $incr->(7), "\n"; my $div = { $^x / $^y }; print $div->(22,7), "\n"; my $half_of = &$div.prebind(y=>2); my $reciprocal = $div.prebind(x=>1); print $half_of->(7), "\n"; print $reciprocal->(7), "\n";
When using both modules, this module must be loaded first.
DIAGNOSTICS
Odd list of bindings for prebind
-
prebind
expects a list ofparameter_name => value
pairs as its arguments. Instead it detected a non-even number of arguments. Can't prebind sub with prototype (%s)
-
Currently the module only supports scalar named parameters. It has detected an attempt to bind a subroutine that has some other type of parameter specified.
Can't prebind nonexistent parameter %s of sub(%s)
-
You can only bind parameters that were actually declared in the subroutine's prototype.
Perl6::Placeholders should not be loaded before Perl6::Currying
-
When using both modules, Perl6::Placeholders should be loaded after Perl6::Currying.
AUTHOR
Damian Conway (damian@conway.org)
BUGS
This module is not designed for serious implementation work.
It uses some relatively sophisticated heuristics to translate Perl 6 syntax back to Perl 5. It will make mistakes if your code gets even moderately tricky.
Nevertheless, bug reports are most welcome.
COPYRIGHT
Copyright (c) 2002, Damian Conway. All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the terms of the Perl Artistic License (see http://www.perl.com/perl/misc/Artistic.html)
Module Install Instructions
To install Perl6::Currying, copy and paste the appropriate command in to your terminal.
cpanm Perl6::Currying
perl -MCPAN -e shell install Perl6::Currying
For more information on module installation, please visit the detailed CPAN module installation guide.