Currying (which has been discussed
before on Perl Monks) makes it easy to specialize functions by
pre-binding some of their arguments to given values. It might not
sound impressive, but after you have coded with currying for a while,
it's hard to live without it.

Unfortunately, currying in Perl is a bit awkward, typically relying
on a helper function of sorts to make the currying happen:

In this meditation, we'll do away with helper functions and
reduce the cost of currying to almost zero. Together, we'll write
AutoCurry, the tiny module that makes it happen.

(Update: If you're wondering why I didn't
use some of the existing currying modules or why I don't use
prototypes or annotations to make my implementation more like "real"
currying, please read my comment on this subject, which
explains why I think the style of currying I present below makes
more sense for Perl (5) than does signature-based currying.)

Our goal is to make currying free, like it is in some other
programming languages. (In Haskell, for example, you don't need to say
that you want to curry a function; you just call it with fewer than
the expected number of arguments, and the currying happens
automatically.)

Why do this in Perl?

Before getting to AutoCurry, let's spend a few moments
justifying the exercise. Why should we try to reduce the cost of
currying in Perl? The answer is because currying reduces the cost of
reusing functions, making reuse practical in more situations, and that
in turn reduces the cost of programming in general. In short, with
currying we reinvent the wheel less. If we can reduce the cost of
currying further, we might be able to achieve further cost reductions.

As a motivating example, consider the case of logging. Let's
say that we have the following generalized logging function:

The application server expects $mylogger to be a logging
function that takes a single argument, the message to be logged.

It would be nice to be able to reuse our existing, 3-argument
logging function for this purpose. We can do this by adapting it to
the application server's expectations. Because the application
server expects a 1-argument function and we have a 3-argument
function, we must specialize away the extra arguments. We'll
do this by binding $fh to STDERR and
$heading to "app server".

In some programming languages, we would need to write a wrapper
function to specialize the function:

That's pretty good, but specialization in Perl is still more expensive
than in some other languages. It would be great to reduce the cost
to the bare minimum, where a regular function call is automatically
curried if it doesn't receive all of the arguments it wants:

The idea behind AutoCurry

AutoCurry gets us very close to the goal. We can't quite make it all
the way because functions in Perl can accept varying numbers of
arguments, and thus it's hard for us to determine reliably when
currying is implied by analyzing function calls. For this reason, we
take the practical road and rely upon a hint from the programmer to
tell us when currying is expected. (Seen from this light, calling the
curry helper function could be considered a rather expensive
hint. We want to make the hint less expensive.)

The hint that we will use is to append the suffix "_c" to
any function call that we want to have currying semantics. To show
how it works with our running example:

In essence, each _c function is a partially applied call to
curry that specializes the corresponding normal, non-curried
function by calling curry again.

Now, to make the approach cost effective, all we need to do
is automate it and bring it to a larger scale.

Mass production

For maximum convenience, we would like to curry-enable every function
in our namespace automatically. The first step, then, is to scan our
namespace for functions. We can do this by scanning its symbol table
and extracting the names associated with non-empty CODE
slots:

To wrap it up, we'll place everything in the AutoCurry package,
along with some documentation and a few extra helper functions. As a
further convenience, the module will accept instructions about what to
auto-curry via its import list:

Implementing the import function and robustifying the code
above is straightforward, and so I'll stop the meditation here. (If
you're curious, I have included the complete code for the module
below. It contains fewer than sixty lines of code.)

Thank you!

Thanks for taking the time to read this meditation.
If you have any criticisms or comments, please let me know.
Also, if you can help me improve my writing, I would greatly
appreciate your suggestions.

I assume you'll be uploading this to CPAN. Where's the test suite? Could you accomodate using some other namespace other than '_c'? I use that when referring to a column attribute when using Alzabo. I'd opt to be verbose and just use the '_curry' namespace instead.

# the first argument to import may be some configuration
use AutoCurry ( { namespace => '_curry' }, LIST );

Also note that your INIT block won't run when your module is loaded during runtime and from common mod_perl configurations. You'll need to expose that block in a named subroutine to give those other people a chance to run that code. You could also just run that from your import() function so your users won't need to care about that detail.

Thanks for taking the time to read the meditation and respond.
Your views are always welcomed.

Yes, I'll put this up on CPAN once I flesh it out. This meditation
is my first opportunity for feedback, and so I expect a round of revision
(including a test suite) before I upload.

Could you accomodate using some other namespace other
than '_c'?

Yes.

That said, I'm reluctant to increase the length of the currying
suffix because it increases the usage cost beyond the point where it
seems like a mere notational convention. Nevertheless, I can see the
opportunity for conflict with existing naming schemes, and tastes do
vary, and so I ought to make the suffix configurable.

Also note that your INIT block won't run when your module is loaded during runtime and from common mod_perl configurations. You'll need to expose that block in a named subroutine to give those other people a chance to run that code.

