[Python-ideas] New __reference__ hook

Bruce Leban bruce at leapyear.org
Wed Dec 5 19:54:22 CET 2012


On Wed, Dec 5, 2012 at 10:09 AM, Sturla Molden <sturla at molden.no> wrote:

>
> But apart from that, I think allowing overloading of the binding operator
> "=" might be a good idea. A special method __bind__ could return the object
> to be bound:
>
>    a = b
>
> should then bind the name "a" to the return value of
>
>    b.__bind__()
>
> if b implements __bind__.
>

It' seems a bit more complicated than that. Take the example below. When is
__bind__ going to be called? After a is multiplied by x, b is multipled by
y, etc. or before? If after, that doesn't accomplish lazy evaluation as
below. If before, then somehow this has to convert to a form that calls
z.__bind__(something) and what is that something?

>
> Sure, it could be used to implement copy on assignment. But it would also
> do other things like allowing lazy evaluation of an expression.
>
> NumPy code like
>
>    z = a*x + b*y + c
>
> could avoid creating three temporary arrays if there was a __bind__
> function called on "=". This is a big thing, cf. the difference between
> NumPy and numexpr:
>
>    z = numexpr.evaluate("""a*x + b*y + c""")
>
> The reason numerical expressions must be written as strings to be
> efficient in Python is because there is no __bind__ function.
>

There is another way to write expressions that don't get evaluated:

lambda: a*x + b*y + c


So you could write this as z.bind(lambda: rhs) or if this is important
enough there could be a new bind operator:

lhs @= rhs


which is equivalent to

lhs.__bind__(lambda: rhs)


I think overriding = so sometimes it does regular binding and sometimes
this magic binding would be confusing and dangerous. It means that every
assignment operates differently if the lhs is already bound. Consider the
difference between

t = a + b
typo = a+b

t @= a+b
typo @= a+b


where typo was supposed to be t but was mistyped. In the first set, line 1
does __bind__ to a+b while line just adds a and b and does a normal
binding. In the second set, the first does __bind__ while the second raises
an exception that typo is not bound.

It's even worse in the context of something like this:

d = {}
for i in range(2):
    d['x'] = a + i


in the first pass through the loop this is a regular assignment. In the
second pass it may call __bind__ depending on what the value of a + 0 is.
Ick.

--- Bruce
Follow me: http://www.twitter.com/Vroo http://www.vroospeak.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20121205/a3de59b8/attachment.html>


More information about the Python-ideas mailing list