Overloading operators for currying, a PEP309 suggestion
Stephen Horne
intentionally at blank.co.uk
Wed Mar 12 05:45:04 EST 2003
On Wed, 12 Mar 2003 07:08:01 GMT, "Lenard Lindstrom"
<PEP308reply at telus.net> wrote:
>
>"Stephen Horne" <intentionally at blank.co.uk> wrote in message
>news:bmjr6vgc7efto3qqqfbmkri9u68l54k78c at 4ax.com...
>>
>> You may be onto something, but I'm not keen on your '|' version in
>> particular.
>>
>I chose the '|' bitwise or and '<<' left shift operators because of a
>superficial simularity between currying a parameter list and manipulating a
>string of bits. Doing an 'or' allows you to selectively set arguments; doing
>a 'shift' allows you to remove arguments sequencially. However, there are
>many operators to choose from.
I see what you are saying, but to me the only one of your original
examples that seemed completely intuitive was '<<' - and that mainly
because I see it in the same sense as C++ stream insertion.
The '>>' looks like it should be removing something from the closure
(analogous with stream extraction).
The '|' version looks - well - I'm not sure, just not right.
Much of this is probably just the fact that you're re-using existing
operators, of course. My initial reaction to C++ stream insertion and
extraction operators was basically 'what - yuck!', but now I quite
like them.
>> I would prefer defining the __len__, __getitem__, __setitem__ and
>> __delitem__ methods to allow direct manipulation (and creation and
>> deletion) of the closure. Though probably the function object should
>> be immutable.
>>
>Yes, I think the curried function object should be immutable. This leaves
>out __setitem__. But is it needed?
The thought was...
<function-name> [<param-selection>] = <value>
...for currying, without needing to save a result or use alternative
operators.
>> How about...
>>
>> <function-obj> [ <int> | <slice> ] -> <closure-item-ref>
>> <function-obj> . <keyword> -> <closure-item-ref>
>>...
>or <function-obj> [ <int> | <slice> | <keyword> ]
OK - I was a bit confused there.
>Using my '<<' grammer, positional assignment might be done like this:
>
>fn << {<posn>:<value>, ...}
>
>eg:
> fn1 = fn << {1:'a'} # the key is an integer posn rather than an arg.
>name.
I think this creates a problem.
fn << 1 # Curries left parameter with rvalue
fn << { 2 : "x" } # Does not curry left parameter with rvalue -
# treats rvalues type as special case.
In short, I think this is a potentially confusing inconsistency.
>> <closure-item-ref> << <value>
>> Return a new function/closure with the selected fields from the
>> old one added or modified.
>>
>Maybe this is where __call__ comes in.
> <closure-item-ref>(<value>, ...)
Not sure - call syntax suggests calling to strongly, which we are not
doing. I though it would be better to choose a syntax which emphasizes
that no call is done - only manipulation of closure contents and
selection flags.
>In addition to the currying operators one can add a 'curry' method that
>behaves like the curry function proposed for the functional module.
True
>> fn2.a.value () # Get value currently assigned to a
>>
> fn2["a"].value ()
> fn2["a"] # Hmmm.
> fn2.getargval("a") # ?
>
>Having to use some method or property like 'value' is awkward.
True, but not IMO important.
> Anyways, implementing value
>retrieval would require additional data be kept around if Python closures
>are used to save the argument values.
I didn't know that - I don't know how Python closures work, only what
the general principle behind closures is.
> How important is it?
Not important - which is why an awkward syntax didn't seem to be a
problem.
BTW - 'fn2["a"]' without a method for getting the value was rejected
because it already has the closure-manipulating meaning. It's a shame,
but - as already noted - I didn't think it was that important.
>> One advantage - it should be possible to write this as a library
>> without any language changes. I think.
>>
>from functional import curryfunction
>
>def fn(<args>):
> <body>
>fn = curryfunction(fn)
Yes, but - erm - well - I don't like it!
I don't think you should need to convert a normal function into a
curryable function - functions should be functions, whether they
support currying or not.
More information about the Python-list
mailing list