http://www.perlmonks.org?node_id=408713


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

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

Replies are listed 'Best First'.
Re^9: Near-free function currying in Perl
by dragonchild (Archbishop) on Nov 18, 2004 at 12:57 UTC
    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.

      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.

      If you apply Sturgeon's law, 90% of all Perl programmers are crud. Coincidence? You decide!

      More seriously I'd estimate that over 50% of all Perl programmers have vague plans to learn something about this OO stuff sometime, so to them OO is an advanced technique. It is all a question of perspective. And if you personally are willing to put some energy in, your perspective bears no relationship to what most people experience.

      My perspective is that currying is pretty simple, and it isn't even very hard to teach. Sure, showing a realistic example induces brain lock the first time. But that is temporary and clears up on its own. Since I have no problem taking the energy to spread the knowledge, I have no problem with using it in reasonable doses.

      90% of all Perl programmers will never know that you can take a reference to a subroutine.

      The question is whether these people deserve to be called "Perl programmers".

      Jenda
      If you're not a programmer, you shouldn't be using Perl. Programming languages are tools for programmers. I apologize if people see that as an elitist statement, but it's true. The mere act of picking up a toolbox doesn't make me an auto mechanic. Would you let me work on your car just because I had a set of tools? I have a pair of scissors at home; you should let me cut your hair.
        -- Greg Bacon

        If you're not a programmer, you shouldn't be using Perl. Programming languages are tools for programmers. I apologize if people see that as an elitist statement, but it's true. The mere act of picking up a toolbox doesn't make me an auto mechanic. Would you let me work on your car just because I had a set of tools? I have a pair of scissors at home; you should let me cut your hair.

        Updated: clarified condition

        Jenda++ -- with a caveat.

        I wouldn't let you cut my hair, or service my car, just because you had a pair of scissors, or a set of tools.

        However, if you wanted to change the oil filter, air filter, wiper blades, or check the tyre pressures on your car and wanted me to give you a few clues as to how you should start, or check what you did afterwards--I'd probably help you with that.

        And if having done a few of the simpler things a few times, you got the taste and confidence to try and tackle something a little more ambicious, I'd probably encourage you.

        And if, over time, it became obvious that you had some sort of flair for what you were doing: you didn't need to ask the same questions over and over; you learnt from your mistakes; displayed the habits of keeping your tools clean and in the right place; laid out the bits you took off in order, so you knew which way to put them back; took the time to label wires and stuff as you went; took responsibility for any mistakes you made--even if based on my advice; then I'd be more than happy to continue to provide what advice I could.

        And, if you eventually got so bitten by the idea that you decided to build your own kit car and asked me to check your work as you went. I'd probably be more that happy to do that too.

        But if you come to me with your nice new toolkit in your hand, and your big pile of kit car bits in the garage and ask me "Where do I start?", I'm probably going to suggest, "I think Joe over the road may know something about wheels and bolts and nuts and stuff."


        Examine what is said, not who speaks.        The end of an era!
        "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
        "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        As BrowserUK said at length, it is obvious that these people do not deserve to be called Perl programmers, but I strongly disagree with your Greg Bacon quote.

        There is a difference between a programmer and someone who sometimes writes programs. However Perl was designed to allow you to get stuff done while only talking baby talk. There are plenty of sysadmins, DBAs, and general users who find Perl helpful even though they are not programmers, and I don't agree with the kind of elitism which would deny them such a useful tool.

        While I can't presume to talk for Larry Wall, the fact that he designed Perl to be productively used while only talking baby talk, and then encouraged this in Programming Perl is strongly suggestive about what he thinks.

        The question is whether these people deserve to be called "Perl programmers".

        No. The question is whether or not they will be paid to be a Perl programmer. If they are, they will fsck up your code. It's a pragmatic matter.

        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.

Re^9: Near-free function currying in Perl
by stvn (Monsignor) on Nov 18, 2004 at 14:05 UTC

    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
      IMO functional programming in general is still a largely acedemic CS territory.

      There's the rub. Yes, currying is largely academic. Sure, you can't do it in C or C++ or Java (actually, I have my doubts about Java -- maybe you can make it work with anonymous classes).

      That doesn't make it hard. That just makes it obscure.

      map and grep are the same way -- at first, they look like inscrutable shorthand for a two- or three-statement for loop, but they're basically straightforward. You don't have to know a lot of theory to use map, or fundamentally change your outlook on programming. I think currying will turn out the same way.

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

        map and grep are the same way -- at first, they look like inscrutable shorthand for a two- or three-statement for loop...

        I've still to see an example of when I might want to use this in Perl?

        Tom kinda dismissed this, as my not being familar with the concept, so therefore I could see the opportunities, but I think he is wrong.

        So far in this thread, I haven't seen anyone else come up with a good, everyday example of where currying would have done something useful.

        I spent a good part of the last few days going through some of the 8000+ small scripts in my test directory looking for places where I might have used this. So far, not a single one.

        Every place where I call a sub with constant value parameters in the first one or two positional arguments, the functions are in a loop so I only needed to type it once anyway.

        All currying would have done in these situations is add an extra two (_c) or more characters to type in-line, plus the use Autocurry qw[ :all ] plus have to worry about making sure that I positioned that use line appropriately so that only the subs I wanted curried would follow it.

        Every way I look at this, currying (or Autocurrying) buys me nothing. I have to type more. My code runs more slowly.

        And with autocurrying, I have an extra administrative task of ensuring that the sequence and position of use lines relative to each other, and to my sub definitions is correct.

        Normally, my use lines go at the top of the program in whatever order I realise I need them. Except when using threads when I have to be somewhat more careful to conserve space.

        And I know exactly what a pain it is having to think about that, so the idea of having another set of position dependancies to worry about is a total anathema to me.

        That maybe a part of the problem. Haskell programs have an entirely different structure to Perl programs.

        Nope. No matter how hard I try, I cannot see any merit in currying, and especially not Autocurrying in Perl (5). None at all. I can never envisage it becoming anything beyond a mildly interesting curiosity.

        In Perl 6, if the overhead of sub calls is less, and the syntax built in and more condusive to it's use, maybe it will become more prevalent, but I still don't see it ever becoming common, nevermind ubiquitous.

        Time will tell :)


        Examine what is said, not who speaks.
        "But you should never overestimate the ingenuity of the sceptics to come up with a counter-argument." -Myles Allen
        "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo         "Efficiency is intelligent laziness." -David Dunham
        "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
        ... or Java (actually, I have my doubts about Java -- maybe you can make it work with anonymous classes)

        No need for anonymous classes (yuk), you just need to use an alternate compiler, check out Pizza, it seems to not have been updated since 2002, but it's still a cool project.

        That doesn't make it hard. That just makes it obscure.

        Okay, i will go with you on that, with the one caveat that it for a large percentage of programmers out there it is not a simple concept to grasp, since the language they use (C/C++, Java, VB, etc) has no facility with which to do it. IMO, without a solid frame of reference it will likely not be very easy for them to grasp. But you are correct, that doesn't mean its hard (it just means those languages SUCK ;-).

        -stvn