It is exposed already via curry_named_functions and
curry_package, although the latter isn't documented yet.

You could also just run that from your import() function so your users won't need to care about that detail.

The import function would be called before one and
two were even parsed, and so it couldn't possibly load them
from the symbol table. That's why the import function
must queue up operations to until INIT time.

You have still neglected to leave the user with the ability to use a different suffix. This suffix is already used by Alzabo::MethodMaker (for row columns) though it is configurable. If I intended to use both Alzabo and AutoCurry, I'd have to do some fancy footwork with the symbol table to rename all the curried functions before other _c functions were installed (or is it the other way, I forget).

Your accomodation may be as simple as providing an overridable package scalar.

Apart from that calling a function log_to_handle() is documenting how the function works, not what the function does; 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.

It is just so much easier and more efficient to allow me to configure the heading and destination filehandle as individual parameters at instantiation.

All your curry() is doing, is complicating a very simple piece of code, in order to justify the introduction of the need for autocurrying.

But there is another, more serious problem with the idea of autocurrying.

If AppServer is a class, as implied by the ->new(...) instantiation, then it would be normal practice for me to be able to instantiate two instances. If I pass in a coderef to each instance, then each instance can store those as instance data and will call the appropriate logger function automatically.

But if instantiating an instance of AppServer class is going to blythly export curried functions into the caller's namespace, then there is going to be a conflict between those exported for use with the first instance, and those for the second etc.

I also wonder how this is going to work with OO code where the first parameter is $self?

Namespace pollution will abound, to create lots of autocurrying functions that in all honesty, I cannot remember using a module that might lend itself to their use.

Your example aside, which seems somewhat contrived anyway, 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.

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

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:

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

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.

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!

I think you've got things reversed. log_to_handle() is not part of the framework, it's a function that Tom already has lying around. The framework does it's logging by running a coderef you provide and passing in the log message as the signle argument.

"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

I'd like to second the comment about allowing a user-defined suffix. But, I'd like to see the ability to use a prefix instead of/in addition to a suffix. For example, I work with some people whose Perl skills are ... well ... lacking. Instead of forcing them to look at the end, I may prefer to have them look at the beginning. So, instead of log_handle_c(), I may like to have CURRY_log_handle(), or somesuch.

So, I would say allow for both a suffix and a prefix, if desired. If nothing is specified, default to suffix=>'_c'. If a suffix is specified, use it instead. If a prefix is specified, but no suffix, just use the prefix. If both are specified, use both. Someone may want to see CURRIED_log_handle_CURRIED() as their name, for readability.

Remember - you're providing low cost as the default. But, maybe I want to pay a higher typing cost in order to achieve a lower overall maintenance cost. Your module should allow that, otherwise its adoption rate may not be as high as you would like.

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.

Nevertheless, in the docs I will try to discourage using anything but the default. While you are no doubt correct that using a more explicit prefix/suffix may reduce the cost of maintenance locally for some settings, not having a common usage across the community may increase cost globally.

