Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^4: Near-free function currying in Perl

by fergal (Chaplain)
on Nov 17, 2004 at 13:01 UTC ( #408395=note: print w/replies, xml ) Need Help??


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

I can't think of one off hand that uses it for logging but why not?

You can't just pass a filehandle because then you cannot do interesting things with a message before logging it or maybe decide not to log it at all (unless you tie the filehandle but please don't go there).

The only other way that has the same flexibility is to pass in a logging object, which has a log() method.

When it comes down to it, a closure and an object with one method are pretty much equivalent, they both store a state and they both have a behaviour which can be invoked. The difference is that it's a lot easier to construct a closure on the fly whereas an object needs an entire class.

The Tk framework is full of things that take a callback. Tk programmers have to write lots of closures. I used to do loads of Tk work (back in the 2oth century :-) and looking back, I frequently found myself currying functions although I didn't have a name for it at the time.

Frameworks in functional languages like lisp and Haskell do this too because it's easy to do for them as currying is built in and is the "natural" way to do this for their programmers.

  • Comment on Re^4: Near-free function currying in Perl

Replies are listed 'Best First'.
Re^5: Near-free function currying in Perl
by BrowserUk (Pope) on Nov 17, 2004 at 13:37 UTC
    (unless you tie the filehandle but please don't go there).

    Why not?

    Frameworks in functional languages like lisp and Haskell do this too because it's easy to do for them as currying is built in and is the "natural" way to do this for their programmers.

    I agree (partially), but tieing is a "natural" way in Perl.

    Lisp and Haskell have to use currying, because FP languages eshew the concept of variables and state. So much so, that they had to invent "functions that you can only run once" (fancifully named 'monads') in order to get around the inconvenient reality that you cannot represent the real world as mathematical functions who's return values are always defined in terms of their inputs.

    Files don't work that way; neither do databases or network connections or users. Perl very much lives in the real world. As LW put it "good chemistry is complicated, and a little bit messy". Perl has constructs for dealing with the real world very efficiently.

    It just strikes me that trying to force-fit the FP function passing style on top of Perl is a kind square peg in a round hole thing.

    Don't get me wrong. I'm really glad that Tom is posting this Haskell inspired stuff. It's helping me in my attempt to get to grips with Haskell. And I wouldn't try and stop anyone else from using it if they see what I don't. I'm just having a hard time trying to envisage the time when I would want to use currying in a Perl program.

    All the examples I find of currying show (the equivalent of) things like

    my $double = sub{ mult( 2, @_ ) }; my $doubled = $double->( 3 ); print $doubled; ## ouputs '6'

    To which my reaction is "Whoo-pee?". And what's wring with print 2 * 3; ?

    Tom at least came up with a vaguely plausible use for it, despite that I can't actually think of any time (with the possible exception of Tk; which I have issues with anyway:) that I might hav eused up till now.

    Maybe the penny will drop for me one day soon. Or maybe I'll just have to confine myself to the backwater of inherently procedural thinkers--although I make full use of map, grep, List::Util::reduce et al. as well as having a growing collection of similarly FP-like functions of my own devizing.

    So I have picked up on some of the concepts and grasped them with both hands. It's just finding a real-world "killer application" for some of the others, like currying, that leave me cold so far.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
      (unless you tie the filehandle but please don't go there).
      Why not?

      Because tieing a filehandle is even more work that passing in an object or even currying by hand. It's also slow. Finally it has interface issues, if the framework has been written to think in terms of logging to a filehandle it might be tempted to do

      print $log_fh "doing something..."; if (do_something(...)) { print $log_fh "suceeded\n"; } else { print $log_fh "failed\n"; }
      which is going to be rather unpleasant for anyone who wants to tie the filehandle and maybe manipulate the messages. You could decide that a log message ends with a \n and then you have to buffer stuff inside your tieing object but that rules out the possibility of multiline messages. It's just not nice.

      tie is a horrible hack to get around the fact that Perl's fundamental data structures are not objects and thus cannot be substituted for by a user defined object implementing a compatible interface. No other language has tie because no other language needs it. So in other languages you can create something that can pretend to be both as a hash and as an array but in Perl we have to choose one or the other.

      There is nothing natural about having to implement TIEHASH, FETCH, STORE, DELETE, CLEAR, EXISTS, FIRSTKEY, NEXTKEY, SCALAR and UNTIE just to create a case insensitive hash. In another language you'd just inherit from hash and override the fetch and exists methods.

      There is one good thing about tie and that is tied scalars because in this case you are effectively taking control of the assignment operation. Most languages allow you to control the behaviour of values, I think Perl is unique in allowing you to control the behaviour of variables but that's it.

      As for the usefulness in general of currying, of course nobody uses currying for adding 2 in real life however if you want to make full use of map, grep, reduce, fold etc. then currying allows you avoid lots of closures. Anything that can be done with currying can be done with closures and many of the most common uses of closures are no more than just currying. So it's just a nice way of compressing

      sub {some_func($this, $that, @_)}
      down to
      some_func_c($this, $that)
      less typing means less typos. It's only a small saving but it eliminates lots of punctuation which gets it some bonus points.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (9)
As of 2020-11-24 20:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?