Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^6: Near-free function currying in Perl

by tmoertel (Chaplain)
on Nov 17, 2004 at 22:20 UTC ( [id://408628]=note: print w/replies, xml ) Need Help??


in reply to Re^5: Near-free function currying in Perl
in thread Near-free function currying in Perl

stvn, thanks for your comments. Let me address this one, in particular:
For instance, your technique would not work with OO, ...
Why not? For example, here I use currying to pre-bind a method to a particular object instance:
#!/usr/bin/perl package MyObj; use warnings; use strict; use AutoCurry ':all'; sub new { my $self = shift; my $name = shift; bless [$name, { @_ }], $self; } sub speak_keyvals { my ($name, $hash) = @{shift()}; print "$name sez: @{[ @$hash{@_} ]}", $/; } my $foo = new MyObj( "foo", a => "alpha", b => "beta" ); $foo->speak_keyvals( "a" ); # foo sez: alpha # for the next line, recall that $o->f(...) === f($o, ...) my $foo_speaker = $foo->speak_keyvals_c(); # binds to $foo $foo_speaker->("b"); # foo sez: beta $foo_speaker->(@$_) for ["a"], ["b"], ["a", "b"]; # foo sez: alpha # foo sez: beta # foo sez: alpha beta
Also, regarding this:
I also take issue with the idea that there is something wrong with design-time decisions to support currying.
To clarify, I didn't say that there was anything wrong with design-time consideration of currying. What I said was that it was a bad idea to require design-time considerations in order to make a currying scheme work. With such a requirement, the vast existing wealth of CPAN is placed beyond the reach of currying.

I don't want my ability to use currying to be dependent upon somebody else having designed it into the code I'm using. I want to be able to take old, existing code and curry it, as is.

Cheers,
Tom

Replies are listed 'Best First'.
Re^7: Near-free function currying in Perl
by stvn (Monsignor) on Nov 17, 2004 at 22:57 UTC
    Why not? For example, here I use currying to pre-bind a method to a particular object instance:

    I stand corrected. Very nice example.

    To clarify, I didn't say that there was anything wrong with design-time consideration of currying. What I said was that it was a bad idea to require design-time considerations in order to make a currying scheme work. With such a requirement, the vast existing wealth of CPAN is placed beyond the reach of currying.

    I don't want my ability to use currying to be dependent upon somebody else having designed it into the code I'm using. I want to be able to take old, existing code and curry it, as is.

    I agree that it can be nice to not have to require design time considerations for currying to work in many cases. Although I think saying that the all of CPAN is now your curried oyster is maybe a little presumptious. For instance, any function which makes use of caller may or may not work properly, and stack traces will quite possibly get very messy. There is a lot of crazy code on CPAN (and not just TheDamians) and I would guess that some of it would not respond well to currying.

    I guess my point really is that currying is something which is not to be used lightly. It is, by its very nature, an advanced technique which is not easily accessible or understandable to most programmers who were trained in procedural or OO programming. A well crafted Haskell or Standard ML function will be built with the understanding, that it will almost certainly be curried at some point. Old perl code will almost certainly not be built with the same considerations. That is not to say that you shouldn't still use currying in those situtations, but I think it ill advised to imply that currying can breath new life into old code.

    -stvn
      I guess my point really is that currying is something which is not to be used lightly. It is, by its very nature, an advanced technique which is not easily accessible or understandable to most programmers who were trained in procedural or OO programming.

      I'm sorry, I have to disagree.

      I don't think that currying's a particularly advanced technique, or a particularly difficult one to grok. I do think that currying in particular, and "functional programming techniques" in general, have gotten a reputation for being difficult to understand, and that programmers approach them expecting difficulty... and creating that difficulty if they don't find it.

      One thing that really threw me when I was learning Haskell was the fact that most partial expressions are perfectly valid... they just return functions that (given the right arguments) complete the expression. That's not an example of currying being difficult, although currying is the mechanism I'm talking about: it's an example of Haskell doing something that most languages do not (that is, transparently currying everything). Currying is just a matter of caching an argument.

      A well crafted Haskell or Standard ML function will be built with the understanding, that it will almost certainly be curried at some point. Old perl code will almost certainly not be built with the same considerations. That is not to say that you shouldn't still use currying in those situtations, but I think it ill advised to imply that currying can breath new life into old code.

      I don't understand. None of the curry functions I've seen on PM does anything more than wrap the curried function in a closure that remembers what the curried argument was. I guess functions that make heavy use of caller or other recondite corners of Perl's introspection might break when curried, but that's about it. I can't think of any "plain old subroutine" convention that would break when curried. I think that most existing code would survive currying quite happily, though I'm willing to speculate that not everything would.

      --
      Yours in pedantry,
      F o x t r o t U n i f o r m

      "Anything you put in comments is not tested and easily goes out of date." -- tye

        For an advanced student of computer science, I would say currying is a simple concept. I would even say that for a not-so-advanced student of computer science who has been made to sit through a couple Scheme-based classes, currying is not an advanced concept. But many CS students I have meet have been trained in either C/C++ or Java and for them the idea of currying is very foreign. In C/C++ to do it would surely be an advanced usage of the language (if it is even possible), and currying in Java is impossible (unless you are using the Pizza compiler, but thats not Java and certainly not for CS 101).

        And lets not forget that many programmers didn't go to school for CS (me amoung them). I highly doubt you are going to find the topic of curried subroutines anywhere in a MIS cirriculum, nor are you likely to find it in an Elec. Eng. progam. Many a EE and MIS grad go on to be programmers/developers. IMO functional programming in general is still a largely acedemic CS territory. Although as time goes by I am seeing what I would describe as a slow-leak of functional thought into the mainstream (OO/procedural) programming world, which I think is a very good thing.

        As for how curry-able old crufty perl subroutines are. The more I thought about it, the more I think I put my foot in my mouth there. There are of course some odd cases where things will go awry, but thinking of modules like Memoize (which in many ways does things similar to currying) I can see that it would likely work out better than I initally thought.

        -stvn
        I think you're missing the point - 90% of all Perl programmers will never know that you can take a reference to a subroutine. To them, currying is a very advanced technique. In fact, it's almost to the point of inscrutability. It's because of this that I would hesitate to ever use any form of currying at most jobs I've been at, regardless of whether or not I had need for it.

        Now, granted, once you grok references, currying is far less complicated than inside-out objects. It's nothing more than fancy caching, just like you said. And, if you know that your maintainers will all be in that 10% of Perl programmers, then it's no more complicated than the map-sort-map of the ST.

        As for what Perl might break ... you just might be right. Anything that depends on caller(), B::*, or is sufficiently introspective will probably have issues. But, I've been testing out my Currying implementation based on attributes and it seems to be taking everything I've been throwing at it. A few of the crazier things have been:

        # Named closures { my $x = 0; sub inc_x : curry($) { $x += shift } } # run-time binding sub foo : curry($); BEGIN { *foo = sub { print "@_\n" } }

        It didn't handle the following, but I think that's because of me screwing up the attribute handler.

        sub foo : curry($); my $ref = foo(); $ref->('hello');
        That created an infinite loop, but I'm not sure why.

        Being right, does not endow the right to be rude; politeness costs nothing.
        Being unknowing, is not the same as being stupid.
        Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
        Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://408628]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-19 01:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found