# Currying functions (was "theory vs practice" ceases power) - PERL Miscellaneous

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Ed Avis <edmembled.com> wrote in news:l1oezgxozo.fsfbudvar.future- i.net: > Dave Benjamin <ramenlackingtalent.com> writes: > >>> sub curry( \$ ) { >>> my \$f = \$_[0]; >>> sub( \$ ) { my \$x = \$_[0]; sub( \$ ) { \$f->(\$x, \$_[0]) } }; >>> } > >>Well, I'd define curry a little differently, > > There isn't really any option about how to define it. As far as I > know the operation 'curry' is defined as > > curry f x y = f (x, y) > > in other words turning a function which ...

1. ## Re: Currying functions (was "theory vs practice" ceases power)

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ed Avis <edmembled.com> wrote in news:l1oezgxozo.fsfbudvar.future-
i.net:
> Dave Benjamin <ramenlackingtalent.com> writes:
>
>>> sub curry( \$ ) {
>>> my \$f = \$_[0];
>>> sub( \$ ) { my \$x = \$_[0]; sub( \$ ) { \$f->(\$x, \$_[0]) } };
>>> }
>
>>Well, I'd define curry a little differently,
>
> There isn't really any option about how to define it. As far as I
> know the operation 'curry' is defined as
>
> curry f x y = f (x, y)
>
> in other words turning a function which takes a pair into a function
> which takes one argument and returns a function taking the second
> argument.
Pardon me for jumping in here, but....

- From time to time I've heard people discussing currying functions, but
only from either a computer science theoretical point of view, or how to
implement them in Perl (or whatever language).

What the heck would one ever use them for? I mean, in the real world,
not as some funky way to solve the Towers of Hanoi or something.

(As a personal aside, I understand closures and regularly use them in the
real world, so it's not like I can't apply complex functional
structures). :-)

Thanks,
- --
Eric
\$_ = reverse sort qw p ekca lre Js reh ts
p, \$/.r, map \$_.\$", qw e p h tona e; print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBPyO7DmPeouIeTNHoEQLM+gCeMsZHnoGAeH4sGcNds5wLv/IGE8QAoOJF
zkk/mB77VEaJiJkgLHp8+f7V
=0wak
-----END PGP SIGNATURE-----
Eric J. Roode Guest

2. ## Re: Currying functions (was "theory vs practice" ceases power)

"Eric J. Roode" <REMOVEsdnCAPScomcast.net> wrote:
> What the heck would one ever use them for? I mean, in the real
> world, not as some funky way to solve the Towers of Hanoi or
> something.
Assuming you want to convert an internet address from the single byte form
to the 32-bit form (Haskell syntax):

bytesToInt = foldl1 (\x y -> 256*x+y)

Ok, this is syntatic sugar for "bytesToInt z = foldl1 (\x y -> 256*x+y) z",
but if you use combinators, it would be more diffcult to do it without
currying, for example if you want to build XML files:

[url]http://www.cs.york.ac.uk/fp/HaXml/icfp99.html[/url]

--
Frank Buß, [email]fbfrank-buss.de[/email]
[url]http://www.frank-buss.de[/url], [url]http://www.it4-systems.de[/url]
Frank Buss Guest

3. ## Re: Currying functions (was "theory vs practice" ceases power)

"Eric J. Roode" <REMOVEsdnCAPScomcast.net> writes:
>- From time to time I've heard people discussing currying functions,
>but only from either a computer science theoretical point of view, or
>how to implement them in Perl (or whatever language).
>
>What the heck would one ever use them for?
I think it is mostly a matter of syntax. In Haskell and many other
functional languages function application is simply

f x

not f(x) as in C, Perl etc. If application is left-associative, then

f x y

is the same as

(f x) y

that is, f takes one argument and returns a function taking one
argument, which is then applied to y.

You have a choice of writing a tupled style:

f (a, b) = something
x = f (1, 2)

