Overloading operators for currying, a PEP309 suggestion

Stephen Horne intentionally at blank.co.uk
Fri Mar 14 01:36:04 CET 2003


On Thu, 13 Mar 2003 05:11:46 GMT, "Lenard Lindstrom"
<PEP308reply at telus.net> wrote:

>Maybe my mistake shows that my
>operator choices are confusing.

Overloading operators with completely new meanings (rather than with
the same meanings for new types) always causes some confusion - it's
almost a basic fact of life.

> Actually, my biggest concern is with the
>precedence of the '<<' operator.

OK - I understand.

I have a very strong tendency to avoid depending on precedence except
in cases where the precedence is absolutely clear. Therefore, if the
value to curry in is derived from an expression then that expression
should be in parentheses.

Meaning I wouldn't write...

>   fn1 = fn << x < 10 << x    # Should this work?

I'd write...

    fn1 = fn << (x < 10) << x

or rather, I'd write...

    fn1 = fn [:] << ((x < 10), x)


To be honest, I'm not very keen on that syntax now either.

>I intended the syntax to resemble a call. The idea behind currying is to
>break down a function call into a series of single argument calls. I like
>the __getitem__ approach with __call__ because now the implied calls are
>obvious.

So this is a difference in mindset over what a call is. OK, I can see
that.

>However, you are right in that what I suggest is not currying in the purest
>sense.

Actually, I wasn't referring to that - I didn't even remember the
distinction until I read your explanation. Until you prodded my
memory, I'd forgotton that the result of currying all parameters
should be the fully evaluated result from the function. Its just that
to me, the closure-manipulation and final execution are different
things. Somehow, the idea that currying all parameters gives a
function requiring no parameters (but not the final result) seems more
natural. It's probably an artifact of my mostly imperative programming
experience.

The only time I used currying like that was in Miranda back at
college, about 10 years ago now. I used Haskell much more recently,
but didn't worry about currying because I was only getting the feel of
the language and didn't want to waste time learning things I *thought*
I already understood.

Now I think about that, I understand why you want a left-currying
syntax which fills the next available uncurried parameter - this was
what Miranda did most naturally because of its prefix-heavy syntax
with no parentheses for call parameters. IIRC a direct mult-parameter
function call such as '+ 1 1' could equally be seen as a sequence of
currying operations. So what I think as the general principle would,
to Miranda users at least, presumably be the fiddly exceptional case.

>Actually allowing for argument value retrieval may not be such a big
>problem. Keeping extra data around would only slow the currying operators.
>The resulting functions would be just as fast. Anyway, there could always be
>two curry classes, a bare-bones performance version as well as a full
>featured version.

Hmmm - if it came to that, I'd start thinking that people who need
access to the curried-in values should keep their own records.

If a function returns a curried function, and there are two
curried-function classes, it needs to anticipate how that result will
be used. Assume the performance case and people can't access the
curried data. Assume the full-featured case and there are overheads
that cannot be easily removed - a conversion to the performance case
(discarding the extra data) would be possible but even that in itself
would waste some time.

>For anyone interested, the three part online article "Charming Python:
>Functional programming in Python" by David Mertz discusses currying,

I think I'll be doing some revision shortly.





More information about the Python-list mailing list