Professional Web Applications Themes

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. #1

    Default 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. #2

    Default 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. #3

    Default 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 Haskell.)

    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. #4

    Default 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. #5

    Default 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.

    Adrian Kubala Guest

  6. #6

    Default Re: Currying functions

    "Adrian Kubala" <adriansixfingeredman.net> wrote in message
    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. #7

    Default Re: Currying functions

    In comp.lang.functional Dave Benjamin <dave3dex.com> wrote:
    : "Adrian Kubala" <adriansixfingeredman.net> wrote in message
    : 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. #8

    Default 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. #9

    Default 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. #10

    Default 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

Similar Threads

  1. "Pattern" or "best practice" in security checks
    By Anders K. Jacobsen [DK] in forum ASP.NET Security
    Replies: 0
    Last Post: December 5th, 07:31 PM
  2. "theory vs practice" ceases power
    By Xah Lee in forum Ruby
    Replies: 10
    Last Post: July 28th, 12:11 PM
  3. theory vs practice ceases power
    By Xah Lee in forum PERL Miscellaneous
    Replies: 1
    Last Post: July 22nd, 06:57 PM
  4. unix pestilence: theory vs practice ceases power
    By Xah Lee in forum Linux / Unix Administration
    Replies: 1
    Last Post: July 22nd, 02:10 PM
  5. Replies: 0
    Last Post: July 18th, 11:51 PM

Bookmarks

Posting Permissions

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139