For what it's worth, in programming languages with support for real currying, there is no notation whatsoever for currying – curried calls and regular calls are look the same (because underneath they are the same) – and it's not confusing once you get the hang of it. (In fact, it's liberating.)

Just out of curiousity, is it because standard Perl functions do not specify how many parameters they need at a minimum, so the compiler cannot tell if a function is satisfied? Because, if it is, couldn't we just use prototypes? For example:

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.

tmoertel,
Ok - I have to admit that I don't fully understand currying or a lot of other concepts from functional programming (FP). I have a few questions - some in general and some specific to your implementation.

The next question is with your statement:
We can't quite make it all the way because functions in Perl can accept varying numbers of arguments, and thus it's hard for us to determine reliably when currying is implied by analyzing function calls.
Prototypes, as evil as they are, do allow for optional arguments or you could always count @_. I don't see why this is a problem.

My final question for now is an apparent flaw in the design. Currying, as I understand it, only works if I don't have the last x arguments. What if I have the middle argument and the entire function requires 5? In Perl, that would be easy because I would use a hash ref and "name" my arguments. I don't see how currying helps in this situation (real currying, not Perl's substitute).

How does it know that I am finishing off one and not
starting another? Or if the 3rd time I called greeting() I did it with
two arguments - what then?

Actually, currying doesn't work that way. Each of the calls above
would result in a partial application of the greeting
function and result in a new function that, if given the final
argument, would emit the final result. Currying doesn't rely upon a
stateful function that accumulates arguments until it is satisfied.
Each call is independent. I explain more on this later.

Regarding how the language knows when the final argument is
supplied, "real" currying is typically paired with a type system that
can infer when all arguments have been satisfied. To use Haskell as
an example, the greeting function would be written like so:

It says, "greeting takes a string and returns a function that takes
another string and returns an IO action." (The notation
a->b means "function from type a to type
b" and is right-associative.) This is more obvious
from the fully parenthesized type:

So, to answer your first question, Haskell knows what to do
at each step because it keeps track of the types. If you
supply both arguments, the result is an IO action –
"Hello, World" is printed. If you supply only the first
argument, the result is a function that takes a string
and returns an IO action. And if you supply zero arguments,
the result is a function that takes a string and returns
a function than takes a string and returns an IO action.
(The reality is a bit more complex. The short of it
is that the intermediate functions are optimized away
when they're not needed.)

The next question is with your statement:

We can't quite make it all the way because
functions in Perl can accept varying numbers of arguments, and thus
it's hard for us to determine reliably when currying is implied by
analyzing function calls.

Prototypes, as evil as they are, do allow for optional arguments
or you could always count @_. I don't see why this is a
problem.

It's not a problem per se, but rather a design decision.
Perl lets us write functions with variable numbers of arguments, and
it offers wonderful argument-splicing call semantics. Why create a
Perl "currying" that doesn't let us take advantage of these strengths?
I want to be able to curry functions like the following, where there
is no ahead-of-time notion of how the arguments will be used:

What this means, however, is that we're not really currying.
What we're doing is a single-shot argument binding. But it's close
enough to true currying for most practical intents and purposes.

My final question for now is an apparent flaw in the
design. Currying, as I understand it, only works if I don't have the
last x arguments. What if I have the middle argument and the entire
function requires 5?

In most languages with native currying, higher-order functions are
also available. They let you manipulate other functions to reorder
arguments (among other things). Nevertheless, in a world with
pervasive currying, most people design their functions so that the
arguments most likely to be specialized come first. Typically, what
you want to specialize on will be one of the first two arguments,
and getting to them is idiomatic.

In Haskell, for example, the higher-order function flip
flips the order of first two arguments of its target function. This
lets you specialize the second argument and leave the first alone:

If I understand correctly, you can still curry with named parameters. You just have to add a little more intelligence. Basically, currying means that the function call was incomplete - we need more parameters before we are satisfied. It's easy to do that with positional - did I get enough stuff. But, using something like Params::Validate, you could build currying for named parameters.

Of course, the trick is making sure you have a good API for the developer to specify currying. I suspect the best way is to just define the API, then have the function automatically curry whenever a required argument is missing.

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.

Very nice meditation, Tom. Being a fan of functional programming myself, I really enjoy reading your meditations. However, being a user of OOP programming too, I despise namespace pollution. I like your idea, but I would like to see it be done without the need for creating new functions in the namespaces. This alone would make me not use this module desipte the fact I can see a number places something like this would be handy.

I suggested above (in response to dragonchild's thought on prototypes) the possibility of using attributes to defined the curry-ability of a function. I think this would be a nicer way to do things (assuming it is possible of course), since it would provide the transparent currying you are after (ala Haskell, Std ML, etc). For me, I would rather have the transparency, in fact I think I would even choose curry(\&func ...) over adding the '_c' to a function as well. Naming conventions are a very sensitive issue for many people and I would think even with having all the suffix and prefix options would still not be enough for some, me in particular ;-)

Obviously, improvements can be made, but I think this does what is desired. There is a slight performance penalty, but it's not bad at all.

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 don't like the syntax. When looking at the code I would definitely not expect foo_c(1,2) to be "equivalent" to sub {foo(1,2,@_}. I think the currying would have to have a very very nice syntax to be used in place of anonymous subs. A syntax that would look readable enough to me is

It only supports the simpler types of calls like foo(params, ...), &$foo(params, ...), $foo->(params, ...), $obj->Method(params, ...) and Class->Method(params, ...) and it uses just \w+ for variable/function/method/class names which definitely is not correct regexp for identifiers in Perl.

Jenda

We'd like to help you learn to help yourself
Look around you, all you see are sympathetic eyes
Stroll around the grounds until you feel at home
-- P. Simon in Mrs. Robinson

That's why I said it's AFAIK doable ONLY using source filters. It was a nice exercise writing the module, I do like the syntax that it allows, but I don't think I will ever use it in production code.

The code could be improved to match the Perl identifiers and variables better, but I'm not sure it'd be worth it. If anyone wants to extend the code, use it and even release it to CPAN it's fine with me. I doubt I ever will. Though ... you never know ;-)

Update: BTW, I searched all my Perl sources including the perl instalation and only found /,\s*\.\.\.\s*\)/ in PODs and comments and in one string printed by DBI.pm, one in Tk\X11Font.pm, one in Benchmark.pm and one in DB_File.pm.

Jenda

We'd like to help you learn to help yourself
Look around you, all you see are sympathetic eyes
Stroll around the grounds until you feel at home
-- P. Simon in Mrs. Robinson

Went to join the gridlock to see it
Held an eclipse party
Watched a live feed
I cn"t see tge kwubosd to amswr thus
I tried to see it, but 8000 miles of rock got in the way
What eclipse?
Wanted to see it, but they wouldn't reschedule it
Read the book instead