[Python-ideas] Operator as first class citizens -- like in scala -- or yet another new operator?

Yanghao Hua yanghao.py at gmail.com
Wed May 29 10:15:50 EDT 2019


On Wed, May 29, 2019 at 3:34 PM Steven D'Aprano <steve at pearwood.info> wrote:
>
> On Tue, May 28, 2019 at 05:45:54PM -0400, Ricky Teachey wrote:
>
> > As things stand right now, it seems like you don't understand what we are
> > saying about using descriptors to accomplish this. However it is certainly
> > possible I simultaneously don't understand what you are really trying to do
> > in the code you wrote (I definitely don't claim to).
>
> Descriptors are, I think, a total red herring.
>
> Yanghao Hua wants to customise the behaviour of assignment. I believe
> that he wants to emulate the behaviour of some hardware description
> languages, where the equals sign = doesn't mean assignment (if I have
> understood correctly, which I may not have), but Something Else.
>
> Yanghao Hua can write a method to perform that Something Else, but he
> wants to use the standard variable assignment syntax:
>
>     x = expression
>
> but there is no hook to customise the behaviour, variable assignment is
> built-into the language. But *attribute assignment* is different:
>
>     obj.x = expression
>
> may call either the descriptor protocol, or simply call type(obj).__setattr__,
> which gives us the opportunity to hook into attribute assignment.
> Likewise for item assignment:
>
>     obj[x] = expression
>
> which calls type(obj).__setitem__.
>
> So Yanghao Hua has lots of options:
>
> 1. Choose a different operator. The obvious choice is << if his object
> is not already using it.
>
> 2. Use a method: x.set(expression)
>
> 3. Use a pre-processor, like Coconut or "Like, Python!". He may need to
> write his own pre-processor, but that may not be very difficult if all
> it does is convert "x = ..." into a method call.
>
> 4. Write an interpreter that does what he likes:
>
>     code = """
>         x = expression
>         """
>     result = interpret(code)
>
> 5. It may be possible to play games with the interpreter by using
> metaclasses, replacing modules with custom objects, etc. But I doubt
> that will change the behaviour of assignment inside the module itself.
>
> 6. Check out MacroPy and see whether its macros will help.
>
> 7. Use a custom interpreter. There is at least one superset of
> Python in common use: Cython.
>
> 8. The most obvious solution is to just use an instance and attribute:
>
>     obj.x = expression
>
> will work fine, but he just doesn't like the look of it.
>
> Aesthetics are an important part of language design, but it is only one
> factor out of many. All languages make compromises, and sometimes
> compromising on aesthetics is one of them.
>
> In Python, the compromise is that we can't hook into plain old
> assignment; but what we gain is certainty (we always know what x=...
> does) and performance. On the flip side, we *can* customise attribute
> assignment obj.x=... but what we lose is certainty and performance:
>
>     obj.x = ...
>
> is slower, because it has to look up the __setattr__ method, or call the
> descriptor protocol, and then call custom code; and we can't know what
> it will do.
>
> ``obj.x = 1`` can call arbitrary code, so it could do literally
> anything.
>
> Extending that ability to hook assignment to plain old variables is
> unlikely. It would need a PEP.
>
> Adding a new operator like <== is less unlikely, but it too would need a
> PEP, and the big question that everyone will ask is "why not just use <<
> instead?"
>
> The bottom line is, Python is not Lisp or Forth, where the very syntax
> itself can be customised. Regular assignment counts as syntax: it's
> unlikely to change, without a very good reason.

Thanks Steven, this is very well summarized. The only other thing is
when you pass signals around (e.g. by connecting different hardware
modules), it is very cumbersome with descriptor, see my reply in 2
minutes to Ricky. (again, I am not saying it is not possible,
everything is possible as long as you have enough disk space to write
more lines of code). This is something I am willing to start putting a
lot of effort in, even if this means I have to maintain my own
modified python. I understand python is not meant for everything, but
I hope one day I can prove this is really a big topic that python
community would love to address.

PS: I think Cython is not really for a customized python interpreter,
e.g. it cannot support you to change CPython behavior, it is more on
extending Python and writing python C modules easier. Or maybe Cython
is more powerful than I am aware of and can even change CPython
behavior like adding operators?


More information about the Python-ideas mailing list