[Python-ideas] (no subject)

Andrew Barnert abarnert at yahoo.com
Fri May 8 21:45:10 CEST 2015


On May 8, 2015, at 09:13, Chris Angelico <rosuav at gmail.com> wrote:
> 
>> On Sat, May 9, 2015 at 2:05 AM, Ron Adam <ron3200 at gmail.com> wrote:
>> I don't think special syntax has an advantage over a function for this.  It
>> may even be a disadvantage. The problem with special syntax is it can't be
>> represented as data easily.  That would be counter to a functional style of
>> programming, which seems at odds with the desired feature. (IMO)
>> 
>>     fns = (set, list, sorted)
>>     result = apply(data, *fns)
> 
> There's no problem with representing it as data; just like elsewhere
> in Python, you can break out a subexpression and give it a name.
> 
> (a @ b @ c)(x)
> # <=>
> f = (a @ b @ c)
> f(x)

Except that a@ and @b aren't subexpressions in Python. With a function, you can write them with partial; with an operator... Well, you can write the first with the bound dunder method and the second with partial and the unbound dunder method, but I don't think anyone finds type(b).__mmul__ as readable as @ (not to mention that the former is monomorphic, while the latter, like almost everything in Python, is duck typed, as it should be).

> It's no different from method calls:
> 
> sys.stdout.write("Hello, world!\n")
> # <=>
> write = sys.stdout.write
> write("Hello, world!\n")

There are other things that are a lot easier to do with a function than an operator, which aren't a problem for methods.

For example, you can unpack arguments. How would you write apply(value, *funcs) or compose(*funcs) with an operator without calling reduce on type(funcs[0]).__mmul__) or similar?

Of course you can always get around any of these problems by wrapping any operator expression up in a function with lambda--but if that really were good enough in practice, we wouldn't have comprehensions (after all, you can do the same thing with map just by wrapping up the expression with lambda--but nobody ever does that except people trying to use Python as Lisp, and nobody else wants to read their code).

This is (a part of) what I meant when I said that just posting Haskell's compose operator without all of the other language features and style idioms that make it so useful won't necessarily give us a useful Python feature. In Haskell, a@ and @b are subexpressions that can be given names and passed around, you can turn @ into a function just by wrapping it in parens rather than having to pull the dunder method off a type, etc. That solves most of these problems automatically, but we don't want to import all of those features into Python. (On the other hand, Haskell only "solves" the *args unpacking issue by just not allowing variable or even optional parameters--I'm not arguing that Haskell is "better" here, just that a compose operator fits into Haskell better than into Python.)


More information about the Python-ideas mailing list