Self-currying functions

Scott David Daniels scott.daniels at acm.org
Sun Jun 1 02:02:12 EDT 2003


Dave Benjamin wrote:

> In article <3ecff6e8$1 at nntp0.pdx.net>, Scott David Daniels wrote:
>>Dave Benjamin wrote:
>>>...
>>>The following is my response, adapted from your example to support Alex
>>>Martelli's curry function (and as a result, curried named parameters). I'm
>>>starting to find interesting uses I hadn't anticipated.
>>>...
>>
>>I am curious why you would want this ability (as opposed to curry..), 
 >> it seems there is a difference between a function with zero arguments
 >> and the result of that function....
>>     Shouldn't selfcurry(lambda:1) == 1?
> 
> I'm not sure that I understand your comments. The point of selfcurry is to
> modify the behavior of an existing function of two or more arguments so that
> they do not need to be supplied at once. A function of zero or one arguments
> does not need to be curried. Maybe selfcurry should just give you back your
> function, unmodified, in that case.

OK, I really am asking a question rahter than trying to score debate
points.  What I am curious about is why the selfcurry interface is
preferable to the curry interface.  As an invention, I can see either
one showing up first, but your response to Carl Baks' implementation
of selfcurry is not, "Oh, curry is what I probably want."

> I don't see what this specific construct has to do with side effects,
> besides the obvious connection with functional programming.

OK, my exposure to currying is from functional programming.  The only
way I can see making a zero-argument function equivalent to its result
is in an environment where you care about when a function is executed.
If functions are side-effect free, it doesn't matter when they are
executed, and it may well be reasonable to consider a function of zero
arguments as equivalent to its result.  In other environments, a
programmer generally cares precisely when the function is elaborated.
I hope this makes clear why I was talking about side-effect-free.

>>The keyword args seems to interfere with this flavor of currying,
>>perhaps you need to add in len(kwargs) to decide on provided arguments.
>> ... [after] f = selfcurry(lambda w, x, *y, **z: (w, x, y, z))
>> ... f(2, x=5)
> This is definitely a gray area that I had not thought of.... it seems
> keyword arguments behave like options....
But they do count as arguments (in terms of the number of arguments).

> What would be the point of explicitly naming positional parameters? 
 > ... why would you want to do this in the first place? Do you normally
 > name your positional arguments explicitly?

I think the deceptive part here was my example (which was too short
to be realistic).  I've worked on a number of systems (typically
simulations), where there are a reasonably large number of parameters
to be specified.  Often there is no reasonable default; the value must
be specified.  In such systems, giving parameters names (and forcing
the names to match actuals) makes for more reliable code.  It is too
easy to read past a mis-ordering of 12 parameters.


>>I am curious why you prefer the selfcurry interface (even assuming
>>keyword issues are dealt with).  It seems to to violate "explicit
>>is better than implicit."
> Can you elaborate on that? ...
This is the crux of my question, I suppose.  Forgive me for going
there again, but if there are no side-effects, then functions are
simply expression rewrites, and there is no meaningful difference
between a function with zero arguments and its result.  If there
are side-effects (such as I/O), when code is executed is crucially
important, and seldom would you write "r = f(a)" without knowing
whether a side-effect can be expected to happen.  I'd expect list
comprehensions and map to be seen as bad style (too cute a trick)
if side-effects are expected, for example.

The expicit/implicit thing I'm talking about is the moment the
function is elaborated (or called, or ...).  Selfcurry turns a
function of an arbitrary number of arguments into a function of
one argument returning a function of one argument returning ...
a result.  It is the "magic" result point that I don't get.
Curry of a function and some arguments returns a function of
fewer arguments (or, for keyword args, potentially different
defaults).  You still always know when the function is invoked
to return a result, and your call will always expect either a
further function or a result.

> I am not advocating that everybody write functions that curry their own
> arguments, or that we throw away the ability to name positional parameters
> when calling functions. I'd just like the ability to write functions that
> have this behavior, and now I have it, and I'm pretty happy about it. =)

And I am not saying you shouldn't have the use of whatever floats your
boat. I am truly eager to hear a use case for selfcurry over curry.  Is
it simply brevity in intermediate expressions, or is there something I
am missing.  Do you feel, "yes, of course, you know when a value is 
produced and a final 'bowlegs' would be no big deal," or "the whole
point is to be able to deal with this ambiguously?"

For those listening in, the parens at the end of "fun()" are what I
mean by bowlegs.  I presume Dave knows the term.

> Thanks, Dave

Thanks for taking the time to respond.

-Scott David Daniels
Scott.Daniels at Acm.Org





More information about the Python-list mailing list