or a curried style:

f a b = something
x = f 1 2

Purely from syntax the second is a bit cleaner. It also lets you
write things like

g = f 1
newlist = map (f 2) list

to partially apply a function, instead of

g (x, y) = f (1, y)
newlist = map (\y -> f (1, y)) list

or similar workarounds. (The syntax '\x -> r' is a lambda expression

In a language that needs more punctuation to call a function, currying
isn't so attractive; you might not enjoy writing f(2)(3) instead of
f(2, 3). But note that C did use a similar idea for array access.

--
Ed Avis <edmembled.com>
Ed Avis Guest

4. ## Re: Currying functions (was "theory vs practice" ceases power)

In article <Xns93C54EC2873DAsdn.comcast206.127.4.25>, Eric J. Roode wrote:
> - From time to time I've heard people discussing currying functions, but
> only from either a computer science theoretical point of view, or how to
> implement them in Perl (or whatever language).
>
> What the heck would one ever use them for? I mean, in the real world,
> not as some funky way to solve the Towers of Hanoi or something.
Well, if we assume a function of one argument, we can generalize a lot. The
most common, obvious example (in my opinion) is the "map" function, which as
you probably know takes a list and applies a function to each element in the
list, returning a list of the results. Now, what if we wanted to use "map",
but the function we wanted to use to map the input list takes two
parameters, not one, and the first parameter is going to be given the same
value for each call?

For example, say we have a function that does a regex match and returns true
or false. It looks like this:

regex_match(pattern, input)

Where pattern is a regular expression, input is whatever string you want to
match, and the result is a boolean. Now, suppose we want a list that
contains [true, false, true, true, ...] for a given input list, depending on
whether or not each string in the input list matches a particular regular
expression.

If we can curry regex_match, we can produce a new function that already
knows the pattern, and just takes the input. Then, we can just use the
regular map function to apply the curried function to the list:

map(curry(regex_match, pattern), input)

Or, Perl-style:

fmap(curry(\&regex_match, \$pattern), input)

Or, in a language like Haskell that does currying implicitly:

map (regex_match pattern) input

This is just a ficticious example, since Perl's built-in map can easily do
regular expression matches within its code blocks, and other languages like
Python and Java use a more OO (and efficient) way of caching the pattern
than using the method I described. I'm just trying to provide a simple
illustration.

Hope this helped a little,
(and apologies to Ed for continuing to abuse the word,)
Dave
Dave Benjamin Guest

5. ## Re: Currying functions

On Mon, 28 Jul 2003, Dave Benjamin wrote:
> other languages like Python and Java use a more OO (and efficient) way
> of caching the pattern than using the method I described.
Why do you say "more efficient" -- can't you implement partial application
with a closure, and why should that less efficient than a full-n
object? I'd think it'd be more efficient since there's no dynamic
dispatch.

6. ## Re: Currying functions

news:Pine.LNX.4.44.0307281409080.11405-100000gwen.sixfingeredman.net...
> On Mon, 28 Jul 2003, Dave Benjamin wrote:
> > other languages like Python and Java use a more OO (and efficient) way
> > of caching the pattern than using the method I described.
>
> Why do you say "more efficient" -- can't you implement partial application
> with a closure, and why should that less efficient than a full-n
> object? I'd think it'd be more efficient since there's no dynamic
> dispatch.
All I was trying to say (and I didn't explain this very well) was that
partial application does no actual computation, so if you partially apply a
regex match function with a particular pattern (assuming pattern means a
string, not a compiled regex), the regex could potentially be recompiled for
each iteration. In other words, if you can do some number crunching before
you have all the arguments you want, you're better off writing a function
that does that computation and then returns a closure instead of currying.

Python and Java achieve their efficiency by doing something similar to
currying, but in object-oriented style. You compile your regular expression
into an object, and that object's "match" method (or similar) can then be
applied to a sequence without worrying about redundantly recompiling the
same regex. Perl's a bit different, because it treats regexes as literals,
and does caching behind the scenes. (Right? I'm guessing...)

Dave

Dave Benjamin Guest

7. ## Re: Currying functions

In comp.lang.functional Dave Benjamin <dave3dex.com> wrote:
: news:Pine.LNX.4.44.0307281409080.11405-100000gwen.sixfingeredman.net...
:> On Mon, 28 Jul 2003, Dave Benjamin wrote:
:> > other languages like Python and Java use a more OO (and efficient) way
:> > of caching the pattern than using the method I described.
:> Why do you say "more efficient"

: All I was trying to say (and I didn't explain this very well) was that
: partial application does no actual computation, so if you partially apply a
: regex match function with a particular pattern (assuming pattern means a
: string, not a compiled regex), the regex could potentially be recompiled for
: each iteration.

That is probably the case for the Perl version (score one against
writing Perl in a functional style) but the Haskell version will
compile it the first time it is _used_ and then never again. That's
just as efficient in the general case and more efficient if your
list is empty.

-Greg
gregm@cs.uwa.edu.au Guest

8. ## Re: Currying functions

In Perl regular expressions are compiled at compile time, except if
they contain variables, in which case the compilation happens at run
time and every time the regexp is used. This is indeed slower than
memoizing previously compiled regexps, as the regexp library of Python
(for example) does.

There is the /o flag which says that once a regexp has been compiled
at run time it can be kept around and not recompiled for each use; you
can use this if you know that the variables you used in the regexp
will not change their values later.

If in Perl you want to use a regexp which is not known until run time,
but on the other hand expect that the same regexp will be used often,
then one way to get the right result is to construct a closure:

my (\$f, \$g);

{
my \$pattern = 'a';
\$f = sub { /\$pattern/o };
}

{
my \$pattern = 'b';
\$g = sub { /\$pattern/o };
}

foreach (qw(a b)) {
print "testing \$_\n";
print "f\n" if \$f->();
print "g\n" if \$g->();
}

The two different closures \$f and \$g have different \$pattern variables
(which could be read from the user rather than set to string literals)
and the regexps applied will be cached after the first use - the /o
flag on the match says that the value of \$pattern will not change.

--
Ed Avis <edmembled.com>

Ed Avis Guest

9. ## Re: Currying functions

Ed Avis wrote:
> If in Perl you want to use a regexp which is not known until run time,
> but on the other hand expect that the same regexp will be used often,
> then one way to get the right result is to construct a closure:
It's simpler to write qr/\$pattern/ - it's a scalar which you can store
in a variable.

--
__("< Marcin Kowalczyk
\__/ [email]qrczakknm.org.pl[/email]
^^ [url]http://qrnik.knm.org.pl/~qrczak/[/url]
Marcin 'Qrczak' Kowalczyk Guest

10. ## Re: Currying functions

Marcin 'Qrczak' Kowalczyk <qrczakknm.org.pl> writes:
>>If in Perl you want to use a regexp which is not known until run
>>time, but on the other hand expect that the same regexp will be used
>>often, then one way to get the right result is to construct a
>>closure:
>
>It's simpler to write qr/\$pattern/ - it's a scalar which you can
>store in a variable.
Apologies - I was still thinking about olden days when qr// didn't
exist. Yes, it seems you can do

my \$letter = 'a';
my \$r0 = qr/\$letter/;
\$letter = 'b';
my \$r1 = qr/\$letter/;

for (qw(a b)) {
print "testing \$_\n";
print "r0\n" if \$_ =~ \$r0;
print "r1\n" if \$_ =~ \$r1;
}

So it looks like the regexp is compiled when qr// is evaluated. This
is a much simpler way to get dynamically-generated (yet compiled once)
regular expressions than the old way of using closures.

--
Ed Avis <edmembled.com>
Ed Avis Guest

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•