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

Thanks for your feedback! (I especially appreciate feedback from you because you take the time to explain your concerns, and you don't dismiss things offhand. When you say that you don't see the value of something, I know that it's not because you aren't trying. Thanks!)

Let me see if I an address your concerns.

But I simply do not see that (currying is less expensive than creating an anonymous wrapper function).
Cost is in the eye of the be-payer, and so I won't tell you that you're wrong. However, I would like to suggest that your cost model would be different if you were familiar with currying.

Later on, you write this:

I cannot think of a single instance of ever needing or wanting to constantise one or more parameters that I had to pass on many calls to a function.
This suggests that currying is indeed a foreign concept to you. When you see currying, then, the cost naturally goes up because it doesn't seem as nearly straightforward as "simply" writing anonymous-subroutine wrapper.

But let me argue that currying is the easier of the two to understand (once currying is familiar). Currying does only one thing: binds arguments to values. Anonymous wrapper subs, on the other hand, can do anything. So, using the code below as an example, you must look closely at the anonymous-subroutine version to ensure that all it's doing is binding the first two arguments:

sub { log_to_handle( *STDERR, "app-server", @_ ) } curry( \&log_to_handle, *STDERR, "app-server" ) log_to_handle_c( *STDERR, "app-server" );
The second version, by definition, can only bind the first two arguments of log_to_handle. There is no other possibility. Please consider that this constraint reduces the cost of understanding the second w.r.t. the first. (Again, assuming that you have already paid the price to understand currying.) And the third version is even simpler (once it is understood that the _c suffix is notation that implies currying.) It is identical in meaning to the second but shorter and closer to the true currying that some other programming languages offer.
All your curry() is doing, is complicating a very simple piece of code, in order to justify the introduction of the need for autocurrying.
No doubt about it, my example sucks as a motivating example for currying. I doubt that anybody who doesn't already value currying is going to bother reading beyond the contrived back-story. (Lesson for me: Invest more time in selecting examples that are simple, illustrative, and yet realistic.)
I would either reject, or modify any application server module that required me to give it function for it to call every time it wanted to log a message.
Please don't read too much into the back-story. Don't focus on the obviously contrived "ooh, we have an application server that we must provide with a logging callback." Instead, see it as "how do we glue the function we want of use into the hole we want to fill, when their shapes are different?"
But there is another, more serious problem with the idea of autocurrying.

(I)f instantiating an instance of AppServer class is going to blythly export curried functions into the caller's namespace, ...

It isn't. Here's the situation:
#!/usr/bin/perl use warnings; use strict; use AppServer; use AutoCurry ':all'; sub log_to_handle { ... } my $appserver = AppServer->new( logger => log_to_handle_c( *STDERR, "app server" ) );
Only log_to_handle_c will be created, and it will be stored in the same namespace as the original log_to_handle (main::). Further, it will happen only once, after the application code is compiled but before it starts executing.

Thanks again for providing a wealth of feedback. I hope that I was able to address some of your concerns. Please don't hesitate to follow up, and I will do my best to respond.


Replies are listed 'Best First'.
Re^3: Near-free function currying in Perl
by ww (Archbishop) on Nov 17, 2004 at 17:45 UTC
    A perl noob (but veteran news writer) re your self-deprecated "motivating example":

    On the one hand (++), you give the reader a warning, "It's a simple function for the sake of our example, but let's imagine that it's complex and would be costly to rewrite." Good; 'cuz it leads to the inference that your basics will be more easily absorbed using a "simple" example.

    To head off critiques such as some already offered here, though, you might want to offer a much more complex function as an example of why currying is desireable -- perhaps even before the existing one.

    For example, you may have a specialized function like this: ((sorry way too new to write that)). Now, suppose new management wants you to write a package that does essentially the same thing, but with only a few possible inputs. But rather than do it with a complex example (that will make it harder to focus on currying), let's pretent the original function is:....

    Re the writing: splendidly clear and concise. This noob had difficulty only with one phrase... and that was simple lack of background... most of which you subsequently supplied. Well done!

    Will be watching the tread.